LCOV - code coverage report
Current view: top level - gcc/c - c-parser.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.4 % 15848 14162
Test Date: 2026-02-28 14:20:25 Functions: 92.6 % 350 324
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Parser for C and Objective-C.
       2              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       3              : 
       4              :    Parser actions based on the old Bison parser; structure somewhat
       5              :    influenced by and fragments based on the C++ parser.
       6              : 
       7              : This file is part of GCC.
       8              : 
       9              : GCC is free software; you can redistribute it and/or modify it under
      10              : the terms of the GNU General Public License as published by the Free
      11              : Software Foundation; either version 3, or (at your option) any later
      12              : version.
      13              : 
      14              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      15              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      16              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      17              : for more details.
      18              : 
      19              : You should have received a copy of the GNU General Public License
      20              : along with GCC; see the file COPYING3.  If not see
      21              : <http://www.gnu.org/licenses/>.  */
      22              : 
      23              : /* TODO:
      24              : 
      25              :    Make sure all relevant comments, and all relevant code from all
      26              :    actions, brought over from old parser.  Verify exact correspondence
      27              :    of syntax accepted.
      28              : 
      29              :    Add testcases covering every input symbol in every state in old and
      30              :    new parsers.
      31              : 
      32              :    Include full syntax for GNU C, including erroneous cases accepted
      33              :    with error messages, in syntax productions in comments.
      34              : 
      35              :    Make more diagnostics in the front end generally take an explicit
      36              :    location rather than implicitly using input_location.  */
      37              : 
      38              : #include "config.h"
      39              : #define INCLUDE_STRING
      40              : #include "system.h"
      41              : #include "coretypes.h"
      42              : #include "target.h"
      43              : #include "function.h"
      44              : #include "c-tree.h"
      45              : #include "timevar.h"
      46              : #include "stringpool.h"
      47              : #include "cgraph.h"
      48              : #include "attribs.h"
      49              : #include "stor-layout.h"
      50              : #include "varasm.h"
      51              : #include "trans-mem.h"
      52              : #include "c-family/c-pragma.h"
      53              : #include "c-lang.h"
      54              : #include "c-family/c-objc.h"
      55              : #include "plugin.h"
      56              : #include "omp-general.h"
      57              : #include "omp-offload.h"
      58              : #include "builtins.h"
      59              : #include "gomp-constants.h"
      60              : #include "c-family/c-indentation.h"
      61              : #include "gimple-expr.h"
      62              : #include "context.h"
      63              : #include "gcc-rich-location.h"
      64              : #include "c-parser.h"
      65              : #include "gimple-parser.h"
      66              : #include "read-rtl-function.h"
      67              : #include "run-rtl-passes.h"
      68              : #include "intl.h"
      69              : #include "c-family/name-hint.h"
      70              : #include "tree-iterator.h"
      71              : #include "tree-pretty-print.h"
      72              : #include "memmodel.h"
      73              : #include "c-family/known-headers.h"
      74              : #include "bitmap.h"
      75              : #include "analyzer/analyzer-language.h"
      76              : #include "toplev.h"
      77              : #include "asan.h"
      78              : #include "c-family/c-ubsan.h"
      79              : #include "gcc-urlifier.h"
      80              : 
      81              : /* We need to walk over decls with incomplete struct/union/enum types
      82              :    after parsing the whole translation unit.
      83              :    In finish_decl(), if the decl is static, has incomplete
      84              :    struct/union/enum type, it is appended to incomplete_record_decls.
      85              :    In c_parser_translation_unit(), we iterate over incomplete_record_decls
      86              :    and report error if any of the decls are still incomplete.  */
      87              : 
      88              : vec<tree> incomplete_record_decls;
      89              : 
      90              : void
      91    208089950 : set_c_expr_source_range (c_expr *expr,
      92              :                          location_t start, location_t finish)
      93              : {
      94    208089950 :   expr->src_range.m_start = start;
      95    208089950 :   expr->src_range.m_finish = finish;
      96    208089950 :   if (expr->value)
      97    208089824 :     set_source_range (expr->value, start, finish);
      98    208089950 : }
      99              : 
     100              : void
     101    230806666 : set_c_expr_source_range (c_expr *expr,
     102              :                          source_range src_range)
     103              : {
     104    230806666 :   expr->src_range = src_range;
     105    230806666 :   if (expr->value)
     106    230806661 :     set_source_range (expr->value, src_range);
     107    230806666 : }
     108              : 
     109              : 
     110              : /* Initialization routine for this file.  */
     111              : 
     112              : void
     113       110763 : c_parse_init (void)
     114              : {
     115              :   /* The only initialization required is of the reserved word
     116              :      identifiers.  */
     117       110763 :   unsigned int i;
     118       110763 :   tree id;
     119       110763 :   int mask = 0;
     120              : 
     121              :   /* Make sure RID_MAX hasn't grown past the 8 bits used to hold the keyword in
     122              :      the c_token structure.  */
     123       110763 :   gcc_assert (RID_MAX <= 255);
     124              : 
     125       110763 :   mask |= D_CXXONLY;
     126       110763 :   if (!flag_isoc99)
     127         6945 :     mask |= D_C99;
     128       110763 :   if (!flag_isoc23)
     129        13185 :     mask |= D_C23;
     130       110763 :   if (flag_no_asm)
     131              :     {
     132         6171 :       mask |= D_ASM | D_EXT;
     133         6171 :       if (!flag_isoc99)
     134         3994 :         mask |= D_EXT89;
     135         6171 :       if (!flag_isoc23)
     136         5126 :         mask |= D_EXT11;
     137              :     }
     138       110763 :   if (!c_dialect_objc ())
     139       110763 :     mask |= D_OBJC | D_CXX_OBJC;
     140              : 
     141       110763 :   ridpointers = ggc_cleared_vec_alloc<tree> ((int) RID_MAX);
     142     25807779 :   for (i = 0; i < num_c_common_reswords; i++)
     143              :     {
     144              :       /* If a keyword is disabled, do not enter it into the table
     145              :          and so create a canonical spelling that isn't a keyword.  */
     146     25697016 :       if (c_common_reswords[i].disable & mask)
     147              :         {
     148      9932928 :           if (warn_cxx_compat
     149       113021 :               && (c_common_reswords[i].disable & D_CXXWARN))
     150              :             {
     151        54177 :               id = get_identifier (c_common_reswords[i].word);
     152        54177 :               C_SET_RID_CODE (id, RID_CXX_COMPAT_WARN);
     153        54177 :               C_IS_RESERVED_WORD (id) = 1;
     154              :             }
     155      9932928 :           continue;
     156              :         }
     157              : 
     158     15764088 :       id = get_identifier (c_common_reswords[i].word);
     159     15764088 :       C_SET_RID_CODE (id, c_common_reswords[i].rid);
     160     15764088 :       C_IS_RESERVED_WORD (id) = 1;
     161     15764088 :       ridpointers [(int) c_common_reswords[i].rid] = id;
     162              :     }
     163              : 
     164       221526 :   for (i = 0; i < NUM_INT_N_ENTS; i++)
     165              :     {
     166              :       /* We always create the symbols but they aren't always supported.  */
     167       110763 :       char name[50];
     168       110763 :       sprintf (name, "__int%d", int_n_data[i].bitsize);
     169       110763 :       id = get_identifier (name);
     170       110763 :       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
     171       110763 :       C_IS_RESERVED_WORD (id) = 1;
     172              : 
     173       110763 :       sprintf (name, "__int%d__", int_n_data[i].bitsize);
     174       110763 :       id = get_identifier (name);
     175       110763 :       C_SET_RID_CODE (id, RID_FIRST_INT_N + i);
     176       110763 :       C_IS_RESERVED_WORD (id) = 1;
     177              :     }
     178              : 
     179       110763 :   if (flag_openmp)
     180              :     {
     181         2289 :       id = get_identifier ("omp_all_memory");
     182         2289 :       C_SET_RID_CODE (id, RID_OMP_ALL_MEMORY);
     183         2289 :       C_IS_RESERVED_WORD (id) = 1;
     184         2289 :       ridpointers [RID_OMP_ALL_MEMORY] = id;
     185              :     }
     186       110763 : }
     187              : 
     188              : /* A parser structure recording information about the state and
     189              :    context of parsing.  Includes lexer information with up to two
     190              :    tokens of look-ahead; more are not needed for C.  */
     191              : struct GTY(()) c_parser {
     192              :   /* The look-ahead tokens.  */
     193              :   c_token * GTY((skip)) tokens;
     194              :   /* Buffer for look-ahead tokens.  */
     195              :   c_token tokens_buf[4];
     196              :   /* How many look-ahead tokens are available (0 - 4, or
     197              :      more if parsing from pre-lexed tokens).  */
     198              :   unsigned int tokens_avail;
     199              :   /* Raw look-ahead tokens, used only for checking in Objective-C
     200              :      whether '[[' starts attributes.  */
     201              :   vec<c_token, va_gc> *raw_tokens;
     202              :   /* The number of raw look-ahead tokens that have since been fully
     203              :      lexed.  */
     204              :   unsigned int raw_tokens_used;
     205              :   /* True if a syntax error is being recovered from; false otherwise.
     206              :      c_parser_error sets this flag.  It should clear this flag when
     207              :      enough tokens have been consumed to recover from the error.  */
     208              :   BOOL_BITFIELD error : 1;
     209              :   /* True if we're processing a pragma, and shouldn't automatically
     210              :      consume CPP_PRAGMA_EOL.  */
     211              :   BOOL_BITFIELD in_pragma : 1;
     212              :   /* True if we're parsing the outermost block of an if statement.  */
     213              :   BOOL_BITFIELD in_if_block : 1;
     214              :   /* True if we want to lex a translated, joined string (for an
     215              :      initial #pragma pch_preprocess).  Otherwise the parser is
     216              :      responsible for concatenating strings and translating to the
     217              :      execution character set as needed.  */
     218              :   BOOL_BITFIELD lex_joined_string : 1;
     219              :   /* True if, when the parser is concatenating string literals, it
     220              :      should translate them to the execution character set (false
     221              :      inside attributes).  */
     222              :   BOOL_BITFIELD translate_strings_p : 1;
     223              : 
     224              :   /* Objective-C specific parser/lexer information.  */
     225              : 
     226              :   /* True if we are in a context where the Objective-C "PQ" keywords
     227              :      are considered keywords.  */
     228              :   BOOL_BITFIELD objc_pq_context : 1;
     229              :   /* True if we are parsing a (potential) Objective-C foreach
     230              :      statement.  This is set to true after we parsed 'for (' and while
     231              :      we wait for 'in' or ';' to decide if it's a standard C for loop or an
     232              :      Objective-C foreach loop.  */
     233              :   BOOL_BITFIELD objc_could_be_foreach_context : 1;
     234              :   /* The following flag is needed to contextualize Objective-C lexical
     235              :      analysis.  In some cases (e.g., 'int NSObject;'), it is
     236              :      undesirable to bind an identifier to an Objective-C class, even
     237              :      if a class with that name exists.  */
     238              :   BOOL_BITFIELD objc_need_raw_identifier : 1;
     239              :   /* Nonzero if we're processing a __transaction statement.  The value
     240              :      is 1 | TM_STMT_ATTR_*.  */
     241              :   unsigned int in_transaction : 4;
     242              :   /* True if we are in a context where the Objective-C "Property attribute"
     243              :      keywords are valid.  */
     244              :   BOOL_BITFIELD objc_property_attr_context : 1;
     245              : 
     246              :   /* Whether we have just seen/constructed a string-literal.  Set when
     247              :      returning a string-literal from c_parser_string_literal.  Reset
     248              :      in consume_token.  Useful when we get a parse error and see an
     249              :      unknown token, which could have been a string-literal constant
     250              :      macro.  */
     251              :   BOOL_BITFIELD seen_string_literal : 1;
     252              : 
     253              :   /* TRUE if omp::directive, omp::decl or omp::sequence attributes may not
     254              :      appear.  */
     255              :   BOOL_BITFIELD omp_attrs_forbidden_p : 1;
     256              : 
     257              :   /* Location of the last consumed token.  */
     258              :   location_t last_token_location;
     259              : 
     260              :   /* Holds state for parsing collapsed OMP_FOR loops.  Managed by
     261              :      c_parser_omp_for_loop.  */
     262              :   struct omp_for_parse_data * GTY((skip)) omp_for_parse_state;
     263              : 
     264              :   /* If we're in the context of OpenMP directives written as C23
     265              :      attributes turned into pragma, the tokens field is temporarily
     266              :      redirected.  This holds data needed to restore state afterwards.
     267              :      It's NULL otherwise.  */
     268              :   struct omp_attribute_pragma_state *in_omp_attribute_pragma;
     269              : 
     270              :   /* Set for omp::decl attribute parsing to the decl to which it
     271              :      appertains.  */
     272              :   tree in_omp_decl_attribute;
     273              : 
     274              :   /* Non-null only when parsing the body of an OpenMP metadirective.
     275              :      Managed by c_parser_omp_metadirective.  */
     276              :   struct omp_metadirective_parse_data * GTY((skip))
     277              :     omp_metadirective_state;
     278              : };
     279              : 
     280              : /* Holds data needed to restore the token stream to its previous state
     281              :    after parsing an OpenMP attribute-syntax pragma.  */
     282              : struct GTY(()) omp_attribute_pragma_state
     283              : {
     284              :   vec<c_token, va_gc> *token_vec;
     285              :   c_token * GTY((skip)) save_tokens;
     286              :   unsigned int save_tokens_avail;
     287              : };
     288              : 
     289              : /* Holds data for deferred lookup of base functions for OpenMP
     290              :    "begin declare variant", which are permitted to be declared after
     291              :    the variant.  */
     292              : struct GTY(()) omp_begin_declare_variant_map_entry {
     293              :   tree variant;         /* The variant decl.  */
     294              :   tree id;              /* Name of base function.  */
     295              :   tree ctx;             /* The context selector associated with the variant.  */
     296              : };
     297              : vec<omp_begin_declare_variant_map_entry, va_gc> *omp_begin_declare_variant_map;
     298              : 
     299              : static tree omp_start_variant_function (c_declarator *, tree);
     300              : static void omp_finish_variant_function (tree, tree, tree);
     301              : 
     302              : /* Return a pointer to the Nth token in PARSERs tokens_buf.  */
     303              : 
     304              : c_token *
     305          234 : c_parser_tokens_buf (c_parser *parser, unsigned n)
     306              : {
     307          234 :   return &parser->tokens_buf[n];
     308              : }
     309              : 
     310              : /* Return the error state of PARSER.  */
     311              : 
     312              : bool
     313         8095 : c_parser_error (c_parser *parser)
     314              : {
     315         8095 :   return parser->error;
     316              : }
     317              : 
     318              : /* Set the error state of PARSER to ERR.  */
     319              : 
     320              : void
     321            0 : c_parser_set_error (c_parser *parser, bool err)
     322              : {
     323            0 :   parser->error = err;
     324            0 : }
     325              : 
     326              : 
     327              : /* The actual parser and external interface.  ??? Does this need to be
     328              :    garbage-collected?  */
     329              : 
     330              : static GTY (()) c_parser *the_parser;
     331              : 
     332              : /* Read in and lex a single token, storing it in *TOKEN.  If RAW,
     333              :    context-sensitive postprocessing of the token is not done.  */
     334              : 
     335              : static void
     336   2314592814 : c_lex_one_token (c_parser *parser, c_token *token, bool raw = false)
     337              : {
     338   2314592814 :   timevar_push (TV_LEX);
     339              : 
     340   2314592814 :   if (raw || vec_safe_length (parser->raw_tokens) == 0)
     341              :     {
     342   2314492659 :       token->type = c_lex_with_flags (&token->value, &token->location,
     343              :                                       &token->flags,
     344   2314492659 :                                       (parser->lex_joined_string
     345              :                                        ? 0 : C_LEX_STRING_NO_JOIN));
     346   2314492502 :       token->id_kind = C_ID_NONE;
     347   2314492502 :       token->keyword = RID_MAX;
     348   2314492502 :       token->pragma_kind = PRAGMA_NONE;
     349              :     }
     350              :   else
     351              :     {
     352              :       /* Use a token previously lexed as a raw look-ahead token, and
     353              :          complete the processing on it.  */
     354       100155 :       *token = (*parser->raw_tokens)[parser->raw_tokens_used];
     355       100155 :       ++parser->raw_tokens_used;
     356       100155 :       if (parser->raw_tokens_used == vec_safe_length (parser->raw_tokens))
     357              :         {
     358        15477 :           vec_free (parser->raw_tokens);
     359        15477 :           parser->raw_tokens_used = 0;
     360              :         }
     361              :     }
     362              : 
     363   2314592657 :   if (raw)
     364       100155 :     goto out;
     365              : 
     366   2314492502 :   switch (token->type)
     367              :     {
     368   1041989265 :     case CPP_NAME:
     369   1041989265 :       {
     370   1041989265 :         tree decl;
     371              : 
     372   1041989265 :         bool objc_force_identifier = parser->objc_need_raw_identifier;
     373   1041989265 :         if (c_dialect_objc ())
     374            0 :           parser->objc_need_raw_identifier = false;
     375              : 
     376   1041989265 :         if (C_IS_RESERVED_WORD (token->value))
     377              :           {
     378    289088776 :             enum rid rid_code = C_RID_CODE (token->value);
     379              : 
     380    289088776 :             if (rid_code == RID_CXX_COMPAT_WARN)
     381              :               {
     382           35 :                 warning_at (token->location,
     383           35 :                             OPT_Wc___compat,
     384              :                             "identifier %qE conflicts with C++ keyword",
     385              :                             token->value);
     386              :               }
     387    289088741 :             else if (rid_code >= RID_FIRST_ADDR_SPACE
     388    289088741 :                      && rid_code <= RID_LAST_ADDR_SPACE)
     389              :               {
     390          177 :                 addr_space_t as;
     391          177 :                 as = (addr_space_t) (rid_code - RID_FIRST_ADDR_SPACE);
     392          177 :                 targetm.addr_space.diagnose_usage (as, token->location);
     393          177 :                 token->id_kind = C_ID_ADDRSPACE;
     394          177 :                 token->keyword = rid_code;
     395          177 :                 break;
     396              :               }
     397    289088564 :             else if (c_dialect_objc () && OBJC_IS_PQ_KEYWORD (rid_code))
     398              :               {
     399              :                 /* We found an Objective-C "pq" keyword (in, out,
     400              :                    inout, bycopy, byref, oneway).  They need special
     401              :                    care because the interpretation depends on the
     402              :                    context.  */
     403            0 :                 if (parser->objc_pq_context)
     404              :                   {
     405            0 :                     token->type = CPP_KEYWORD;
     406            0 :                     token->keyword = rid_code;
     407            0 :                     break;
     408              :                   }
     409            0 :                 else if (parser->objc_could_be_foreach_context
     410            0 :                          && rid_code == RID_IN)
     411              :                   {
     412              :                     /* We are in Objective-C, inside a (potential)
     413              :                        foreach context (which means after having
     414              :                        parsed 'for (', but before having parsed ';'),
     415              :                        and we found 'in'.  We consider it the keyword
     416              :                        which terminates the declaration at the
     417              :                        beginning of a foreach-statement.  Note that
     418              :                        this means you can't use 'in' for anything else
     419              :                        in that context; in particular, in Objective-C
     420              :                        you can't use 'in' as the name of the running
     421              :                        variable in a C for loop.  We could potentially
     422              :                        try to add code here to disambiguate, but it
     423              :                        seems a reasonable limitation.  */
     424            0 :                     token->type = CPP_KEYWORD;
     425            0 :                     token->keyword = rid_code;
     426            0 :                     break;
     427              :                   }
     428              :                 /* Else, "pq" keywords outside of the "pq" context are
     429              :                    not keywords, and we fall through to the code for
     430              :                    normal tokens.  */
     431              :               }
     432    289088564 :             else if (c_dialect_objc () && OBJC_IS_PATTR_KEYWORD (rid_code))
     433              :               {
     434              :                 /* We found an Objective-C "property attribute"
     435              :                    keyword (getter, setter, readonly, etc). These are
     436              :                    only valid in the property context.  */
     437            0 :                 if (parser->objc_property_attr_context)
     438              :                   {
     439            0 :                     token->type = CPP_KEYWORD;
     440            0 :                     token->keyword = rid_code;
     441            0 :                     break;
     442              :                   }
     443              :                 /* Else they are not special keywords.
     444              :                 */
     445              :               }
     446    289088564 :             else if (c_dialect_objc ()
     447            0 :                      && (OBJC_IS_AT_KEYWORD (rid_code)
     448              :                          || OBJC_IS_CXX_KEYWORD (rid_code)))
     449              :               {
     450              :                 /* We found one of the Objective-C "@" keywords (defs,
     451              :                    selector, synchronized, etc) or one of the
     452              :                    Objective-C "cxx" keywords (class, private,
     453              :                    protected, public, try, catch, throw) without a
     454              :                    preceding '@' sign.  Do nothing and fall through to
     455              :                    the code for normal tokens (in C++ we would still
     456              :                    consider the CXX ones keywords, but not in C).  */
     457              :                 ;
     458              :               }
     459              :             else
     460              :               {
     461    289088564 :                 token->type = CPP_KEYWORD;
     462    289088564 :                 token->keyword = rid_code;
     463    289088564 :                 break;
     464              :               }
     465              :           }
     466              : 
     467    752900524 :         decl = lookup_name (token->value);
     468    752900524 :         if (decl)
     469              :           {
     470    421719928 :             if (TREE_CODE (decl) == TYPE_DECL)
     471              :               {
     472    245575573 :                 token->id_kind = C_ID_TYPENAME;
     473    245575573 :                 break;
     474              :               }
     475              :           }
     476    331180596 :         else if (c_dialect_objc ())
     477              :           {
     478            0 :             tree objc_interface_decl = objc_is_class_name (token->value);
     479              :             /* Objective-C class names are in the same namespace as
     480              :                variables and typedefs, and hence are shadowed by local
     481              :                declarations.  */
     482            0 :             if (objc_interface_decl
     483            0 :                 && (!objc_force_identifier || global_bindings_p ()))
     484              :               {
     485            0 :                 token->value = objc_interface_decl;
     486            0 :                 token->id_kind = C_ID_CLASSNAME;
     487            0 :                 break;
     488              :               }
     489              :           }
     490    507324951 :         token->id_kind = C_ID_ID;
     491              :       }
     492    507324951 :       break;
     493            0 :     case CPP_AT_NAME:
     494              :       /* This only happens in Objective-C; it must be a keyword.  */
     495            0 :       token->type = CPP_KEYWORD;
     496            0 :       switch (C_RID_CODE (token->value))
     497              :         {
     498              :           /* Replace 'class' with '@class', 'private' with '@private',
     499              :              etc.  This prevents confusion with the C++ keyword
     500              :              'class', and makes the tokens consistent with other
     501              :              Objective-C 'AT' keywords.  For example '@class' is
     502              :              reported as RID_AT_CLASS which is consistent with
     503              :              '@synchronized', which is reported as
     504              :              RID_AT_SYNCHRONIZED.
     505              :           */
     506            0 :         case RID_CLASS:     token->keyword = RID_AT_CLASS; break;
     507            0 :         case RID_PRIVATE:   token->keyword = RID_AT_PRIVATE; break;
     508            0 :         case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
     509            0 :         case RID_PUBLIC:    token->keyword = RID_AT_PUBLIC; break;
     510            0 :         case RID_THROW:     token->keyword = RID_AT_THROW; break;
     511            0 :         case RID_TRY:       token->keyword = RID_AT_TRY; break;
     512            0 :         case RID_CATCH:     token->keyword = RID_AT_CATCH; break;
     513            0 :         case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
     514            0 :         default:            token->keyword = C_RID_CODE (token->value);
     515              :         }
     516              :       break;
     517    698010723 :     case CPP_COLON:
     518    698010723 :     case CPP_COMMA:
     519    698010723 :     case CPP_CLOSE_PAREN:
     520    698010723 :     case CPP_SEMICOLON:
     521              :       /* These tokens may affect the interpretation of any identifiers
     522              :          following, if doing Objective-C.  */
     523    698010723 :       if (c_dialect_objc ())
     524            0 :         parser->objc_need_raw_identifier = false;
     525              :       break;
     526      1927758 :     case CPP_PRAGMA:
     527              :       /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
     528      1927758 :       token->pragma_kind = (enum pragma_kind) TREE_INT_CST_LOW (token->value);
     529      1927758 :       token->value = NULL;
     530      1927758 :       break;
     531              :     default:
     532              :       break;
     533              :     }
     534   2314592657 :  out:
     535   2314592657 :   timevar_pop (TV_LEX);
     536   2314592657 : }
     537              : 
     538              : /* Return a pointer to the next token from PARSER, reading it in if
     539              :    necessary.  */
     540              : 
     541              : c_token *
     542  17268880705 : c_parser_peek_token (c_parser *parser)
     543              : {
     544  17268880705 :   if (parser->tokens_avail == 0)
     545              :     {
     546   1896416203 :       c_lex_one_token (parser, &parser->tokens[0]);
     547   1896416046 :       parser->tokens_avail = 1;
     548              :     }
     549  17268880548 :   return &parser->tokens[0];
     550              : }
     551              : 
     552              : /* Return a pointer to the next-but-one token from PARSER, reading it
     553              :    in if necessary.  The next token is already read in.  */
     554              : 
     555              : c_token *
     556    157654941 : c_parser_peek_2nd_token (c_parser *parser)
     557              : {
     558    157654941 :   if (parser->tokens_avail >= 2)
     559      8507429 :     return &parser->tokens[1];
     560    149147512 :   gcc_assert (parser->tokens_avail == 1);
     561    149147512 :   gcc_assert (parser->tokens[0].type != CPP_EOF);
     562    149147512 :   gcc_assert (parser->tokens[0].type != CPP_PRAGMA_EOL);
     563    149147512 :   c_lex_one_token (parser, &parser->tokens[1]);
     564    149147512 :   parser->tokens_avail = 2;
     565    149147512 :   return &parser->tokens[1];
     566              : }
     567              : 
     568              : /* Return a pointer to the Nth token from PARSER, reading it
     569              :    in if necessary.  The N-1th token is already read in.  */
     570              : 
     571              : c_token *
     572   1288015786 : c_parser_peek_nth_token (c_parser *parser, unsigned int n)
     573              : {
     574              :   /* N is 1-based, not zero-based.  */
     575   1288015786 :   gcc_assert (n > 0);
     576              : 
     577   1288015786 :   if (parser->tokens_avail >= n)
     578   1019086842 :     return &parser->tokens[n - 1];
     579    268928944 :   gcc_assert (parser->tokens_avail == n - 1);
     580    268928944 :   c_lex_one_token (parser, &parser->tokens[n - 1]);
     581    268928944 :   parser->tokens_avail = n;
     582    268928944 :   return &parser->tokens[n - 1];
     583              : }
     584              : 
     585              : /* Return a pointer to the Nth token from PARSER, reading it in as a
     586              :    raw look-ahead token if necessary.  The N-1th token is already read
     587              :    in.  Raw look-ahead tokens remain available for when the non-raw
     588              :    functions above are called.  */
     589              : 
     590              : c_token *
     591       136225 : c_parser_peek_nth_token_raw (c_parser *parser, unsigned int n)
     592              : {
     593              :   /* N is 1-based, not zero-based.  */
     594       136225 :   gcc_assert (n > 0);
     595              : 
     596       136225 :   if (parser->tokens_avail >= n)
     597        10327 :     return &parser->tokens[n - 1];
     598       125898 :   unsigned int raw_len = vec_safe_length (parser->raw_tokens);
     599       125898 :   unsigned int raw_avail
     600       125898 :     = parser->tokens_avail + raw_len - parser->raw_tokens_used;
     601       125898 :   gcc_assert (raw_avail >= n - 1);
     602       125898 :   if (raw_avail >= n)
     603        25743 :     return &(*parser->raw_tokens)[parser->raw_tokens_used
     604        25743 :                                   + n - 1 - parser->tokens_avail];
     605       100155 :   vec_safe_reserve (parser->raw_tokens, 1);
     606       100155 :   parser->raw_tokens->quick_grow (raw_len + 1);
     607       100155 :   c_lex_one_token (parser, &(*parser->raw_tokens)[raw_len], true);
     608       100155 :   return &(*parser->raw_tokens)[raw_len];
     609              : }
     610              : 
     611              : bool
     612     44663642 : c_keyword_starts_typename (enum rid keyword)
     613              : {
     614     44663642 :   switch (keyword)
     615              :     {
     616              :     case RID_UNSIGNED:
     617              :     case RID_LONG:
     618              :     case RID_SHORT:
     619              :     case RID_SIGNED:
     620              :     case RID_COMPLEX:
     621              :     case RID_INT:
     622              :     case RID_CHAR:
     623              :     case RID_FLOAT:
     624              :     case RID_DOUBLE:
     625              :     case RID_VOID:
     626              :     case RID_DFLOAT32:
     627              :     case RID_DFLOAT64:
     628              :     case RID_DFLOAT128:
     629              :     case RID_DFLOAT64X:
     630              :     CASE_RID_FLOATN_NX:
     631              :     case RID_BOOL:
     632              :     case RID_BITINT:
     633              :     case RID_ENUM:
     634              :     case RID_STRUCT:
     635              :     case RID_UNION:
     636              :     case RID_TYPEOF:
     637              :     case RID_TYPEOF_UNQUAL:
     638              :     case RID_CONST:
     639              :     case RID_ATOMIC:
     640              :     case RID_VOLATILE:
     641              :     case RID_RESTRICT:
     642              :     case RID_ATTRIBUTE:
     643              :     case RID_FRACT:
     644              :     case RID_ACCUM:
     645              :     case RID_SAT:
     646              :     case RID_AUTO_TYPE:
     647              :     case RID_ALIGNAS:
     648              :       return true;
     649     36636666 :     default:
     650     36636666 :       if (keyword >= RID_FIRST_INT_N
     651              :           && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
     652          547 :           && int_n_enabled_p[keyword - RID_FIRST_INT_N])
     653              :         return true;
     654              :       return false;
     655              :     }
     656              : }
     657              : 
     658              : /* Return true if TOKEN can start a type name,
     659              :    false otherwise.  */
     660              : bool
     661    447778717 : c_token_starts_typename (c_token *token)
     662              : {
     663    447778717 :   switch (token->type)
     664              :     {
     665    396580538 :     case CPP_NAME:
     666    396580538 :       switch (token->id_kind)
     667              :         {
     668              :         case C_ID_ID:
     669              :           return false;
     670              :         case C_ID_ADDRSPACE:
     671              :           return true;
     672              :         case C_ID_TYPENAME:
     673              :           return true;
     674            0 :         case C_ID_CLASSNAME:
     675            0 :           gcc_assert (c_dialect_objc ());
     676              :           return true;
     677            0 :         default:
     678            0 :           gcc_unreachable ();
     679              :         }
     680     44608194 :     case CPP_KEYWORD:
     681     44608194 :       return c_keyword_starts_typename (token->keyword);
     682            0 :     case CPP_LESS:
     683            0 :       if (c_dialect_objc ())
     684              :         return true;
     685              :       return false;
     686              :     default:
     687              :       return false;
     688              :     }
     689              : }
     690              : 
     691              : /* Return true if the next token from PARSER, starting from token N, can start
     692              :    a type name, false otherwise.  LA specifies how to do lookahead in order to
     693              :    detect unknown type names.  If unsure, pick CLA_PREFER_ID.  */
     694              : 
     695              : static inline bool
     696    318973440 : c_parser_next_tokens_start_typename (c_parser *parser, enum c_lookahead_kind la,
     697              :                                      unsigned int n = 1)
     698              : {
     699    318973440 :   c_token *token = c_parser_peek_nth_token (parser, n);
     700    318973440 :   if (c_token_starts_typename (token))
     701              :     return true;
     702              : 
     703              :   /* Try a bit harder to detect an unknown typename.  */
     704     69631839 :   if (la != cla_prefer_id
     705     44364165 :       && token->type == CPP_NAME
     706      6474981 :       && token->id_kind == C_ID_ID
     707              : 
     708              :       /* Do not try too hard when we could have "object in array".  */
     709      6474981 :       && !parser->objc_could_be_foreach_context
     710              : 
     711      6474981 :       && (la == cla_prefer_type
     712      6474888 :           || c_parser_peek_nth_token (parser, n + 1)->type == CPP_NAME
     713      6474804 :           || c_parser_peek_nth_token (parser, n + 1)->type == CPP_MULT)
     714              : 
     715              :       /* Only unknown identifiers.  */
     716     69633273 :       && !lookup_name (token->value))
     717              :     return true;
     718              : 
     719              :   return false;
     720              : }
     721              : 
     722              : /* Return true if TOKEN, after an open parenthesis, can start a
     723              :    compound literal (either a storage class specifier allowed in that
     724              :    context, or a type name), false otherwise.  */
     725              : static bool
     726    128801361 : c_token_starts_compound_literal (c_token *token)
     727              : {
     728    128801361 :   switch (token->type)
     729              :     {
     730      4486994 :     case CPP_KEYWORD:
     731      4486994 :       switch (token->keyword)
     732              :         {
     733              :         case RID_CONSTEXPR:
     734              :         case RID_REGISTER:
     735              :         case RID_STATIC:
     736              :         case RID_THREAD:
     737              :           return true;
     738              :         default:
     739              :           break;
     740              :         }
     741              :       /* Fall through.  */
     742    128801051 :     default:
     743    128801051 :       return c_token_starts_typename (token);
     744              :     }
     745              : }
     746              : 
     747              : /* Return true if TOKEN is a type qualifier, false otherwise.  */
     748              : static bool
     749    436638773 : c_token_is_qualifier (c_token *token)
     750              : {
     751    436638773 :   switch (token->type)
     752              :     {
     753    432820174 :     case CPP_NAME:
     754    432820174 :       switch (token->id_kind)
     755              :         {
     756              :         case C_ID_ADDRSPACE:
     757              :           return true;
     758              :         default:
     759              :           return false;
     760              :         }
     761      3818599 :     case CPP_KEYWORD:
     762      3818599 :       switch (token->keyword)
     763              :         {
     764              :         case RID_CONST:
     765              :         case RID_VOLATILE:
     766              :         case RID_RESTRICT:
     767              :         case RID_ATTRIBUTE:
     768              :         case RID_ATOMIC:
     769              :           return true;
     770              :         default:
     771              :           return false;
     772              :         }
     773              :     case CPP_LESS:
     774              :       return false;
     775            0 :     default:
     776            0 :       gcc_unreachable ();
     777              :     }
     778              : }
     779              : 
     780              : /* Return true if the next token from PARSER is a type qualifier,
     781              :    false otherwise.  */
     782              : static inline bool
     783    436638773 : c_parser_next_token_is_qualifier (c_parser *parser)
     784              : {
     785    436638773 :   c_token *token = c_parser_peek_token (parser);
     786    436638773 :   return c_token_is_qualifier (token);
     787              : }
     788              : 
     789              : /* Return true if TOKEN can start declaration specifiers (not
     790              :    including standard attributes), false otherwise.  */
     791              : static bool
     792    175959936 : c_token_starts_declspecs (c_token *token)
     793              : {
     794    175959936 :   switch (token->type)
     795              :     {
     796     98148205 :     case CPP_NAME:
     797     98148205 :       switch (token->id_kind)
     798              :         {
     799              :         case C_ID_ID:
     800              :           return false;
     801              :         case C_ID_ADDRSPACE:
     802              :           return true;
     803              :         case C_ID_TYPENAME:
     804              :           return true;
     805            0 :         case C_ID_CLASSNAME:
     806            0 :           gcc_assert (c_dialect_objc ());
     807              :           return true;
     808            0 :         default:
     809            0 :           gcc_unreachable ();
     810              :         }
     811     76123258 :     case CPP_KEYWORD:
     812     76123258 :       switch (token->keyword)
     813              :         {
     814              :         case RID_STATIC:
     815              :         case RID_EXTERN:
     816              :         case RID_REGISTER:
     817              :         case RID_TYPEDEF:
     818              :         case RID_INLINE:
     819              :         case RID_NORETURN:
     820              :         case RID_AUTO:
     821              :         case RID_THREAD:
     822              :         case RID_UNSIGNED:
     823              :         case RID_LONG:
     824              :         case RID_SHORT:
     825              :         case RID_SIGNED:
     826              :         case RID_COMPLEX:
     827              :         case RID_INT:
     828              :         case RID_CHAR:
     829              :         case RID_FLOAT:
     830              :         case RID_DOUBLE:
     831              :         case RID_VOID:
     832              :         case RID_DFLOAT32:
     833              :         case RID_DFLOAT64:
     834              :         case RID_DFLOAT128:
     835              :         case RID_DFLOAT64X:
     836              :         CASE_RID_FLOATN_NX:
     837              :         case RID_BOOL:
     838              :         case RID_BITINT:
     839              :         case RID_ENUM:
     840              :         case RID_STRUCT:
     841              :         case RID_UNION:
     842              :         case RID_TYPEOF:
     843              :         case RID_TYPEOF_UNQUAL:
     844              :         case RID_CONST:
     845              :         case RID_VOLATILE:
     846              :         case RID_RESTRICT:
     847              :         case RID_ATTRIBUTE:
     848              :         case RID_FRACT:
     849              :         case RID_ACCUM:
     850              :         case RID_SAT:
     851              :         case RID_ALIGNAS:
     852              :         case RID_ATOMIC:
     853              :         case RID_AUTO_TYPE:
     854              :         case RID_CONSTEXPR:
     855              :           return true;
     856     36288686 :         default:
     857     36288686 :           if (token->keyword >= RID_FIRST_INT_N
     858              :               && token->keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
     859          461 :               && int_n_enabled_p[token->keyword - RID_FIRST_INT_N])
     860              :             return true;
     861              :           return false;
     862              :         }
     863            2 :     case CPP_LESS:
     864            2 :       if (c_dialect_objc ())
     865              :         return true;
     866              :       return false;
     867              :     default:
     868              :       return false;
     869              :     }
     870              : }
     871              : 
     872              : 
     873              : /* Return true if TOKEN can start declaration specifiers (not
     874              :    including standard attributes) or a static assertion, false
     875              :    otherwise.  */
     876              : static bool
     877     51076623 : c_token_starts_declaration (c_token *token)
     878              : {
     879     51076623 :   if (c_token_starts_declspecs (token)
     880     51076623 :       || token->keyword == RID_STATIC_ASSERT)
     881      7653270 :     return true;
     882              :   else
     883              :     return false;
     884              : }
     885              : 
     886              : /* Return true if the next token from PARSER can start declaration
     887              :    specifiers (not including standard attributes), false
     888              :    otherwise.  */
     889              : bool
     890    124883313 : c_parser_next_token_starts_declspecs (c_parser *parser)
     891              : {
     892    124883313 :   c_token *token = c_parser_peek_token (parser);
     893              : 
     894              :   /* In Objective-C, a classname normally starts a declspecs unless it
     895              :      is immediately followed by a dot.  In that case, it is the
     896              :      Objective-C 2.0 "dot-syntax" for class objects, ie, calls the
     897              :      setter/getter on the class.  c_token_starts_declspecs() can't
     898              :      differentiate between the two cases because it only checks the
     899              :      current token, so we have a special check here.  */
     900    124883313 :   if (c_dialect_objc ()
     901            0 :       && token->type == CPP_NAME
     902            0 :       && token->id_kind == C_ID_CLASSNAME
     903    124883313 :       && c_parser_peek_2nd_token (parser)->type == CPP_DOT)
     904              :     return false;
     905              : 
     906    124883313 :   return c_token_starts_declspecs (token);
     907              : }
     908              : 
     909              : static bool c_parser_check_balanced_raw_token_sequence (c_parser *,
     910              :                                                         unsigned int *);
     911              : 
     912              : /* Return true if the next tokens from PARSER (starting with token N, 1-based)
     913              :    can start declaration specifiers (not including standard attributes) or a
     914              :    static assertion, false otherwise.  */
     915              : bool
     916     51077921 : c_parser_next_tokens_start_declaration (c_parser *parser, unsigned int n)
     917              : {
     918     51077921 :   c_token *token = c_parser_peek_nth_token (parser, n);
     919              : 
     920              :   /* Same as above.  */
     921     51077921 :   if (c_dialect_objc ()
     922            0 :       && token->type == CPP_NAME
     923            0 :       && token->id_kind == C_ID_CLASSNAME
     924     51077921 :       && c_parser_peek_nth_token (parser, n + 1)->type == CPP_DOT)
     925              :     return false;
     926              : 
     927              :   /* Labels do not start declarations.  */
     928     51077921 :   if (token->type == CPP_NAME
     929     51077921 :       && c_parser_peek_nth_token (parser, n + 1)->type == CPP_COLON)
     930              :     return false;
     931              : 
     932              :   /* A static assertion is only a declaration if followed by a semicolon;
     933              :      otherwise, it may be an expression in C2Y.  */
     934     51077903 :   if (token->keyword == RID_STATIC_ASSERT
     935     51077903 :       && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_PAREN)
     936              :     {
     937         1280 :       n += 2;
     938         1280 :       if (!c_parser_check_balanced_raw_token_sequence (parser, &n)
     939         1280 :           || c_parser_peek_nth_token_raw (parser, n)->type != CPP_CLOSE_PAREN)
     940              :         /* Invalid static assertion syntax; treat as a declaration and report a
     941              :            syntax error there.  */
     942            5 :         return true;
     943         1275 :       return c_parser_peek_nth_token_raw (parser, n + 1)->type == CPP_SEMICOLON;
     944              :     }
     945              : 
     946     51076623 :   if (c_token_starts_declaration (token))
     947              :     return true;
     948              : 
     949     43423353 :   if (c_parser_next_tokens_start_typename (parser, cla_nonabstract_decl, n))
     950              :     return true;
     951              : 
     952              :   return false;
     953              : }
     954              : 
     955              : /* Consume the next token from PARSER.  */
     956              : 
     957              : void
     958   2312505190 : c_parser_consume_token (c_parser *parser)
     959              : {
     960   2312505190 :   gcc_assert (parser->tokens_avail >= 1);
     961   2312505190 :   gcc_assert (parser->tokens[0].type != CPP_EOF);
     962   2312505190 :   gcc_assert (!parser->in_pragma || parser->tokens[0].type != CPP_PRAGMA_EOL);
     963   2312505190 :   gcc_assert (parser->error || parser->tokens[0].type != CPP_PRAGMA);
     964   2312505190 :   parser->last_token_location = parser->tokens[0].location;
     965   2312505190 :   if (parser->tokens != &parser->tokens_buf[0])
     966        45546 :     parser->tokens++;
     967   2312459644 :   else if (parser->tokens_avail >= 2)
     968              :     {
     969    152426053 :       parser->tokens[0] = parser->tokens[1];
     970    152426053 :       if (parser->tokens_avail >= 3)
     971              :         {
     972        32024 :           parser->tokens[1] = parser->tokens[2];
     973        32024 :           if (parser->tokens_avail >= 4)
     974        12572 :             parser->tokens[2] = parser->tokens[3];
     975              :         }
     976              :     }
     977   2312505190 :   parser->tokens_avail--;
     978   2312505190 :   parser->seen_string_literal = false;
     979   2312505190 : }
     980              : 
     981              : /* Expect the current token to be a #pragma.  Consume it and remember
     982              :    that we've begun parsing a pragma.  */
     983              : 
     984              : static void
     985      1928572 : c_parser_consume_pragma (c_parser *parser)
     986              : {
     987      1928572 :   gcc_assert (!parser->in_pragma);
     988      1928572 :   gcc_assert (parser->tokens_avail >= 1);
     989      1928572 :   gcc_assert (parser->tokens[0].type == CPP_PRAGMA);
     990      1928572 :   if (parser->tokens != &parser->tokens_buf[0])
     991          924 :     parser->tokens++;
     992      1927648 :   else if (parser->tokens_avail >= 2)
     993              :     {
     994          299 :       parser->tokens[0] = parser->tokens[1];
     995          299 :       if (parser->tokens_avail >= 3)
     996           10 :         parser->tokens[1] = parser->tokens[2];
     997              :     }
     998      1928572 :   parser->tokens_avail--;
     999      1928572 :   parser->in_pragma = true;
    1000      1928572 : }
    1001              : 
    1002              : /* Update the global input_location from TOKEN.  */
    1003              : static inline void
    1004      8152321 : c_parser_set_source_position_from_token (c_token *token)
    1005              : {
    1006      8152321 :   if (token->type != CPP_EOF)
    1007              :     {
    1008      8152245 :       input_location = token->location;
    1009              :     }
    1010              : }
    1011              : 
    1012              : /* Helper function for c_parser_error.
    1013              :    Having peeked a token of kind TOK1_KIND that might signify
    1014              :    a conflict marker, peek successor tokens to determine
    1015              :    if we actually do have a conflict marker.
    1016              :    Specifically, we consider a run of 7 '<', '=' or '>' characters
    1017              :    at the start of a line as a conflict marker.
    1018              :    These come through the lexer as three pairs and a single,
    1019              :    e.g. three CPP_LSHIFT ("<<") and a CPP_LESS ('<').
    1020              :    If it returns true, *OUT_LOC is written to with the location/range
    1021              :    of the marker.  */
    1022              : 
    1023              : static bool
    1024           30 : c_parser_peek_conflict_marker (c_parser *parser, enum cpp_ttype tok1_kind,
    1025              :                                location_t *out_loc)
    1026              : {
    1027           30 :   c_token *token2 = c_parser_peek_2nd_token (parser);
    1028           30 :   if (token2->type != tok1_kind)
    1029              :     return false;
    1030           25 :   c_token *token3 = c_parser_peek_nth_token (parser, 3);
    1031           25 :   if (token3->type != tok1_kind)
    1032              :     return false;
    1033           22 :   c_token *token4 = c_parser_peek_nth_token (parser, 4);
    1034           22 :   if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
    1035              :     return false;
    1036              : 
    1037              :   /* It must be at the start of the line.  */
    1038           15 :   location_t start_loc = c_parser_peek_token (parser)->location;
    1039           15 :   if (LOCATION_COLUMN (start_loc) != 1)
    1040              :     return false;
    1041              : 
    1042              :   /* We have a conflict marker.  Construct a location of the form:
    1043              :        <<<<<<<
    1044              :        ^~~~~~~
    1045              :      with start == caret, finishing at the end of the marker.  */
    1046           12 :   location_t finish_loc = get_finish (token4->location);
    1047           12 :   *out_loc = make_location (start_loc, start_loc, finish_loc);
    1048              : 
    1049           12 :   return true;
    1050              : }
    1051              : 
    1052              : /* Issue a diagnostic of the form
    1053              :       FILE:LINE: MESSAGE before TOKEN
    1054              :    where TOKEN is the next token in the input stream of PARSER.
    1055              :    MESSAGE (specified by the caller) is usually of the form "expected
    1056              :    OTHER-TOKEN".
    1057              : 
    1058              :    Use RICHLOC as the location of the diagnostic.
    1059              : 
    1060              :    Do not issue a diagnostic if still recovering from an error.
    1061              : 
    1062              :    Return true iff an error was actually emitted.
    1063              : 
    1064              :    ??? This is taken from the C++ parser, but building up messages in
    1065              :    this way is not i18n-friendly and some other approach should be
    1066              :    used.  */
    1067              : 
    1068              : static bool
    1069         3082 : c_parser_error_richloc (c_parser *parser, const char *gmsgid,
    1070              :                         rich_location *richloc)
    1071              : {
    1072         3082 :   c_token *token = c_parser_peek_token (parser);
    1073         3082 :   if (parser->error)
    1074              :     return false;
    1075         2349 :   parser->error = true;
    1076         2349 :   if (!gmsgid)
    1077              :     return false;
    1078              : 
    1079              :   /* If this is actually a conflict marker, report it as such.  */
    1080         2234 :   if (token->type == CPP_LSHIFT
    1081         2234 :       || token->type == CPP_RSHIFT
    1082         2215 :       || token->type == CPP_EQ_EQ)
    1083              :     {
    1084           30 :       location_t loc;
    1085           30 :       if (c_parser_peek_conflict_marker (parser, token->type, &loc))
    1086              :         {
    1087           12 :           error_at (loc, "version control conflict marker in file");
    1088           12 :           return true;
    1089              :         }
    1090              :     }
    1091              : 
    1092              :   /* If we were parsing a string-literal and there is an unknown name
    1093              :      token right after, then check to see if that could also have been
    1094              :      a literal string by checking the name against a list of known
    1095              :      standard string literal constants defined in header files. If
    1096              :      there is one, then add that as an hint to the error message. */
    1097         2222 :   auto_diagnostic_group d;
    1098         2222 :   name_hint h;
    1099         2222 :   if (parser->seen_string_literal && token->type == CPP_NAME)
    1100              :     {
    1101           16 :       tree name = token->value;
    1102           16 :       const char *token_name = IDENTIFIER_POINTER (name);
    1103           16 :       const char *header_hint
    1104           16 :         = get_c_stdlib_header_for_string_macro_name (token_name);
    1105           16 :       if (header_hint != NULL)
    1106           48 :         h = name_hint (nullptr,
    1107              :                        std::make_unique<suggest_missing_header>
    1108           32 :                          (token->location,
    1109              :                           token_name,
    1110           16 :                           header_hint));
    1111              :     }
    1112              : 
    1113         2222 :   c_parse_error (gmsgid,
    1114              :                  /* Because c_parse_error does not understand
    1115              :                     CPP_KEYWORD, keywords are treated like
    1116              :                     identifiers.  */
    1117         2222 :                  (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
    1118              :                  /* ??? The C parser does not save the cpp flags of a
    1119              :                     token, we need to pass 0 here and we will not get
    1120              :                     the source spelling of some tokens but rather the
    1121              :                     canonical spelling.  */
    1122              :                  token->value, /*flags=*/0, richloc);
    1123         2222 :   return true;
    1124         2222 : }
    1125              : 
    1126              : /* As c_parser_error_richloc, but issue the message at the
    1127              :    location of PARSER's next token, or at input_location
    1128              :    if the next token is EOF.  */
    1129              : 
    1130              : bool
    1131         1949 : c_parser_error (c_parser *parser, const char *gmsgid)
    1132              : {
    1133         1949 :   c_token *token = c_parser_peek_token (parser);
    1134         1949 :   c_parser_set_source_position_from_token (token);
    1135         1949 :   rich_location richloc (line_table, input_location);
    1136         1949 :   return c_parser_error_richloc (parser, gmsgid, &richloc);
    1137         1949 : }
    1138              : 
    1139              : /* Some tokens naturally come in pairs e.g.'(' and ')'.
    1140              :    This class is for tracking such a matching pair of symbols.
    1141              :    In particular, it tracks the location of the first token,
    1142              :    so that if the second token is missing, we can highlight the
    1143              :    location of the first token when notifying the user about the
    1144              :    problem.  */
    1145              : 
    1146              : template <typename traits_t>
    1147              : class token_pair
    1148              : {
    1149              :  public:
    1150              :   /* token_pair's ctor.  */
    1151    176887235 :   token_pair () : m_open_loc (UNKNOWN_LOCATION) {}
    1152              : 
    1153              :   /* If the next token is the opening symbol for this pair, consume it and
    1154              :      return true.
    1155              :      Otherwise, issue an error and return false.
    1156              :      In either case, record the location of the opening token.  */
    1157              : 
    1158      4529317 :   bool require_open (c_parser *parser)
    1159              :   {
    1160      4529317 :     c_token *token = c_parser_peek_token (parser);
    1161      4529317 :     if (token)
    1162      4529317 :       m_open_loc = token->location;
    1163              : 
    1164      4529317 :     return c_parser_require (parser, traits_t::open_token_type,
    1165      4529317 :                              traits_t::open_gmsgid);
    1166              :   }
    1167              : 
    1168              :   /* Consume the next token from PARSER, recording its location as
    1169              :      that of the opening token within the pair.  */
    1170              : 
    1171    172358214 :   void consume_open (c_parser *parser)
    1172              :   {
    1173    172358214 :     c_token *token = c_parser_peek_token (parser);
    1174    172358214 :     gcc_assert (token->type == traits_t::open_token_type);
    1175    172358214 :     m_open_loc = token->location;
    1176    172358214 :     c_parser_consume_token (parser);
    1177    172358214 :   }
    1178              : 
    1179              :   /* If the next token is the closing symbol for this pair, consume it
    1180              :      and return true.
    1181              :      Otherwise, issue an error, highlighting the location of the
    1182              :      corresponding opening token, and return false.  */
    1183              : 
    1184      1795772 :   bool require_close (c_parser *parser) const
    1185              :   {
    1186      1795772 :     return c_parser_require (parser, traits_t::close_token_type,
    1187      1795772 :                              traits_t::close_gmsgid, m_open_loc);
    1188              :   }
    1189              : 
    1190              :   /* Like token_pair::require_close, except that tokens will be skipped
    1191              :      until the desired token is found.  An error message is still produced
    1192              :      if the next token is not as expected.  */
    1193              : 
    1194    173702336 :   void skip_until_found_close (c_parser *parser) const
    1195              :   {
    1196    173702336 :     c_parser_skip_until_found (parser, traits_t::close_token_type,
    1197    173702336 :                                traits_t::close_gmsgid, m_open_loc);
    1198        49135 :   }
    1199              : 
    1200              :  private:
    1201              :   location_t m_open_loc;
    1202              : };
    1203              : 
    1204              : /* Traits for token_pair<T> for tracking matching pairs of parentheses.  */
    1205              : 
    1206              : struct matching_paren_traits
    1207              : {
    1208              :   static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
    1209              :   static const char * const open_gmsgid;
    1210              :   static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
    1211              :   static const char * const close_gmsgid;
    1212              : };
    1213              : 
    1214              : const char * const matching_paren_traits::open_gmsgid = "expected %<(%>";
    1215              : const char * const matching_paren_traits::close_gmsgid = "expected %<)%>";
    1216              : 
    1217              : /* "matching_parens" is a token_pair<T> class for tracking matching
    1218              :    pairs of parentheses.  */
    1219              : 
    1220              : typedef token_pair<matching_paren_traits> matching_parens;
    1221              : 
    1222              : /* Traits for token_pair<T> for tracking matching pairs of braces.  */
    1223              : 
    1224              : struct matching_brace_traits
    1225              : {
    1226              :   static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
    1227              :   static const char * const open_gmsgid;
    1228              :   static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
    1229              :   static const char * const close_gmsgid;
    1230              : };
    1231              : 
    1232              : const char * const matching_brace_traits::open_gmsgid = "expected %<{%>";
    1233              : const char * const matching_brace_traits::close_gmsgid = "expected %<}%>";
    1234              : 
    1235              : /* "matching_braces" is a token_pair<T> class for tracking matching
    1236              :    pairs of braces.  */
    1237              : 
    1238              : typedef token_pair<matching_brace_traits> matching_braces;
    1239              : 
    1240              : /* Get a description of the matching symbol to TYPE e.g. "(" for
    1241              :    CPP_CLOSE_PAREN.  */
    1242              : 
    1243              : static const char *
    1244            4 : get_matching_symbol (enum cpp_ttype type)
    1245              : {
    1246            4 :   switch (type)
    1247              :     {
    1248            0 :     default:
    1249            0 :       gcc_unreachable ();
    1250              :     case CPP_CLOSE_PAREN:
    1251              :       return "(";
    1252            1 :     case CPP_CLOSE_BRACE:
    1253            1 :       return "{";
    1254              :     }
    1255              : }
    1256              : 
    1257              : /* If the next token is of the indicated TYPE, consume it.  Otherwise,
    1258              :    issue the error MSGID.  If MSGID is NULL then a message has already
    1259              :    been produced and no message will be produced this time.  Returns
    1260              :    true if found, false otherwise.
    1261              : 
    1262              :    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
    1263              :    within any error as the location of an "opening" token matching
    1264              :    the close token TYPE (e.g. the location of the '(' when TYPE is
    1265              :    CPP_CLOSE_PAREN).
    1266              : 
    1267              :    If TYPE_IS_UNIQUE is true (the default) then msgid describes exactly
    1268              :    one type (e.g. "expected %<)%>") and thus it may be reasonable to
    1269              :    attempt to generate a fix-it hint for the problem.
    1270              :    Otherwise msgid describes multiple token types (e.g.
    1271              :    "expected %<;%>, %<,%> or %<)%>"), and thus we shouldn't attempt to
    1272              :    generate a fix-it hint.  */
    1273              : 
    1274              : bool
    1275    452509532 : c_parser_require (c_parser *parser,
    1276              :                   enum cpp_ttype type,
    1277              :                   const char *msgid,
    1278              :                   location_t matching_location,
    1279              :                   bool type_is_unique)
    1280              : {
    1281    452509532 :   if (c_parser_next_token_is (parser, type))
    1282              :     {
    1283    452508399 :       c_parser_consume_token (parser);
    1284    452508399 :       return true;
    1285              :     }
    1286              :   else
    1287              :     {
    1288         1133 :       location_t next_token_loc = c_parser_peek_token (parser)->location;
    1289         1133 :       gcc_rich_location richloc (next_token_loc);
    1290              : 
    1291              :       /* Potentially supply a fix-it hint, suggesting to add the
    1292              :          missing token immediately after the *previous* token.
    1293              :          This may move the primary location within richloc.  */
    1294         1133 :       if (!parser->error && type_is_unique)
    1295          666 :         maybe_suggest_missing_token_insertion (&richloc, type,
    1296              :                                                parser->last_token_location);
    1297              : 
    1298              :       /* If matching_location != UNKNOWN_LOCATION, highlight it.
    1299              :          Attempt to consolidate diagnostics by printing it as a
    1300              :          secondary range within the main diagnostic.  */
    1301         1133 :       bool added_matching_location = false;
    1302         1133 :       if (matching_location != UNKNOWN_LOCATION)
    1303          413 :         added_matching_location
    1304          413 :           = richloc.add_location_if_nearby (*global_dc, matching_location);
    1305              : 
    1306         1133 :       if (c_parser_error_richloc (parser, msgid, &richloc))
    1307              :         /* If we weren't able to consolidate matching_location, then
    1308              :            print it as a secondary diagnostic.  */
    1309          559 :         if (matching_location != UNKNOWN_LOCATION && !added_matching_location)
    1310            4 :           inform (matching_location, "to match this %qs",
    1311              :                   get_matching_symbol (type));
    1312              : 
    1313         1133 :       return false;
    1314         1133 :     }
    1315              : }
    1316              : 
    1317              : /* If the next token is the indicated keyword, consume it.  Otherwise,
    1318              :    issue the error MSGID.  Returns true if found, false otherwise.  */
    1319              : 
    1320              : static bool
    1321       145321 : c_parser_require_keyword (c_parser *parser,
    1322              :                           enum rid keyword,
    1323              :                           const char *msgid)
    1324              : {
    1325       145321 :   if (c_parser_next_token_is_keyword (parser, keyword))
    1326              :     {
    1327       145320 :       c_parser_consume_token (parser);
    1328       145320 :       return true;
    1329              :     }
    1330              :   else
    1331              :     {
    1332            1 :       c_parser_error (parser, msgid);
    1333            1 :       return false;
    1334              :     }
    1335              : }
    1336              : 
    1337              : /* Like c_parser_require, except that tokens will be skipped until the
    1338              :    desired token is found.  An error message is still produced if the
    1339              :    next token is not as expected.  If MSGID is NULL then a message has
    1340              :    already been produced and no message will be produced this
    1341              :    time.
    1342              : 
    1343              :    If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
    1344              :    within any error as the location of an "opening" token matching
    1345              :    the close token TYPE (e.g. the location of the '(' when TYPE is
    1346              :    CPP_CLOSE_PAREN).  */
    1347              : 
    1348              : void
    1349    225742117 : c_parser_skip_until_found (c_parser *parser,
    1350              :                            enum cpp_ttype type,
    1351              :                            const char *msgid,
    1352              :                            location_t matching_location)
    1353              : {
    1354    225742117 :   unsigned nesting_depth = 0;
    1355              : 
    1356    225742117 :   if (c_parser_require (parser, type, msgid, matching_location))
    1357              :     {
    1358    225741214 :       if (UNLIKELY (type == CPP_PRAGMA_EOL) && parser->in_omp_attribute_pragma)
    1359              :         {
    1360            0 :           c_token *token = c_parser_peek_token (parser);
    1361            0 :           if (token->type == CPP_EOF)
    1362              :             {
    1363            0 :               parser->tokens = parser->in_omp_attribute_pragma->save_tokens;
    1364            0 :               parser->tokens_avail
    1365            0 :                 = parser->in_omp_attribute_pragma->save_tokens_avail;
    1366            0 :               parser->in_omp_attribute_pragma = NULL;
    1367              :             }
    1368              :         }
    1369    225741214 :       return;
    1370              :     }
    1371              : 
    1372              :   /* Skip tokens until the desired token is found.  */
    1373         6033 :   while (true)
    1374              :     {
    1375              :       /* Peek at the next token.  */
    1376         3468 :       c_token *token = c_parser_peek_token (parser);
    1377              :       /* If we've reached the token we want, consume it and stop.  */
    1378         3468 :       if (token->type == type && !nesting_depth)
    1379              :         {
    1380          700 :           c_parser_consume_token (parser);
    1381          700 :           if (UNLIKELY (type == CPP_PRAGMA_EOL)
    1382          108 :               && parser->in_omp_attribute_pragma)
    1383              :             {
    1384            1 :               c_token *token = c_parser_peek_token (parser);
    1385            1 :               if (token->type == CPP_EOF)
    1386              :                 {
    1387            1 :                   parser->tokens = parser->in_omp_attribute_pragma->save_tokens;
    1388            1 :                   parser->tokens_avail
    1389            1 :                     = parser->in_omp_attribute_pragma->save_tokens_avail;
    1390            1 :                   parser->in_omp_attribute_pragma = NULL;
    1391              :                 }
    1392              :             }
    1393              :           break;
    1394              :         }
    1395              : 
    1396              :       /* If we've run out of tokens, stop.  */
    1397         2768 :       if (token->type == CPP_EOF)
    1398              :         return;
    1399         2749 :       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
    1400              :         return;
    1401         2683 :       if (token->type == CPP_OPEN_BRACE
    1402              :           || token->type == CPP_OPEN_PAREN
    1403              :           || token->type == CPP_OPEN_SQUARE)
    1404          296 :         ++nesting_depth;
    1405              :       else if (token->type == CPP_CLOSE_BRACE
    1406              :                || token->type == CPP_CLOSE_PAREN
    1407              :                || token->type == CPP_CLOSE_SQUARE)
    1408              :         {
    1409          414 :           if (nesting_depth-- == 0)
    1410              :             break;
    1411              :         }
    1412              :       /* Consume this token.  */
    1413         2565 :       c_parser_consume_token (parser);
    1414         2565 :     }
    1415          818 :   parser->error = false;
    1416              : }
    1417              : 
    1418              : /* Skip tokens until the end of a parameter is found, but do not
    1419              :    consume the comma, semicolon or closing delimiter.  */
    1420              : 
    1421              : static void
    1422           97 : c_parser_skip_to_end_of_parameter (c_parser *parser)
    1423              : {
    1424           97 :   unsigned nesting_depth = 0;
    1425              : 
    1426          501 :   while (true)
    1427              :     {
    1428          299 :       c_token *token = c_parser_peek_token (parser);
    1429          299 :       if ((token->type == CPP_COMMA || token->type == CPP_SEMICOLON)
    1430           25 :           && !nesting_depth)
    1431              :         break;
    1432              :       /* If we've run out of tokens, stop.  */
    1433          274 :       if (token->type == CPP_EOF)
    1434              :         return;
    1435          274 :       if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
    1436              :         return;
    1437          274 :       if (token->type == CPP_OPEN_BRACE
    1438              :           || token->type == CPP_OPEN_PAREN
    1439              :           || token->type == CPP_OPEN_SQUARE)
    1440            3 :         ++nesting_depth;
    1441              :       else if (token->type == CPP_CLOSE_BRACE
    1442              :                || token->type == CPP_CLOSE_PAREN
    1443              :                || token->type == CPP_CLOSE_SQUARE)
    1444              :         {
    1445           75 :           if (nesting_depth-- == 0)
    1446              :             break;
    1447              :         }
    1448              :       /* Consume this token.  */
    1449          202 :       c_parser_consume_token (parser);
    1450          202 :     }
    1451           97 :   parser->error = false;
    1452              : }
    1453              : 
    1454              : /* Skip tokens until a non-nested closing curly brace is the next
    1455              :    token, or there are no more tokens. Return true in the first case,
    1456              :    false otherwise.  */
    1457              : 
    1458              : static bool
    1459           26 : c_parser_skip_to_closing_brace (c_parser *parser)
    1460              : {
    1461           26 :   unsigned nesting_depth = 0;
    1462              : 
    1463           96 :   while (true)
    1464              :     {
    1465           61 :       c_token *token = c_parser_peek_token (parser);
    1466              : 
    1467           61 :       switch (token->type)
    1468              :         {
    1469            2 :         case CPP_PRAGMA_EOL:
    1470            2 :           if (!parser->in_pragma)
    1471              :             break;
    1472              :           /* FALLTHRU */
    1473              :         case CPP_EOF:
    1474              :           /* If we've run out of tokens, stop.  */
    1475              :           return false;
    1476              : 
    1477           24 :         case CPP_CLOSE_BRACE:
    1478              :           /* If the next token is a non-nested `}', then we have reached
    1479              :              the end of the current block.  */
    1480           24 :           if (nesting_depth-- == 0)
    1481              :             return true;
    1482              :           break;
    1483              : 
    1484            0 :         case CPP_OPEN_BRACE:
    1485              :           /* If it the next token is a `{', then we are entering a new
    1486              :              block.  Consume the entire block.  */
    1487            0 :           ++nesting_depth;
    1488            0 :           break;
    1489              : 
    1490              :         default:
    1491              :           break;
    1492              :         }
    1493              : 
    1494              :       /* Consume the token.  */
    1495           35 :       c_parser_consume_token (parser);
    1496           35 :     }
    1497              : }
    1498              : 
    1499              : /* Expect to be at the end of the pragma directive and consume an
    1500              :    end of line marker.  */
    1501              : 
    1502              : static void
    1503      1929714 : c_parser_skip_to_pragma_eol (c_parser *parser, bool error_if_not_eol = true)
    1504              : {
    1505      1929714 :   gcc_assert (parser->in_pragma);
    1506      1929714 :   parser->in_pragma = false;
    1507              : 
    1508      1929714 :   if (error_if_not_eol && c_parser_peek_token (parser)->type != CPP_PRAGMA_EOL)
    1509          197 :     c_parser_error (parser, "expected end of line");
    1510              : 
    1511      1931094 :   cpp_ttype token_type;
    1512      1931094 :   do
    1513              :     {
    1514      1931094 :       c_token *token = c_parser_peek_token (parser);
    1515      1931094 :       token_type = token->type;
    1516      1931094 :       if (token_type == CPP_EOF)
    1517              :         break;
    1518      1931094 :       c_parser_consume_token (parser);
    1519              :     }
    1520      1931094 :   while (token_type != CPP_PRAGMA_EOL);
    1521              : 
    1522      1929714 :   if (parser->in_omp_attribute_pragma)
    1523              :     {
    1524          754 :       c_token *token = c_parser_peek_token (parser);
    1525          754 :       if (token->type == CPP_EOF)
    1526              :         {
    1527          607 :           parser->tokens = parser->in_omp_attribute_pragma->save_tokens;
    1528          607 :           parser->tokens_avail
    1529          607 :             = parser->in_omp_attribute_pragma->save_tokens_avail;
    1530          607 :           parser->in_omp_attribute_pragma = NULL;
    1531              :         }
    1532              :     }
    1533              : 
    1534      1929714 :   parser->error = false;
    1535      1929714 : }
    1536              : 
    1537              : /* Skip tokens up to and including "#pragma omp end declare variant".
    1538              :    Properly handle nested "#pragma omp begin declare variant" pragmas.  */
    1539              : static void
    1540            6 : c_parser_skip_to_pragma_omp_end_declare_variant (c_parser *parser)
    1541              : {
    1542          166 :   for (int depth = 0; depth >= 0; )
    1543              :     {
    1544          160 :       c_token *token = c_parser_peek_token (parser);
    1545              : 
    1546          160 :       switch (token->type)
    1547              :         {
    1548            0 :         case CPP_PRAGMA_EOL:
    1549            0 :           if (!parser->in_pragma)
    1550              :             break;
    1551              :           /* FALLTHRU */
    1552              :         case CPP_EOF:
    1553              :           /* If we've run out of tokens, stop.  */
    1554              :           return;
    1555              : 
    1556           10 :         case CPP_PRAGMA:
    1557           10 :           if ((token->pragma_kind == PRAGMA_OMP_BEGIN
    1558            8 :                || token->pragma_kind == PRAGMA_OMP_END)
    1559           10 :               && c_parser_peek_nth_token (parser, 2)->type == CPP_NAME
    1560           20 :               && c_parser_peek_nth_token (parser, 3)->type == CPP_NAME)
    1561              :             {
    1562           10 :               tree id1 = c_parser_peek_nth_token (parser, 2)->value;
    1563           10 :               tree id2 = c_parser_peek_nth_token (parser, 3)->value;
    1564           10 :               if (strcmp (IDENTIFIER_POINTER (id1), "declare") == 0
    1565           20 :                   && strcmp (IDENTIFIER_POINTER (id2), "variant") == 0)
    1566              :                 {
    1567           10 :                   if (token->pragma_kind == PRAGMA_OMP_BEGIN)
    1568            2 :                     depth++;
    1569              :                   else
    1570            8 :                     depth--;
    1571              :                 }
    1572              :             }
    1573           10 :           c_parser_consume_pragma (parser);
    1574           10 :           c_parser_skip_to_pragma_eol (parser, false);
    1575           10 :           continue;
    1576              : 
    1577              :         default:
    1578              :           break;
    1579           10 :         }
    1580              : 
    1581              :       /* Consume the token.  */
    1582          150 :       c_parser_consume_token (parser);
    1583              :     }
    1584              : }
    1585              : 
    1586              : /* Skip tokens until we have consumed an entire block, or until we
    1587              :    have consumed a non-nested ';'.  */
    1588              : 
    1589              : static void
    1590          488 : c_parser_skip_to_end_of_block_or_statement (c_parser *parser,
    1591              :                                             bool metadirective_p = false)
    1592              : {
    1593          488 :   unsigned nesting_depth = 0;
    1594          488 :   int bracket_depth = 0;
    1595          488 :   bool save_error = parser->error;
    1596              : 
    1597         1791 :   while (true)
    1598              :     {
    1599         1791 :       c_token *token;
    1600              : 
    1601              :       /* Peek at the next token.  */
    1602         1791 :       token = c_parser_peek_token (parser);
    1603              : 
    1604         1791 :       switch (token->type)
    1605              :         {
    1606              :         case CPP_EOF:
    1607              :           return;
    1608              : 
    1609            0 :         case CPP_PRAGMA_EOL:
    1610            0 :           if (parser->in_pragma)
    1611              :             return;
    1612              :           break;
    1613              : 
    1614          425 :         case CPP_SEMICOLON:
    1615              :           /* If the next token is a ';', we have reached the
    1616              :              end of the statement.  */
    1617          425 :           if (!nesting_depth && (!metadirective_p || bracket_depth <= 0))
    1618              :             {
    1619              :               /* Consume the ';'.  */
    1620          360 :               c_parser_consume_token (parser);
    1621          360 :               goto finished;
    1622              :             }
    1623              :           break;
    1624              : 
    1625          110 :         case CPP_CLOSE_BRACE:
    1626              :           /* If the next token is a non-nested '}', then we have
    1627              :              reached the end of the current block.  */
    1628           61 :           if ((nesting_depth == 0 || --nesting_depth == 0)
    1629          171 :               && (!metadirective_p || bracket_depth <= 0))
    1630              :             {
    1631          110 :               c_parser_consume_token (parser);
    1632          110 :               goto finished;
    1633              :             }
    1634              :           break;
    1635              : 
    1636           61 :         case CPP_OPEN_BRACE:
    1637              :           /* If it the next token is a '{', then we are entering a new
    1638              :              block.  Consume the entire block.  */
    1639           61 :           ++nesting_depth;
    1640           61 :           break;
    1641              : 
    1642           64 :         case CPP_OPEN_PAREN:
    1643              :           /* Track parentheses in case the statement is a standalone 'for'
    1644              :              statement - we want to skip over the semicolons separating the
    1645              :              operands.  */
    1646           64 :           if (metadirective_p && nesting_depth == 0)
    1647            2 :             ++bracket_depth;
    1648              :           break;
    1649              : 
    1650           90 :         case CPP_CLOSE_PAREN:
    1651           90 :           if (metadirective_p && nesting_depth == 0)
    1652            2 :             --bracket_depth;
    1653              :           break;
    1654              : 
    1655            7 :         case CPP_PRAGMA:
    1656              :           /* If we see a pragma, consume the whole thing at once.  We
    1657              :              have some safeguards against consuming pragmas willy-nilly.
    1658              :              Normally, we'd expect to be here with parser->error set,
    1659              :              which disables these safeguards.  But it's possible to get
    1660              :              here for secondary error recovery, after parser->error has
    1661              :              been cleared.  */
    1662            7 :           c_parser_consume_pragma (parser);
    1663            7 :           c_parser_skip_to_pragma_eol (parser, false);
    1664            7 :           parser->error = save_error;
    1665            7 :           continue;
    1666              : 
    1667              :         default:
    1668              :           break;
    1669              :         }
    1670              : 
    1671         1296 :       c_parser_consume_token (parser);
    1672              :     }
    1673              : 
    1674          470 :  finished:
    1675          470 :   parser->error = false;
    1676              : }
    1677              : 
    1678              : /* CPP's options (initialized by c-opts.cc).  */
    1679              : extern cpp_options *cpp_opts;
    1680              : 
    1681              : /* Save the warning flags which are controlled by __extension__.  */
    1682              : 
    1683              : static inline int
    1684       975963 : disable_extension_diagnostics (void)
    1685              : {
    1686      1951926 :   int ret = (pedantic
    1687       975963 :              | (warn_pointer_arith << 1)
    1688       975963 :              | (warn_traditional << 2)
    1689       975963 :              | (flag_iso << 3)
    1690       975963 :              | (warn_long_long << 4)
    1691       975963 :              | (warn_cxx_compat << 5)
    1692       975963 :              | (warn_overlength_strings << 6)
    1693              :              /* warn_c90_c99_compat has three states: -1/0/1, so we must
    1694              :                 play tricks to properly restore it.  */
    1695       975963 :              | ((warn_c90_c99_compat == 1) << 7)
    1696       975963 :              | ((warn_c90_c99_compat == -1) << 8)
    1697              :              /* Similarly for warn_c99_c11_compat.  */
    1698       975963 :              | ((warn_c99_c11_compat == 1) << 9)
    1699       975963 :              | ((warn_c99_c11_compat == -1) << 10)
    1700              :              /* Similarly for warn_c11_c23_compat.  */
    1701       975963 :              | ((warn_c11_c23_compat == 1) << 11)
    1702       975963 :              | ((warn_c11_c23_compat == -1) << 12)
    1703              :              /* Similarly for warn_c23_c2y_compat.  */
    1704       975963 :              | ((warn_c23_c2y_compat == 1) << 13)
    1705       975963 :              | ((warn_c23_c2y_compat == -1) << 14)
    1706              :              );
    1707       975963 :   cpp_opts->cpp_pedantic = pedantic = 0;
    1708       975963 :   warn_pointer_arith = 0;
    1709       975963 :   cpp_opts->cpp_warn_traditional = warn_traditional = 0;
    1710       975963 :   flag_iso = 0;
    1711       975963 :   cpp_opts->cpp_warn_long_long = warn_long_long = 0;
    1712       975963 :   warn_cxx_compat = 0;
    1713       975963 :   warn_overlength_strings = 0;
    1714       975963 :   warn_c90_c99_compat = 0;
    1715       975963 :   warn_c99_c11_compat = 0;
    1716       975963 :   warn_c11_c23_compat = 0;
    1717       975963 :   warn_c23_c2y_compat = 0;
    1718       975963 :   return ret;
    1719              : }
    1720              : 
    1721              : /* Restore the warning flags which are controlled by __extension__.
    1722              :    FLAGS is the return value from disable_extension_diagnostics.  */
    1723              : 
    1724              : static inline void
    1725       975963 : restore_extension_diagnostics (int flags)
    1726              : {
    1727       975963 :   cpp_opts->cpp_pedantic = pedantic = flags & 1;
    1728       975963 :   warn_pointer_arith = (flags >> 1) & 1;
    1729       975963 :   cpp_opts->cpp_warn_traditional = warn_traditional = (flags >> 2) & 1;
    1730       975963 :   flag_iso = (flags >> 3) & 1;
    1731       975963 :   cpp_opts->cpp_warn_long_long = warn_long_long = (flags >> 4) & 1;
    1732       975963 :   warn_cxx_compat = (flags >> 5) & 1;
    1733       975963 :   warn_overlength_strings = (flags >> 6) & 1;
    1734              :   /* See above for why is this needed.  */
    1735       975963 :   warn_c90_c99_compat = (flags >> 7) & 1 ? 1 : ((flags >> 8) & 1 ? -1 : 0);
    1736       975963 :   warn_c99_c11_compat = (flags >> 9) & 1 ? 1 : ((flags >> 10) & 1 ? -1 : 0);
    1737       975963 :   warn_c11_c23_compat = (flags >> 11) & 1 ? 1 : ((flags >> 12) & 1 ? -1 : 0);
    1738       975963 :   warn_c23_c2y_compat = (flags >> 13) & 1 ? 1 : ((flags >> 14) & 1 ? -1 : 0);
    1739       975963 : }
    1740              : 
    1741              : /* Helper data structure for parsing #pragma acc routine.  */
    1742              : struct oacc_routine_data {
    1743              :   bool error_seen; /* Set if error has been reported.  */
    1744              :   bool fndecl_seen; /* Set if one fn decl/definition has been seen already.  */
    1745              :   tree clauses;
    1746              :   location_t loc;
    1747              : };
    1748              : 
    1749              : /* Used for parsing objc foreach statements.  */
    1750              : static tree objc_foreach_break_label, objc_foreach_continue_label;
    1751              : 
    1752              : /* Used for parsing OMP for loops.
    1753              : 
    1754              :    Some notes on flags used for context:
    1755              :    parser->omp_for_parse_state is non-null anywhere inside the OMP FOR
    1756              :    construct, except for the final-loop-body.
    1757              :    The want_nested_loop flag is true if inside a {} sequence where
    1758              :    a loop-nest (or another {} sequence containing a loop-nest) is expected,
    1759              :    but has not yet been seen.  It's false when parsing intervening code
    1760              :    statements or their substatements that cannot contain a loop-nest.
    1761              :    The in_intervening_code flag is true when parsing any intervening code,
    1762              :    including substatements, and whether or not want_nested_loop is true.
    1763              : 
    1764              :    And, about error handling:
    1765              :    The saw_intervening_code flag is set if the loop is not perfectly
    1766              :    nested, even in the usual case where this is not an error.
    1767              :    perfect_nesting_fail is set if an error has been diagnosed because an
    1768              :    imperfectly-nested loop was found where a perfectly-nested one is
    1769              :    required (we diagnose this only once).
    1770              :    fail is set if any kind of structural error in the loop nest
    1771              :    has been found and diagnosed.
    1772              :   */
    1773              : struct omp_for_parse_data {
    1774              :   enum tree_code code;
    1775              :   tree declv, condv, incrv, initv;
    1776              :   tree pre_body;
    1777              :   tree bindings;
    1778              :   int count;    /* Expected nesting depth.  */
    1779              :   int depth;    /* Current nesting depth.  */
    1780              :   location_t for_loc;
    1781              :   bool ordered : 1;
    1782              :   bool inscan : 1;
    1783              :   bool want_nested_loop : 1;
    1784              :   bool in_intervening_code : 1;
    1785              :   bool saw_intervening_code: 1;
    1786              :   bool perfect_nesting_fail : 1;
    1787              :   bool fail : 1;
    1788              : };
    1789              : 
    1790              : struct attr_state
    1791              : {
    1792              :   /* True if we parsed a musttail attribute for return.  */
    1793              :   bool musttail_p;
    1794              : };
    1795              : 
    1796              : static bool c_parser_nth_token_starts_std_attributes (c_parser *,
    1797              :                                                       unsigned int);
    1798              : static tree c_parser_std_attribute_specifier_sequence (c_parser *);
    1799              : static void c_parser_external_declaration (c_parser *);
    1800              : static void c_parser_asm_definition (c_parser *);
    1801              : static tree c_parser_declaration_or_fndef (c_parser *, bool, bool, bool,
    1802              :                                            bool, bool, bool, tree * = NULL,
    1803              :                                            vec<c_token> * = NULL,
    1804              :                                            bool have_attrs = false,
    1805              :                                            tree attrs = NULL,
    1806              :                                            struct oacc_routine_data * = NULL,
    1807              :                                            bool * = NULL);
    1808              : static bool c_parser_handle_statement_omp_attributes (c_parser *, tree &,
    1809              :                                                       bool *);
    1810              : static void c_parser_static_assert_declaration_no_semi (c_parser *);
    1811              : static void c_parser_static_assert_declaration (c_parser *);
    1812              : static struct c_typespec c_parser_enum_specifier (c_parser *);
    1813              : static struct c_typespec c_parser_struct_or_union_specifier (c_parser *);
    1814              : static tree c_parser_struct_declaration (c_parser *, tree *);
    1815              : static struct c_typespec c_parser_typeof_specifier (c_parser *);
    1816              : static tree c_parser_alignas_specifier (c_parser *);
    1817              : static struct c_declarator *c_parser_direct_declarator (c_parser *, bool,
    1818              :                                                         c_dtr_syn, bool *);
    1819              : static struct c_declarator *c_parser_direct_declarator_inner (c_parser *,
    1820              :                                                               bool,
    1821              :                                                               struct c_declarator *);
    1822              : static struct c_arg_info *c_parser_parms_declarator (c_parser *, bool, tree,
    1823              :                                                      bool);
    1824              : static struct c_arg_info *c_parser_parms_list_declarator (c_parser *, tree,
    1825              :                                                           tree, bool);
    1826              : static struct c_parm *c_parser_parameter_declaration (c_parser *, tree, bool);
    1827              : static tree c_parser_asm_string_literal (c_parser *);
    1828              : static tree c_parser_simple_asm_expr (c_parser *);
    1829              : static tree c_parser_gnu_attributes (c_parser *);
    1830              : static struct c_expr c_parser_initializer (c_parser *, tree);
    1831              : static struct c_expr c_parser_braced_init (c_parser *, tree, bool,
    1832              :                                            struct obstack *, bool);
    1833              : static void c_parser_initelt (c_parser *, struct obstack *);
    1834              : static void c_parser_initval (c_parser *, struct c_expr *,
    1835              :                               struct obstack *);
    1836              : static tree c_parser_compound_statement (c_parser *, location_t * = NULL);
    1837              : static location_t c_parser_compound_statement_nostart (c_parser *);
    1838              : static void c_parser_label (c_parser *, tree);
    1839              : static void c_parser_statement (c_parser *, bool *, location_t * = NULL);
    1840              : static void c_parser_statement_after_labels (c_parser *, bool *, tree,
    1841              :                                              vec<tree> * = NULL,
    1842              :                                              attr_state = {});
    1843              : static tree c_parser_c99_block_statement (c_parser *, bool *,
    1844              :                                           location_t * = NULL);
    1845              : static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
    1846              : static void c_parser_switch_statement (c_parser *, bool *, tree);
    1847              : static void c_parser_while_statement (c_parser *, bool, unsigned short, bool,
    1848              :                                       bool *, tree);
    1849              : static void c_parser_do_statement (c_parser *, bool, unsigned short, bool,
    1850              :                                    tree);
    1851              : static void c_parser_for_statement (c_parser *, bool, unsigned short, bool,
    1852              :                                     bool *, tree);
    1853              : static tree c_parser_asm_statement (c_parser *);
    1854              : static tree c_parser_asm_operands (c_parser *);
    1855              : static tree c_parser_asm_goto_operands (c_parser *);
    1856              : static tree c_parser_asm_clobbers (c_parser *);
    1857              : static struct c_expr c_parser_expr_no_commas (c_parser *, struct c_expr *,
    1858              :                                               tree = NULL_TREE);
    1859              : static struct c_expr c_parser_conditional_expression (c_parser *,
    1860              :                                                       struct c_expr *, tree);
    1861              : static struct c_expr c_parser_binary_expression (c_parser *, struct c_expr *,
    1862              :                                                  tree);
    1863              : static struct c_expr c_parser_cast_expression (c_parser *, struct c_expr *);
    1864              : static struct c_expr c_parser_unary_expression (c_parser *);
    1865              : static struct c_expr c_parser_sizeof_or_countof_expression (c_parser *,
    1866              :                                                             enum rid);
    1867              : static struct c_expr c_parser_alignof_expression (c_parser *);
    1868              : static struct c_expr c_parser_maxof_or_minof_expression (c_parser *, enum rid);
    1869              : static struct c_expr c_parser_postfix_expression (c_parser *);
    1870              : static struct c_expr c_parser_postfix_expression_after_paren_type (c_parser *,
    1871              :                                                                    struct c_declspecs *,
    1872              :                                                                    struct c_type_name *,
    1873              :                                                                    location_t);
    1874              : static struct c_expr c_parser_postfix_expression_after_primary (c_parser *,
    1875              :                                                                 location_t loc,
    1876              :                                                                 struct c_expr);
    1877              : static tree c_parser_transaction (c_parser *, enum rid);
    1878              : static struct c_expr c_parser_transaction_expression (c_parser *, enum rid);
    1879              : static tree c_parser_transaction_cancel (c_parser *);
    1880              : static struct c_expr c_parser_expression (c_parser *);
    1881              : static struct c_expr c_parser_expression_conv (c_parser *);
    1882              : static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool,
    1883              :                                              vec<tree, va_gc> **, location_t *,
    1884              :                                              tree *, vec<location_t> *,
    1885              :                                              unsigned int * = NULL);
    1886              : static struct c_expr c_parser_has_attribute_expression (c_parser *);
    1887              : 
    1888              : static void c_parser_oacc_declare (c_parser *);
    1889              : static void c_parser_oacc_enter_exit_data (c_parser *, bool);
    1890              : static void c_parser_oacc_update (c_parser *);
    1891              : static void c_parser_omp_construct (c_parser *, bool *);
    1892              : static void c_parser_omp_groupprivate (c_parser *);
    1893              : static void c_parser_omp_threadprivate (c_parser *);
    1894              : static void c_parser_omp_barrier (c_parser *);
    1895              : static void c_parser_omp_depobj (c_parser *);
    1896              : static void c_parser_omp_flush (c_parser *);
    1897              : static bool c_parser_omp_next_tokens_can_be_canon_loop (c_parser *,
    1898              :                                                         enum tree_code, bool);
    1899              : static tree c_parser_omp_loop_nest (c_parser *, bool *);
    1900              : static tree c_parser_omp_for_loop (location_t, c_parser *, enum tree_code,
    1901              :                                    tree, tree *, bool *);
    1902              : static void c_parser_omp_taskwait (c_parser *);
    1903              : static void c_parser_omp_taskyield (c_parser *);
    1904              : static void c_parser_omp_cancel (c_parser *);
    1905              : static void c_parser_omp_nothing (c_parser *);
    1906              : static void c_parser_omp_metadirective (c_parser *, bool *);
    1907              : 
    1908              : enum pragma_context { pragma_external, pragma_struct, pragma_param,
    1909              :                       pragma_stmt, pragma_compound };
    1910              : static bool c_parser_pragma (c_parser *, enum pragma_context, bool *, tree);
    1911              : static bool c_parser_omp_cancellation_point (c_parser *, enum pragma_context);
    1912              : static bool c_parser_omp_target (c_parser *, enum pragma_context, bool *);
    1913              : static void c_parser_omp_begin (c_parser *);
    1914              : static void c_parser_omp_end (c_parser *);
    1915              : static bool c_parser_omp_declare (c_parser *, enum pragma_context);
    1916              : static void c_parser_omp_requires (c_parser *);
    1917              : static bool c_parser_omp_error (c_parser *, enum pragma_context);
    1918              : static void c_parser_omp_assumption_clauses (c_parser *, bool);
    1919              : static void c_parser_omp_allocate (c_parser *);
    1920              : static void c_parser_omp_assumes (c_parser *);
    1921              : static bool c_parser_omp_ordered (c_parser *, enum pragma_context, bool *);
    1922              : static tree c_parser_omp_dispatch (location_t, c_parser *);
    1923              : static void c_parser_omp_interop (c_parser *);
    1924              : static void c_parser_oacc_routine (c_parser *, enum pragma_context);
    1925              : 
    1926              : /* These Objective-C parser functions are only ever called when
    1927              :    compiling Objective-C.  */
    1928              : static void c_parser_objc_class_definition (c_parser *, tree);
    1929              : static void c_parser_objc_class_instance_variables (c_parser *);
    1930              : static void c_parser_objc_class_declaration (c_parser *);
    1931              : static void c_parser_objc_alias_declaration (c_parser *);
    1932              : static void c_parser_objc_protocol_definition (c_parser *, tree);
    1933              : static bool c_parser_objc_method_type (c_parser *);
    1934              : static void c_parser_objc_method_definition (c_parser *);
    1935              : static void c_parser_objc_methodprotolist (c_parser *);
    1936              : static void c_parser_objc_methodproto (c_parser *);
    1937              : static tree c_parser_objc_method_decl (c_parser *, bool, tree *, tree *);
    1938              : static tree c_parser_objc_type_name (c_parser *);
    1939              : static tree c_parser_objc_protocol_refs (c_parser *);
    1940              : static void c_parser_objc_try_catch_finally_statement (c_parser *);
    1941              : static void c_parser_objc_synchronized_statement (c_parser *);
    1942              : static tree c_parser_objc_selector (c_parser *);
    1943              : static tree c_parser_objc_selector_arg (c_parser *);
    1944              : static tree c_parser_objc_receiver (c_parser *);
    1945              : static tree c_parser_objc_message_args (c_parser *);
    1946              : static tree c_parser_objc_keywordexpr (c_parser *);
    1947              : static void c_parser_objc_at_property_declaration (c_parser *);
    1948              : static void c_parser_objc_at_synthesize_declaration (c_parser *);
    1949              : static void c_parser_objc_at_dynamic_declaration (c_parser *);
    1950              : static bool c_parser_objc_diagnose_bad_element_prefix
    1951              :   (c_parser *, struct c_declspecs *);
    1952              : static location_t c_parser_parse_rtl_body (c_parser *, char *);
    1953              : static tree c_parser_handle_musttail (c_parser *, tree, attr_state &);
    1954              : 
    1955              : #if ENABLE_ANALYZER
    1956              : 
    1957              : namespace ana {
    1958              : 
    1959              : /* Concrete implementation of ana::translation_unit for the C frontend.  */
    1960              : 
    1961              : class c_translation_unit : public translation_unit
    1962              : {
    1963              : public:
    1964              :   /* Implementation of translation_unit::lookup_constant_by_id for use by the
    1965              :      analyzer to look up named constants in the user's source code.  */
    1966         7155 :   tree lookup_constant_by_id (tree id) const final override
    1967              :   {
    1968              :     /* Consider decls.  */
    1969         7155 :     if (tree decl = lookup_name (id))
    1970           42 :       if (TREE_CODE (decl) == CONST_DECL)
    1971           42 :         if (tree value = DECL_INITIAL (decl))
    1972           42 :           if (TREE_CODE (value) == INTEGER_CST)
    1973              :             return value;
    1974              : 
    1975              :     /* Consider macros.  */
    1976         7113 :     cpp_hashnode *hashnode = C_CPP_HASHNODE (id);
    1977         7113 :     if (cpp_macro_p (hashnode))
    1978           48 :       if (tree value = consider_macro (hashnode->value.macro))
    1979              :         return value;
    1980              : 
    1981              :     return NULL_TREE;
    1982              :   }
    1983              : 
    1984              :   tree
    1985            4 :   lookup_type_by_id (tree id) const final override
    1986              :   {
    1987            4 :     if (tree type_decl = lookup_name (id))
    1988            0 :         if (TREE_CODE (type_decl) == TYPE_DECL)
    1989              :           {
    1990            0 :             tree record_type = TREE_TYPE (type_decl);
    1991            0 :             if (TREE_CODE (record_type) == RECORD_TYPE)
    1992            0 :               return record_type;
    1993              :           }
    1994              : 
    1995              :     return NULL_TREE;
    1996              :   }
    1997              : 
    1998              :   tree
    1999            2 :   lookup_global_var_by_id (tree id) const final override
    2000              :   {
    2001            2 :     if (tree var_decl = lookup_name (id))
    2002            0 :       if (TREE_CODE (var_decl) == VAR_DECL)
    2003            0 :                                 return var_decl;
    2004              : 
    2005              :     return NULL_TREE;
    2006              :   }
    2007              : 
    2008              : private:
    2009              :   /* Attempt to get an INTEGER_CST from MACRO.
    2010              :      Only handle the simplest cases: where MACRO's definition is a single
    2011              :      token containing a number, by lexing the number again.
    2012              :      This will handle e.g.
    2013              :        #define NAME 42
    2014              :      and other bases but not negative numbers, parentheses or e.g.
    2015              :        #define NAME 1 << 7
    2016              :      as doing so would require a parser.  */
    2017           48 :   tree consider_macro (cpp_macro *macro) const
    2018              :   {
    2019           48 :     if (macro->paramc > 0)
    2020              :       return NULL_TREE;
    2021           45 :     if (macro->kind != cmk_macro)
    2022              :       return NULL_TREE;
    2023           45 :     if (macro->count != 1)
    2024              :       return NULL_TREE;
    2025           39 :     const cpp_token &tok = macro->exp.tokens[0];
    2026           39 :     if (tok.type != CPP_NUMBER)
    2027              :       return NULL_TREE;
    2028              : 
    2029           36 :     cpp_reader *old_parse_in = parse_in;
    2030           36 :     parse_in = cpp_create_reader (CLK_GNUC89, NULL, line_table);
    2031              : 
    2032           36 :     pretty_printer pp;
    2033           36 :     pp_string (&pp, (const char *) tok.val.str.text);
    2034           36 :     pp_newline (&pp);
    2035           72 :     cpp_push_buffer (parse_in,
    2036           36 :                      (const unsigned char *) pp_formatted_text (&pp),
    2037              :                      strlen (pp_formatted_text (&pp)),
    2038              :                      0);
    2039              : 
    2040           36 :     tree value;
    2041           36 :     location_t loc;
    2042           36 :     unsigned char cpp_flags;
    2043           36 :     c_lex_with_flags (&value, &loc, &cpp_flags, 0);
    2044              : 
    2045           36 :     cpp_destroy (parse_in);
    2046           36 :     parse_in = old_parse_in;
    2047              : 
    2048           36 :     if (value && TREE_CODE (value) == INTEGER_CST)
    2049           36 :       return value;
    2050              : 
    2051              :     return NULL_TREE;
    2052           36 :   }
    2053              : };
    2054              : 
    2055              : } // namespace ana
    2056              : 
    2057              : #endif /* #if ENABLE_ANALYZER */
    2058              : 
    2059              : /* Parse a translation unit (C90 6.7, C99 6.9, C11 6.9).
    2060              : 
    2061              :    translation-unit:
    2062              :      external-declarations
    2063              : 
    2064              :    external-declarations:
    2065              :      external-declaration
    2066              :      external-declarations external-declaration
    2067              : 
    2068              :    GNU extensions:
    2069              : 
    2070              :    translation-unit:
    2071              :      empty
    2072              : */
    2073              : 
    2074              : static void
    2075       105296 : c_parser_translation_unit (c_parser *parser)
    2076              : {
    2077       105296 :   if (c_parser_next_token_is (parser, CPP_EOF))
    2078              :     {
    2079         1229 :       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
    2080              :                "ISO C forbids an empty translation unit");
    2081              :     }
    2082              :   else
    2083              :     {
    2084       104067 :       void *obstack_position = obstack_alloc (&parser_obstack, 0);
    2085       104067 :       mark_valid_location_for_stdc_pragma (false);
    2086     58163954 :       do
    2087              :         {
    2088     58163954 :           ggc_collect ();
    2089     58163954 :           c_parser_external_declaration (parser);
    2090     58163949 :           obstack_free (&parser_obstack, obstack_position);
    2091              :         }
    2092     58163949 :       while (c_parser_next_token_is_not (parser, CPP_EOF));
    2093              :     }
    2094              : 
    2095              :   unsigned int i;
    2096              :   tree decl;
    2097       105341 :   FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl)
    2098          135 :     if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node)
    2099           37 :       error ("storage size of %q+D isn%'t known", decl);
    2100              : 
    2101       105206 :   if (vec_safe_length (current_omp_declare_target_attribute))
    2102              :     {
    2103            4 :       c_omp_declare_target_attr
    2104            4 :         a = current_omp_declare_target_attribute->pop ();
    2105            4 :       if (!errorcount)
    2106            3 :         error ("%qs without corresponding %qs",
    2107              :                a.device_type >= 0 ? "#pragma omp begin declare target"
    2108              :                                   : "#pragma omp declare target",
    2109              :                "#pragma omp end declare target");
    2110            8 :       vec_safe_truncate (current_omp_declare_target_attribute, 0);
    2111              :     }
    2112       105206 :   if (vec_safe_length (current_omp_begin_assumes))
    2113              :     {
    2114            1 :       if (!errorcount)
    2115            1 :         error ("%qs without corresponding %qs",
    2116              :                "#pragma omp begin assumes", "#pragma omp end assumes");
    2117            1 :       vec_safe_truncate (current_omp_begin_assumes, 0);
    2118              :     }
    2119       105206 :   if (vec_safe_length (current_omp_declare_variant_attribute))
    2120              :     {
    2121            0 :       if (!errorcount)
    2122            0 :         error ("%<omp begin declare variant%> without corresponding "
    2123              :                "%<omp end declare variant%>");
    2124            0 :       vec_safe_truncate (current_omp_declare_variant_attribute, 0);
    2125              :     }
    2126       105206 :   if (vec_safe_length (omp_begin_declare_variant_map))
    2127              :     {
    2128              :       unsigned int i;
    2129              :       omp_begin_declare_variant_map_entry *e;
    2130           32 :       FOR_EACH_VEC_ELT (*omp_begin_declare_variant_map, i, e)
    2131           24 :         omp_finish_variant_function (e->variant, e->id, e->ctx);
    2132            8 :       vec_safe_truncate (omp_begin_declare_variant_map, 0);
    2133              :     }
    2134              : 
    2135              : #if ENABLE_ANALYZER
    2136       105206 :   if (flag_analyzer)
    2137              :     {
    2138         1431 :       ana::c_translation_unit tu;
    2139         1431 :       ana::on_finish_translation_unit (tu);
    2140              :     }
    2141              : #endif
    2142       105206 : }
    2143              : 
    2144              : /* Parse an external declaration (C90 6.7, C99 6.9, C11 6.9).
    2145              : 
    2146              :    external-declaration:
    2147              :      function-definition
    2148              :      declaration
    2149              : 
    2150              :    GNU extensions:
    2151              : 
    2152              :    external-declaration:
    2153              :      asm-definition
    2154              :      ;
    2155              :      __extension__ external-declaration
    2156              : 
    2157              :    Objective-C:
    2158              : 
    2159              :    external-declaration:
    2160              :      objc-class-definition
    2161              :      objc-class-declaration
    2162              :      objc-alias-declaration
    2163              :      objc-protocol-definition
    2164              :      objc-method-definition
    2165              :      @end
    2166              : */
    2167              : 
    2168              : static void
    2169     58613461 : c_parser_external_declaration (c_parser *parser)
    2170              : {
    2171     58613461 :   int ext;
    2172     58613461 :   switch (c_parser_peek_token (parser)->type)
    2173              :     {
    2174     56799346 :     case CPP_KEYWORD:
    2175     56799346 :       switch (c_parser_peek_token (parser)->keyword)
    2176              :         {
    2177       449507 :         case RID_EXTENSION:
    2178       449507 :           ext = disable_extension_diagnostics ();
    2179       449507 :           c_parser_consume_token (parser);
    2180       449507 :           c_parser_external_declaration (parser);
    2181       449507 :           restore_extension_diagnostics (ext);
    2182       449507 :           break;
    2183          214 :         case RID_ASM:
    2184          214 :           c_parser_asm_definition (parser);
    2185          214 :           break;
    2186            0 :         case RID_AT_INTERFACE:
    2187            0 :         case RID_AT_IMPLEMENTATION:
    2188            0 :           gcc_assert (c_dialect_objc ());
    2189            0 :           c_parser_objc_class_definition (parser, NULL_TREE);
    2190            0 :           break;
    2191            0 :         case RID_AT_CLASS:
    2192            0 :           gcc_assert (c_dialect_objc ());
    2193            0 :           c_parser_objc_class_declaration (parser);
    2194            0 :           break;
    2195            0 :         case RID_AT_ALIAS:
    2196            0 :           gcc_assert (c_dialect_objc ());
    2197            0 :           c_parser_objc_alias_declaration (parser);
    2198            0 :           break;
    2199            0 :         case RID_AT_PROTOCOL:
    2200            0 :           gcc_assert (c_dialect_objc ());
    2201            0 :           c_parser_objc_protocol_definition (parser, NULL_TREE);
    2202            0 :           break;
    2203            0 :         case RID_AT_PROPERTY:
    2204            0 :           gcc_assert (c_dialect_objc ());
    2205            0 :           c_parser_objc_at_property_declaration (parser);
    2206            0 :           break;
    2207            0 :         case RID_AT_SYNTHESIZE:
    2208            0 :           gcc_assert (c_dialect_objc ());
    2209            0 :           c_parser_objc_at_synthesize_declaration (parser);
    2210            0 :           break;
    2211            0 :         case RID_AT_DYNAMIC:
    2212            0 :           gcc_assert (c_dialect_objc ());
    2213            0 :           c_parser_objc_at_dynamic_declaration (parser);
    2214            0 :           break;
    2215            0 :         case RID_AT_END:
    2216            0 :           gcc_assert (c_dialect_objc ());
    2217            0 :           c_parser_consume_token (parser);
    2218            0 :           objc_finish_implementation ();
    2219            0 :           break;
    2220     56349625 :         default:
    2221     56349625 :           goto decl_or_fndef;
    2222              :         }
    2223              :       break;
    2224         2136 :     case CPP_SEMICOLON:
    2225         2136 :       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
    2226              :                "ISO C does not allow extra %<;%> outside of a function");
    2227         2136 :       c_parser_consume_token (parser);
    2228         2136 :       break;
    2229      1588943 :     case CPP_PRAGMA:
    2230      1588943 :       mark_valid_location_for_stdc_pragma (true);
    2231      1588943 :       c_parser_pragma (parser, pragma_external, NULL, NULL_TREE);
    2232      1588943 :       mark_valid_location_for_stdc_pragma (false);
    2233      1588943 :       break;
    2234            1 :     case CPP_PLUS:
    2235            1 :     case CPP_MINUS:
    2236            1 :       if (c_dialect_objc ())
    2237              :         {
    2238            0 :           c_parser_objc_method_definition (parser);
    2239            0 :           break;
    2240              :         }
    2241              :       /* Else fall through, and yield a syntax error trying to parse
    2242              :          as a declaration or function definition.  */
    2243              :       /* FALLTHRU */
    2244     56572661 :     default:
    2245            1 :     decl_or_fndef:
    2246              :       /* A declaration or a function definition (or, in Objective-C,
    2247              :          an @interface or @protocol with prefix attributes).  We can
    2248              :          only tell which after parsing the declaration specifiers, if
    2249              :          any, and the first declarator.  */
    2250     56572661 :       c_parser_declaration_or_fndef (parser, true, true, true, false, true,
    2251              :                                      false);
    2252     56572661 :       break;
    2253              :     }
    2254     58613456 : }
    2255              : 
    2256              : static void c_parser_handle_directive_omp_attributes (tree &, vec<c_token> *&,
    2257              :                                                       vec<c_token> *);
    2258              : static void c_finish_omp_declare_simd (c_parser *, tree, tree, vec<c_token> *);
    2259              : static void c_finish_oacc_routine (struct oacc_routine_data *, tree, bool);
    2260              : 
    2261              : /* Build and add a DEBUG_BEGIN_STMT statement with location LOC.  */
    2262              : 
    2263              : static void
    2264    106925724 : add_debug_begin_stmt (location_t loc)
    2265              : {
    2266              :   /* Don't add DEBUG_BEGIN_STMTs outside of functions, see PR84721.  */
    2267    106925724 :   if (!MAY_HAVE_DEBUG_MARKER_STMTS || !building_stmt_list_p ())
    2268    104179523 :     return;
    2269              : 
    2270      2746201 :   tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
    2271      2746201 :   SET_EXPR_LOCATION (stmt, loc);
    2272      2746201 :   add_stmt (stmt);
    2273              : }
    2274              : 
    2275              : /* Helper function for c_parser_declaration_or_fndef and
    2276              :    Handle assume attribute(s).  */
    2277              : 
    2278              : static tree
    2279           38 : handle_assume_attribute (location_t here, tree attrs, bool nested)
    2280              : {
    2281           38 :   if (nested)
    2282           78 :     for (tree attr = lookup_attribute ("gnu", "assume", attrs); attr;
    2283           41 :          attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
    2284              :       {
    2285           41 :         tree args = TREE_VALUE (attr);
    2286           41 :         int nargs = list_length (args);
    2287           41 :         if (nargs != 1)
    2288              :           {
    2289            6 :             error_at (here, "wrong number of arguments specified "
    2290              :                             "for %qE attribute",
    2291              :                       get_attribute_name (attr));
    2292            6 :             inform (here, "expected %i, found %i", 1, nargs);
    2293              :           }
    2294              :         else
    2295              :           {
    2296           35 :             tree arg = TREE_VALUE (args);
    2297           35 :             arg = c_objc_common_truthvalue_conversion (here, arg);
    2298           35 :             arg = c_fully_fold (arg, false, NULL);
    2299           35 :             if (arg != error_mark_node)
    2300              :               {
    2301           33 :                 tree fn = build_call_expr_internal_loc (here, IFN_ASSUME,
    2302              :                                                         void_type_node, 1,
    2303              :                                                         arg);
    2304           33 :                 add_stmt (fn);
    2305              :               }
    2306              :           }
    2307              :       }
    2308              :   else
    2309            1 :     pedwarn (here, OPT_Wattributes,
    2310              :              "%<assume%> attribute at top level");
    2311              : 
    2312           38 :   return remove_attribute ("gnu", "assume", attrs);
    2313              : }
    2314              : 
    2315              : /* We might need to reclassify any previously-lexed identifier, e.g.
    2316              :    when we've left a for loop with an if-statement without else in the
    2317              :    body - we might have used a wrong scope for the token.  See PR67784.  */
    2318              : 
    2319              : static void
    2320     37885556 : c_parser_maybe_reclassify_token (c_parser *parser)
    2321              : {
    2322     37885556 :   if (c_parser_next_token_is (parser, CPP_NAME))
    2323              :     {
    2324       203650 :       c_token *token = c_parser_peek_token (parser);
    2325              : 
    2326       203650 :       if (token->id_kind == C_ID_ID || token->id_kind == C_ID_TYPENAME)
    2327              :         {
    2328       203649 :           tree decl = lookup_name (token->value);
    2329              : 
    2330       203649 :           token->id_kind = C_ID_ID;
    2331       203649 :           if (decl)
    2332              :             {
    2333       200608 :               if (TREE_CODE (decl) == TYPE_DECL)
    2334         2233 :                 token->id_kind = C_ID_TYPENAME;
    2335              :             }
    2336         3041 :           else if (c_dialect_objc ())
    2337              :             {
    2338            0 :               tree objc_interface_decl = objc_is_class_name (token->value);
    2339              :               /* Objective-C class names are in the same namespace as
    2340              :                  variables and typedefs, and hence are shadowed by local
    2341              :                  declarations.  */
    2342            0 :               if (objc_interface_decl)
    2343              :                 {
    2344            0 :                   token->value = objc_interface_decl;
    2345            0 :                   token->id_kind = C_ID_CLASSNAME;
    2346              :                 }
    2347              :             }
    2348              :         }
    2349              :     }
    2350     37885556 : }
    2351              : 
    2352              : /* Parse a declaration or function definition (C90 6.5, 6.7.1, C99
    2353              :    6.7, 6.9.1, C11 6.7, 6.9.1).  If FNDEF_OK is true, a function definition
    2354              :    is accepted; otherwise (old-style parameter declarations) only other
    2355              :    declarations are accepted.  If STATIC_ASSERT_OK is true, a static
    2356              :    assertion is accepted; otherwise (old-style parameter declarations)
    2357              :    it is not.  If NESTED is true, we are inside a function or parsing
    2358              :    old-style parameter declarations; any functions encountered are
    2359              :    nested functions and declaration specifiers are required; otherwise
    2360              :    we are at top level and functions are normal functions and
    2361              :    declaration specifiers may be optional.  If EMPTY_OK is true, empty
    2362              :    declarations are OK (subject to all other constraints); otherwise
    2363              :    (old-style parameter declarations) they are diagnosed.  If
    2364              :    START_ATTR_OK is true, the declaration specifiers may start with
    2365              :    attributes (GNU or standard); otherwise they may not.
    2366              :    OBJC_FOREACH_OBJECT_DECLARATION can be used to get back the parsed
    2367              :    declaration when parsing an Objective-C foreach statement.
    2368              :    FALLTHRU_ATTR_P is used to signal whether this function parsed
    2369              :    "__attribute__((fallthrough));".  ATTRS are any standard attributes
    2370              :    parsed in the caller (in contexts where such attributes had to be
    2371              :    parsed to determine whether what follows is a declaration or a
    2372              :    statement); HAVE_ATTRS says whether there were any such attributes
    2373              :    (even empty).  If SIMPLE_OK, the construct can be a simple-declaration;
    2374              :    in that case, the ';' is not consumed (left to the caller so that it
    2375              :    can figure out if there was a simple-declaration or not), there must
    2376              :    be an initializer, and only one object may be declared.  When SIMPLE_OK
    2377              :    is true we are called from c_parser_selection_header.
    2378              : 
    2379              :    Returns the resulting declaration, if there was any with an initializer.
    2380              : 
    2381              :    declaration:
    2382              :      declaration-specifiers init-declarator-list[opt] ;
    2383              :      static_assert-declaration
    2384              : 
    2385              :    function-definition:
    2386              :      declaration-specifiers[opt] declarator declaration-list[opt]
    2387              :        compound-statement
    2388              : 
    2389              :    declaration-list:
    2390              :      declaration
    2391              :      declaration-list declaration
    2392              : 
    2393              :    init-declarator-list:
    2394              :      init-declarator
    2395              :      init-declarator-list , init-declarator
    2396              : 
    2397              :    init-declarator:
    2398              :      declarator simple-asm-expr[opt] gnu-attributes[opt]
    2399              :      declarator simple-asm-expr[opt] gnu-attributes[opt] = initializer
    2400              : 
    2401              :    simple-declaration:
    2402              :      attribute-specifier-sequence[opt] declaration-specifiers declarator
    2403              :        = initializer
    2404              : 
    2405              :    GNU extensions:
    2406              : 
    2407              :    nested-function-definition:
    2408              :      declaration-specifiers declarator declaration-list[opt]
    2409              :        compound-statement
    2410              : 
    2411              :    attribute ;
    2412              : 
    2413              :    Objective-C:
    2414              :      gnu-attributes objc-class-definition
    2415              :      gnu-attributes objc-category-definition
    2416              :      gnu-attributes objc-protocol-definition
    2417              : 
    2418              :    The simple-asm-expr and gnu-attributes are GNU extensions.
    2419              : 
    2420              :    This function does not handle __extension__; that is handled in its
    2421              :    callers.  ??? Following the old parser, __extension__ may start
    2422              :    external declarations, declarations in functions and declarations
    2423              :    at the start of "for" loops, but not old-style parameter
    2424              :    declarations.
    2425              : 
    2426              :    C99 requires declaration specifiers in a function definition; the
    2427              :    absence is diagnosed through the diagnosis of implicit int.  In GNU
    2428              :    C we also allow but diagnose declarations without declaration
    2429              :    specifiers, but only at top level (elsewhere they conflict with
    2430              :    other syntax).
    2431              : 
    2432              :    In Objective-C, declarations of the looping variable in a foreach
    2433              :    statement are exceptionally terminated by 'in' (for example, 'for
    2434              :    (NSObject *object in array) { ... }').
    2435              : 
    2436              :    OpenMP:
    2437              : 
    2438              :    declaration:
    2439              :      threadprivate-directive
    2440              : 
    2441              :    GIMPLE:
    2442              : 
    2443              :    gimple-function-definition:
    2444              :      declaration-specifiers[opt] __GIMPLE (gimple-or-rtl-pass-list) declarator
    2445              :        declaration-list[opt] compound-statement
    2446              : 
    2447              :    rtl-function-definition:
    2448              :      declaration-specifiers[opt] __RTL (gimple-or-rtl-pass-list) declarator
    2449              :        declaration-list[opt] compound-statement  */
    2450              : 
    2451              : static tree
    2452     64239168 : c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
    2453              :                                bool static_assert_ok, bool empty_ok,
    2454              :                                bool nested, bool start_attr_ok,
    2455              :                                bool simple_ok,
    2456              :                                tree *objc_foreach_object_declaration
    2457              :                                /* = NULL */,
    2458              :                                vec<c_token> *omp_declare_simd_clauses
    2459              :                                /* = NULL */,
    2460              :                                bool have_attrs /* = false */,
    2461              :                                tree attrs /* = NULL_TREE */,
    2462              :                                struct oacc_routine_data *oacc_routine_data
    2463              :                                /* = NULL */,
    2464              :                                bool *fallthru_attr_p /* = NULL */)
    2465              : {
    2466     64239168 :   struct c_declspecs *specs;
    2467     64239168 :   tree prefix_attrs;
    2468     64239168 :   tree all_prefix_attrs;
    2469     64239168 :   bool diagnosed_no_specs = false;
    2470     64239168 :   location_t here = c_parser_peek_token (parser)->location;
    2471     64239168 :   tree result = NULL_TREE;
    2472              : 
    2473     64239168 :   add_debug_begin_stmt (c_parser_peek_token (parser)->location);
    2474              : 
    2475     64239168 :   if (static_assert_ok
    2476    128464989 :       && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
    2477              :     {
    2478         1948 :       c_parser_static_assert_declaration (parser);
    2479         1948 :       return result;
    2480              :     }
    2481     64237220 :   specs = build_null_declspecs ();
    2482              : 
    2483              :   /* Handle any standard attributes parsed in the caller.  */
    2484     64237220 :   if (have_attrs)
    2485              :     {
    2486          143 :       declspecs_add_attrs (here, specs, attrs);
    2487          143 :       specs->non_std_attrs_seen_p = false;
    2488              :     }
    2489              : 
    2490              :   /* Try to detect an unknown type name when we have "A B" or "A *B".  */
    2491     64237220 :   if (c_parser_peek_token (parser)->type == CPP_NAME
    2492      5895650 :       && c_parser_peek_token (parser)->id_kind == C_ID_ID
    2493         9295 :       && (c_parser_peek_2nd_token (parser)->type == CPP_NAME
    2494         9186 :           || c_parser_peek_2nd_token (parser)->type == CPP_MULT)
    2495     64237353 :       && (!nested || !lookup_name (c_parser_peek_token (parser)->value)))
    2496              :     {
    2497          131 :       tree name = c_parser_peek_token (parser)->value;
    2498              : 
    2499              :       /* Issue a warning about NAME being an unknown type name, perhaps
    2500              :          with some kind of hint.
    2501              :          If the user forgot a "struct" etc, suggest inserting
    2502              :          it.  Otherwise, attempt to look for misspellings.  */
    2503          131 :       gcc_rich_location richloc (here);
    2504          131 :       if (tag_exists_p (RECORD_TYPE, name))
    2505              :         {
    2506              :           /* This is not C++ with its implicit typedef.  */
    2507            3 :           richloc.add_fixit_insert_before ("struct ");
    2508            3 :           error_at (&richloc,
    2509              :                     "unknown type name %qE;"
    2510              :                     " use %<struct%> keyword to refer to the type",
    2511              :                     name);
    2512              :         }
    2513          128 :       else if (tag_exists_p (UNION_TYPE, name))
    2514              :         {
    2515            3 :           richloc.add_fixit_insert_before ("union ");
    2516            3 :           error_at (&richloc,
    2517              :                     "unknown type name %qE;"
    2518              :                     " use %<union%> keyword to refer to the type",
    2519              :                     name);
    2520              :         }
    2521          125 :       else if (tag_exists_p (ENUMERAL_TYPE, name))
    2522              :         {
    2523            3 :           richloc.add_fixit_insert_before ("enum ");
    2524            3 :           error_at (&richloc,
    2525              :                     "unknown type name %qE;"
    2526              :                     " use %<enum%> keyword to refer to the type",
    2527              :                     name);
    2528              :         }
    2529              :       else
    2530              :         {
    2531          122 :           auto_diagnostic_group d;
    2532          122 :           name_hint hint = lookup_name_fuzzy (name, FUZZY_LOOKUP_TYPENAME,
    2533          122 :                                               here);
    2534          122 :           if (const char *suggestion = hint.suggestion ())
    2535              :             {
    2536           12 :               richloc.add_fixit_replace (suggestion);
    2537           12 :               error_at (&richloc,
    2538              :                         "unknown type name %qE; did you mean %qs?",
    2539              :                         name, suggestion);
    2540              :             }
    2541              :           else
    2542          110 :             error_at (here, "unknown type name %qE", name);
    2543          122 :         }
    2544              : 
    2545              :       /* Parse declspecs normally to get a correct pointer type, but avoid
    2546              :          a further "fails to be a type name" error.  Refuse nested functions
    2547              :          since it is not how the user likely wants us to recover.  */
    2548          131 :       c_parser_peek_token (parser)->type = CPP_KEYWORD;
    2549          131 :       c_parser_peek_token (parser)->keyword = RID_VOID;
    2550          131 :       c_parser_peek_token (parser)->value = error_mark_node;
    2551          131 :       fndef_ok = !nested;
    2552          131 :     }
    2553              : 
    2554              :   /* When there are standard attributes at the start of the
    2555              :      declaration (to apply to the entity being declared), an
    2556              :      init-declarator-list or function definition must be present.  */
    2557     64237220 :   if (c_parser_nth_token_starts_std_attributes (parser, 1))
    2558          602 :     have_attrs = true;
    2559              : 
    2560     64237220 :   c_parser_declspecs (parser, specs, true, true, start_attr_ok,
    2561              :                       true, true, start_attr_ok, true, cla_nonabstract_decl);
    2562     64237220 :   if (parser->error)
    2563              :     {
    2564           33 :       c_parser_skip_to_end_of_block_or_statement (parser);
    2565           33 :       return result;
    2566              :     }
    2567     64237187 :   if (nested && !specs->declspecs_seen_p)
    2568              :     {
    2569           63 :       c_parser_error (parser, "expected declaration specifiers");
    2570           63 :       c_parser_skip_to_end_of_block_or_statement (parser);
    2571           63 :       return result;
    2572              :     }
    2573              : 
    2574     64237124 :   finish_declspecs (specs);
    2575              :   /* When the decl is declared, its type is a top level type, we should
    2576              :      call verify_counted_by_for_top_anonymous_type.  */
    2577     64237124 :   if (specs->typespec_kind == ctsk_tagdef)
    2578      1192288 :     verify_counted_by_for_top_anonymous_type (specs->type);
    2579              : 
    2580     64237124 :   bool gnu_auto_type_p = specs->typespec_word == cts_auto_type;
    2581     64237124 :   bool std_auto_type_p = specs->c23_auto_p;
    2582     64237124 :   bool any_auto_type_p = gnu_auto_type_p || std_auto_type_p;
    2583     64237124 :   gcc_assert (!(gnu_auto_type_p && std_auto_type_p));
    2584     64237124 :   const char *auto_type_keyword = gnu_auto_type_p ? "__auto_type" : "auto";
    2585     64237124 :   if (specs->constexpr_p)
    2586              :     {
    2587              :       /* An underspecified declaration may not declare tags or members
    2588              :          or structures or unions; it is undefined behavior to declare
    2589              :          the members of an enumeration.  Where the structure, union or
    2590              :          enumeration type is declared within an initializer, this is
    2591              :          diagnosed elsewhere.  Diagnose here the case of declaring
    2592              :          such a type in the type specifiers of a constexpr
    2593              :          declaration.  */
    2594          368 :       switch (specs->typespec_kind)
    2595              :         {
    2596            6 :         case ctsk_tagfirstref:
    2597            6 :         case ctsk_tagfirstref_attrs:
    2598            6 :           error_at (here, "%qT declared in underspecified object declaration",
    2599              :                     specs->type);
    2600            6 :           break;
    2601              : 
    2602           10 :         case ctsk_tagdef:
    2603           10 :           error_at (here, "%qT defined in underspecified object declaration",
    2604              :                     specs->type);
    2605           10 :           break;
    2606              : 
    2607              :         default:
    2608              :           break;
    2609              :         }
    2610              :     }
    2611              : 
    2612     64237124 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    2613              :     {
    2614       501899 :       bool handled_assume = false;
    2615       501899 :       if (specs->attrs
    2616          504 :           && !nested
    2617          127 :           && specs->typespec_kind == ctsk_none
    2618       502008 :           && c_parser_handle_statement_omp_attributes (parser, specs->attrs,
    2619              :                                                        NULL))
    2620              :         {
    2621           88 :           if (specs->attrs)
    2622            0 :             c_warn_unused_attributes (specs->attrs);
    2623          177 :           while (parser->in_omp_attribute_pragma)
    2624              :             {
    2625           89 :               gcc_assert (c_parser_next_token_is (parser, CPP_PRAGMA));
    2626           89 :               c_parser_pragma (parser, pragma_external, NULL, NULL_TREE);
    2627              :             }
    2628           88 :           c_parser_consume_token (parser);
    2629           88 :           return result;
    2630              :         }
    2631       501811 :       if (specs->typespec_kind == ctsk_none
    2632       501811 :           && lookup_attribute ("gnu", "assume", specs->attrs))
    2633              :         {
    2634           38 :           handled_assume = true;
    2635           38 :           specs->attrs
    2636           38 :             = handle_assume_attribute (here, specs->attrs, nested);
    2637              :         }
    2638       501811 :       if (any_auto_type_p)
    2639            6 :         error_at (here, "%qs in empty declaration", auto_type_keyword);
    2640       501805 :       else if (specs->typespec_kind == ctsk_none
    2641       501805 :                && attribute_fallthrough_p (specs->attrs))
    2642              :         {
    2643          328 :           if (fallthru_attr_p != NULL)
    2644          327 :             *fallthru_attr_p = true;
    2645          328 :           if (nested)
    2646              :             {
    2647          327 :               tree fn = build_call_expr_internal_loc (here, IFN_FALLTHROUGH,
    2648              :                                                       void_type_node, 0);
    2649          327 :               add_stmt (fn);
    2650              :             }
    2651              :           else
    2652            1 :             pedwarn (here, OPT_Wattributes,
    2653              :                      "%<fallthrough%> attribute at top level");
    2654              :         }
    2655       501477 :       else if (empty_ok
    2656       501460 :                && !(have_attrs && specs->non_std_attrs_seen_p)
    2657       501457 :                && !handled_assume)
    2658       501419 :         shadow_tag (specs);
    2659              :       else
    2660              :         {
    2661           58 :           shadow_tag_warned (specs, 1);
    2662           58 :           if (!handled_assume)
    2663           20 :             pedwarn (here, 0, "empty declaration");
    2664              :         }
    2665              :       /* We still have to evaluate size expressions.  */
    2666       501811 :       if (specs->expr)
    2667          107 :         add_stmt (fold_convert (void_type_node, specs->expr));
    2668       501811 :       c_parser_consume_token (parser);
    2669       501811 :       if (oacc_routine_data)
    2670            0 :         c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
    2671       501811 :       return result;
    2672              :     }
    2673     63735225 :   else if (specs->typespec_kind == ctsk_none
    2674              :            && nested
    2675              :            /* Only parse __attribute__((musttail)) when called from
    2676              :               c_parser_compound_statement_nostart.  This certainly isn't
    2677              :               a declaration in that case, but we don't do tentative parsing
    2678              :               of GNU attributes right now.  */
    2679         9772 :            && fallthru_attr_p
    2680     63735306 :            && c_parser_next_token_is_keyword (parser, RID_RETURN))
    2681              :     {
    2682           12 :       attr_state astate = {};
    2683           12 :       specs->attrs = c_parser_handle_musttail (parser, specs->attrs, astate);
    2684           12 :       if (astate.musttail_p)
    2685              :         {
    2686           12 :           if (specs->attrs)
    2687              :             {
    2688            0 :               auto_urlify_attributes sentinel;
    2689            0 :               warning_at (c_parser_peek_token (parser)->location,
    2690            0 :                           OPT_Wattributes,
    2691              :                           "attribute %<musttail%> mixed with other attributes "
    2692              :                           "on %<return%> statement");
    2693            0 :             }
    2694           12 :           c_parser_statement_after_labels (parser, NULL, NULL_TREE, NULL,
    2695              :                                            astate);
    2696           12 :           return result;
    2697              :         }
    2698              :     }
    2699              : 
    2700              :   /* Provide better error recovery.  Note that a type name here is usually
    2701              :      better diagnosed as a redeclaration.  */
    2702     63735213 :   if (empty_ok
    2703     63722080 :       && specs->typespec_kind == ctsk_tagdef
    2704       779031 :       && c_parser_next_token_starts_declspecs (parser)
    2705     63735243 :       && !c_parser_next_token_is (parser, CPP_NAME))
    2706              :     {
    2707            9 :       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
    2708            9 :       parser->error = false;
    2709            9 :       shadow_tag_warned (specs, 1);
    2710            9 :       return result;
    2711              :     }
    2712     63735204 :   else if (c_dialect_objc () && !any_auto_type_p)
    2713              :     {
    2714              :       /* Prefix attributes are an error on method decls.  */
    2715            0 :       switch (c_parser_peek_token (parser)->type)
    2716              :         {
    2717            0 :           case CPP_PLUS:
    2718            0 :           case CPP_MINUS:
    2719            0 :             if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
    2720              :               return result;
    2721            0 :             if (specs->attrs)
    2722              :               {
    2723            0 :                 warning_at (c_parser_peek_token (parser)->location,
    2724            0 :                             OPT_Wattributes,
    2725              :                             "prefix attributes are ignored for methods");
    2726            0 :                 specs->attrs = NULL_TREE;
    2727              :               }
    2728            0 :             if (fndef_ok)
    2729            0 :               c_parser_objc_method_definition (parser);
    2730              :             else
    2731            0 :               c_parser_objc_methodproto (parser);
    2732            0 :             return result;
    2733            0 :             break;
    2734            0 :           default:
    2735            0 :             break;
    2736              :         }
    2737              :       /* This is where we parse 'attributes @interface ...',
    2738              :          'attributes @implementation ...', 'attributes @protocol ...'
    2739              :          (where attributes could be, for example, __attribute__
    2740              :          ((deprecated)).
    2741              :       */
    2742            0 :       switch (c_parser_peek_token (parser)->keyword)
    2743              :         {
    2744            0 :         case RID_AT_INTERFACE:
    2745            0 :           {
    2746            0 :             if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
    2747              :               return result;
    2748            0 :             c_parser_objc_class_definition (parser, specs->attrs);
    2749            0 :             return result;
    2750              :           }
    2751            0 :           break;
    2752            0 :         case RID_AT_IMPLEMENTATION:
    2753            0 :           {
    2754            0 :             if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
    2755              :               return result;
    2756            0 :             if (specs->attrs)
    2757              :               {
    2758            0 :                 warning_at (c_parser_peek_token (parser)->location,
    2759            0 :                         OPT_Wattributes,
    2760              :                         "prefix attributes are ignored for implementations");
    2761            0 :                 specs->attrs = NULL_TREE;
    2762              :               }
    2763            0 :             c_parser_objc_class_definition (parser, NULL_TREE);
    2764            0 :             return result;
    2765              :           }
    2766            0 :           break;
    2767            0 :         case RID_AT_PROTOCOL:
    2768            0 :           {
    2769            0 :             if (c_parser_objc_diagnose_bad_element_prefix (parser, specs))
    2770              :               return result;
    2771            0 :             c_parser_objc_protocol_definition (parser, specs->attrs);
    2772            0 :             return result;
    2773              :           }
    2774            0 :           break;
    2775            0 :         case RID_AT_ALIAS:
    2776            0 :         case RID_AT_CLASS:
    2777            0 :         case RID_AT_END:
    2778            0 :         case RID_AT_PROPERTY:
    2779            0 :           if (specs->attrs)
    2780              :             {
    2781            0 :               c_parser_error (parser, "unexpected attribute");
    2782            0 :               specs->attrs = NULL;
    2783              :             }
    2784              :           break;
    2785              :         default:
    2786              :           break;
    2787              :         }
    2788              :     }
    2789     63735204 :   else if (attribute_fallthrough_p (specs->attrs))
    2790            5 :     warning_at (here, OPT_Wattributes,
    2791              :                 "%<fallthrough%> attribute not followed by %<;%>");
    2792     63735199 :   else if (lookup_attribute ("gnu", "assume", specs->attrs))
    2793            2 :     warning_at (here, OPT_Wattributes,
    2794              :                 "%<assume%> attribute not followed by %<;%>");
    2795              : 
    2796    127470403 :   auto_vec<c_token> omp_declare_simd_attr_clauses;
    2797     63735204 :   c_parser_handle_directive_omp_attributes (specs->attrs,
    2798              :                                             omp_declare_simd_clauses,
    2799              :                                             &omp_declare_simd_attr_clauses);
    2800     63735204 :   pending_xref_error ();
    2801     63735204 :   prefix_attrs = specs->attrs;
    2802     63735204 :   all_prefix_attrs = prefix_attrs;
    2803     63735204 :   specs->attrs = NULL_TREE;
    2804     63735204 :   bool more_than_one_decl = false;
    2805     64585756 :   while (true)
    2806              :     {
    2807     64160480 :       struct c_declarator *declarator;
    2808     64160480 :       bool dummy = false;
    2809     64160480 :       timevar_id_t tv;
    2810     64160480 :       tree fnbody = NULL_TREE;
    2811     64160480 :       tree underspec_name = NULL_TREE;
    2812     64160480 :       auto_vec<c_token> omp_dsimd_idattr_clauses;
    2813              :       /* Declaring either one or more declarators (in which case we
    2814              :          should diagnose if there were no declaration specifiers) or a
    2815              :          function definition (in which case the diagnostic for
    2816              :          implicit int suffices).  */
    2817    128320960 :       declarator = c_parser_declarator (parser,
    2818     64160480 :                                         specs->typespec_kind != ctsk_none,
    2819              :                                         C_DTR_NORMAL, &dummy);
    2820     64160480 :       if (declarator == NULL)
    2821              :         {
    2822          211 :           if (omp_declare_simd_clauses)
    2823            1 :             c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
    2824              :                                        omp_declare_simd_clauses);
    2825          211 :           if (oacc_routine_data)
    2826            0 :             c_finish_oacc_routine (oacc_routine_data, NULL_TREE, false);
    2827              :           /* This check is here purely to improve the diagnostic.  */
    2828          211 :           if (!simple_ok)
    2829          191 :             c_parser_skip_to_end_of_block_or_statement (parser);
    2830          211 :           return result;
    2831              :         }
    2832     64160269 :       if (flag_openmp || flag_openmp_simd)
    2833              :         {
    2834              :           struct c_declarator *d = declarator;
    2835       857716 :           while (d->kind != cdk_id)
    2836       372924 :             d = d->declarator;
    2837       484792 :           vec<c_token> *dummy = NULL;
    2838       484792 :           c_parser_handle_directive_omp_attributes (d->u.id.attrs, dummy,
    2839              :                                                     &omp_dsimd_idattr_clauses);
    2840              :         }
    2841     64160269 :       if (gnu_auto_type_p && declarator->kind != cdk_id)
    2842              :         {
    2843            1 :           error_at (here,
    2844              :                     "%<__auto_type%> requires a plain identifier"
    2845              :                     " as declarator");
    2846            1 :           c_parser_skip_to_end_of_block_or_statement (parser);
    2847            1 :           return result;
    2848              :         }
    2849     64160268 :       if (std_auto_type_p)
    2850              :         {
    2851              :           struct c_declarator *d = declarator;
    2852           82 :           while (d->kind == cdk_attrs)
    2853            0 :             d = d->declarator;
    2854           82 :           if (d->kind != cdk_id)
    2855              :             {
    2856            1 :               error_at (here,
    2857              :                         "%<auto%> requires a plain identifier, possibly with"
    2858              :                         " attributes, as declarator");
    2859            1 :               c_parser_skip_to_end_of_block_or_statement (parser);
    2860            1 :               return result;
    2861              :             }
    2862           81 :           underspec_name = d->u.id.id;
    2863              :         }
    2864     64160186 :       else if (specs->constexpr_p)
    2865              :         {
    2866              :           struct c_declarator *d = declarator;
    2867          432 :           while (d->kind != cdk_id)
    2868           79 :             d = d->declarator;
    2869          353 :           underspec_name = d->u.id.id;
    2870              :         }
    2871     64160267 :       if (c_parser_next_token_is (parser, CPP_EQ)
    2872     57824493 :           || c_parser_next_token_is (parser, CPP_COMMA)
    2873     57515825 :           || c_parser_next_token_is (parser, CPP_SEMICOLON)
    2874     49481048 :           || c_parser_next_token_is_keyword (parser, RID_ASM)
    2875     48609602 :           || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE)
    2876    100410687 :           || c_parser_next_token_is_keyword (parser, RID_IN))
    2877              :         {
    2878     27909847 :           tree asm_name = NULL_TREE;
    2879     27909847 :           tree postfix_attrs = NULL_TREE;
    2880     27909847 :           if (!diagnosed_no_specs && !specs->declspecs_seen_p)
    2881              :             {
    2882           79 :               diagnosed_no_specs = true;
    2883           79 :               pedwarn (here, 0, "data definition has no type or storage class");
    2884              :             }
    2885              :           /* Having seen a data definition, there cannot now be a
    2886              :              function definition.  */
    2887     27909847 :           fndef_ok = false;
    2888     27909847 :           if (c_parser_next_token_is_keyword (parser, RID_ASM))
    2889       871446 :             asm_name = c_parser_simple_asm_expr (parser);
    2890     27909847 :           if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    2891              :             {
    2892     13181331 :               postfix_attrs = c_parser_gnu_attributes (parser);
    2893     13181331 :               if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    2894              :                 {
    2895              :                   /* This means there is an attribute specifier after
    2896              :                      the declarator in a function definition.  Provide
    2897              :                      some more information for the user.  */
    2898            1 :                   error_at (here, "attributes should be specified before the "
    2899              :                             "declarator in a function definition");
    2900            1 :                   c_parser_skip_to_end_of_block_or_statement (parser);
    2901            1 :                   return result;
    2902              :                 }
    2903              :             }
    2904     27909846 :           if (c_parser_next_token_is (parser, CPP_EQ))
    2905              :             {
    2906      6337213 :               tree d;
    2907      6337213 :               struct c_expr init;
    2908      6337213 :               location_t init_loc;
    2909      6337213 :               c_parser_consume_token (parser);
    2910      6337213 :               if (any_auto_type_p)
    2911              :                 {
    2912         1953 :                   init_loc = c_parser_peek_token (parser)->location;
    2913         1953 :                   rich_location richloc (line_table, init_loc);
    2914         1953 :                   unsigned int underspec_state = 0;
    2915         1953 :                   if (std_auto_type_p)
    2916           79 :                     underspec_state =
    2917           79 :                       start_underspecified_init (init_loc, underspec_name);
    2918         1953 :                   start_init (NULL_TREE, asm_name,
    2919         1953 :                               (global_bindings_p ()
    2920         1889 :                                || specs->storage_class == csc_static
    2921         3840 :                                || specs->constexpr_p),
    2922         1953 :                               specs->constexpr_p, &richloc);
    2923              :                   /* A parameter is initialized, which is invalid.  Don't
    2924              :                      attempt to instrument the initializer.  */
    2925         1953 :                   sanitize_code_type flag_sanitize_save = flag_sanitize;
    2926         1953 :                   if (nested && !empty_ok)
    2927           30 :                     flag_sanitize = 0;
    2928         1953 :                   init = c_parser_expr_no_commas (parser, NULL);
    2929         1953 :                   if (std_auto_type_p)
    2930           79 :                     finish_underspecified_init (underspec_name,
    2931              :                                                 underspec_state);
    2932         1953 :                   flag_sanitize = flag_sanitize_save;
    2933         1953 :                   if (gnu_auto_type_p
    2934         1874 :                       && TREE_CODE (init.value) == COMPONENT_REF
    2935         1954 :                       && DECL_C_BIT_FIELD (TREE_OPERAND (init.value, 1)))
    2936            1 :                     error_at (here,
    2937              :                               "%<__auto_type%> used with a bit-field"
    2938              :                               " initializer");
    2939         1953 :                   init = convert_lvalue_to_rvalue (init_loc, init, true, true,
    2940              :                                                    true);
    2941         1953 :                   tree init_type = TREE_TYPE (init.value);
    2942         1953 :                   bool vm_type = c_type_variably_modified_p (init_type);
    2943         1953 :                   if (vm_type)
    2944           95 :                     init.value = save_expr (init.value);
    2945         1953 :                   finish_init ();
    2946         1953 :                   specs->typespec_kind = ctsk_typeof;
    2947         1953 :                   specs->locations[cdw_typedef] = init_loc;
    2948         1953 :                   specs->typedef_p = true;
    2949         1953 :                   specs->type = init_type;
    2950         1953 :                   if (specs->postfix_attrs)
    2951              :                     {
    2952              :                       /* Postfix [[]] attributes are valid with C23
    2953              :                          auto, although not with __auto_type, and
    2954              :                          modify the type given by the initializer.  */
    2955            2 :                       specs->postfix_attrs
    2956            2 :                         = c_warn_type_attributes (specs->type,
    2957              :                                                   specs->postfix_attrs);
    2958            2 :                       decl_attributes (&specs->type, specs->postfix_attrs, 0);
    2959            2 :                       specs->postfix_attrs = NULL_TREE;
    2960              :                     }
    2961         1953 :                   if (vm_type)
    2962              :                     {
    2963           95 :                       bool maybe_const = true;
    2964           95 :                       tree type_expr = c_fully_fold (init.value, false,
    2965              :                                                      &maybe_const);
    2966           95 :                       specs->expr_const_operands &= maybe_const;
    2967           95 :                       if (specs->expr)
    2968            0 :                         specs->expr = build2 (COMPOUND_EXPR,
    2969            0 :                                               TREE_TYPE (type_expr),
    2970              :                                               specs->expr, type_expr);
    2971              :                       else
    2972           95 :                         specs->expr = type_expr;
    2973              :                     }
    2974         1953 :                   d = start_decl (declarator, specs, true,
    2975              :                                   chainon (postfix_attrs, all_prefix_attrs));
    2976         1953 :                   if (!d)
    2977           12 :                     d = error_mark_node;
    2978         1953 :                   if (omp_declare_simd_clauses)
    2979            0 :                     c_finish_omp_declare_simd (parser, d, NULL_TREE,
    2980              :                                                omp_declare_simd_clauses);
    2981         1953 :                   if (!omp_dsimd_idattr_clauses.is_empty ())
    2982            0 :                     c_finish_omp_declare_simd (parser, d, NULL_TREE,
    2983              :                                                &omp_dsimd_idattr_clauses);
    2984         1953 :                 }
    2985              :               else
    2986              :                 {
    2987              :                   /* The declaration of the variable is in effect while
    2988              :                      its initializer is parsed, except for a constexpr
    2989              :                      variable.  */
    2990      6335260 :                   init_loc = c_parser_peek_token (parser)->location;
    2991      6335260 :                   rich_location richloc (line_table, init_loc);
    2992      6335260 :                   unsigned int underspec_state = 0;
    2993      6335260 :                   if (specs->constexpr_p)
    2994          348 :                     underspec_state =
    2995          348 :                       start_underspecified_init (init_loc, underspec_name);
    2996      6335260 :                   d = start_decl (declarator, specs, true,
    2997              :                                   chainon (postfix_attrs,
    2998              :                                            all_prefix_attrs),
    2999      6335260 :                                   !specs->constexpr_p);
    3000      6335260 :                   if (!d)
    3001            4 :                     d = error_mark_node;
    3002      6335260 :                   if (!specs->constexpr_p && omp_declare_simd_clauses)
    3003            0 :                     c_finish_omp_declare_simd (parser, d, NULL_TREE,
    3004              :                                                omp_declare_simd_clauses);
    3005      6335260 :                   if (!specs->constexpr_p
    3006      6335260 :                       && !omp_dsimd_idattr_clauses.is_empty ())
    3007            0 :                     c_finish_omp_declare_simd (parser, d, NULL_TREE,
    3008              :                                                &omp_dsimd_idattr_clauses);
    3009      6335260 :                   start_init (d, asm_name,
    3010      6158716 :                               TREE_STATIC (d) || specs->constexpr_p,
    3011      6335260 :                               specs->constexpr_p, &richloc);
    3012              :                   /* A parameter is initialized, which is invalid.  Don't
    3013              :                      attempt to instrument the initializer.  */
    3014      6335260 :                   sanitize_code_type flag_sanitize_save = flag_sanitize;
    3015      6335260 :                   if (TREE_CODE (d) == PARM_DECL)
    3016           35 :                     flag_sanitize = 0;
    3017      6335260 :                   init = c_parser_initializer (parser, d);
    3018      6335258 :                   flag_sanitize = flag_sanitize_save;
    3019      6335258 :                   if (specs->constexpr_p)
    3020              :                     {
    3021          348 :                       finish_underspecified_init (underspec_name,
    3022              :                                                   underspec_state);
    3023          348 :                       d = pushdecl (d);
    3024          348 :                       if (omp_declare_simd_clauses)
    3025            0 :                         c_finish_omp_declare_simd (parser, d, NULL_TREE,
    3026              :                                                    omp_declare_simd_clauses);
    3027          348 :                   if (!specs->constexpr_p
    3028          348 :                       && !omp_dsimd_idattr_clauses.is_empty ())
    3029            0 :                     c_finish_omp_declare_simd (parser, d, NULL_TREE,
    3030              :                                                &omp_dsimd_idattr_clauses);
    3031              :                     }
    3032      6335258 :                   finish_init ();
    3033      6335258 :                 }
    3034      6337211 :               if (oacc_routine_data)
    3035            0 :                 c_finish_oacc_routine (oacc_routine_data, d, false);
    3036      6337211 :               if (d != error_mark_node)
    3037              :                 {
    3038      6337195 :                   maybe_warn_string_init (init_loc, TREE_TYPE (d), init);
    3039      6337195 :                   finish_decl (d, init_loc, init.value,
    3040              :                                init.original_type, asm_name);
    3041      6337195 :                   result = d;
    3042              :                 }
    3043              :             }
    3044              :           else
    3045              :             {
    3046     21572633 :               if (any_auto_type_p || specs->constexpr_p)
    3047              :                 {
    3048            8 :                   error_at (here,
    3049              :                             "%qs requires an initialized data declaration",
    3050              :                             any_auto_type_p ? auto_type_keyword : "constexpr");
    3051            5 :                   c_parser_skip_to_end_of_block_or_statement (parser);
    3052            5 :                   return result;
    3053              :                 }
    3054              : 
    3055     21572628 :               location_t lastloc = UNKNOWN_LOCATION;
    3056     21572628 :               tree attrs = chainon (postfix_attrs, all_prefix_attrs);
    3057     21572628 :               tree d = start_decl (declarator, specs, false, attrs, true,
    3058              :                                    &lastloc);
    3059     21572627 :               if (d && TREE_CODE (d) == FUNCTION_DECL)
    3060              :                 {
    3061              :                   /* Find the innermost declarator that is neither cdk_id
    3062              :                      nor cdk_attrs.  */
    3063              :                   const struct c_declarator *decl = declarator;
    3064              :                   const struct c_declarator *last_non_id_attrs = NULL;
    3065              : 
    3066     29692165 :                   while (decl)
    3067     29692165 :                     switch (decl->kind)
    3068              :                       {
    3069     15020635 :                       case cdk_array:
    3070     15020635 :                       case cdk_function:
    3071     15020635 :                       case cdk_pointer:
    3072     15020635 :                         last_non_id_attrs = decl;
    3073     15020635 :                         decl = decl->declarator;
    3074     15020635 :                         break;
    3075              : 
    3076          111 :                       case cdk_attrs:
    3077          111 :                         decl = decl->declarator;
    3078          111 :                         break;
    3079              : 
    3080              :                       case cdk_id:
    3081              :                         decl = 0;
    3082              :                         break;
    3083              : 
    3084            0 :                       default:
    3085            0 :                         gcc_unreachable ();
    3086              :                       }
    3087              : 
    3088              :                   /* If it exists and is cdk_function declaration whose
    3089              :                      arguments have not been set yet, use its arguments.  */
    3090     14671419 :                   if (last_non_id_attrs
    3091     14050743 :                       && last_non_id_attrs->kind == cdk_function)
    3092              :                     {
    3093     14050743 :                       tree parms = last_non_id_attrs->u.arg_info->parms;
    3094     14050743 :                       if (DECL_ARGUMENTS (d) == NULL_TREE
    3095     14050743 :                           && DECL_INITIAL (d) == NULL_TREE)
    3096     13596770 :                         DECL_ARGUMENTS (d) = parms;
    3097              : 
    3098     14050743 :                       warn_parms_array_mismatch (lastloc, d, parms);
    3099              :                     }
    3100              :                 }
    3101     21572627 :               if (omp_declare_simd_clauses
    3102     21572627 :                   || !omp_dsimd_idattr_clauses.is_empty ())
    3103              :                 {
    3104          489 :                   tree parms = NULL_TREE;
    3105          489 :                   if (d && TREE_CODE (d) == FUNCTION_DECL)
    3106              :                     {
    3107              :                       struct c_declarator *ce = declarator;
    3108          478 :                       while (ce != NULL)
    3109          478 :                         if (ce->kind == cdk_function)
    3110              :                           {
    3111          475 :                             parms = ce->u.arg_info->parms;
    3112          475 :                             break;
    3113              :                           }
    3114              :                         else
    3115            3 :                           ce = ce->declarator;
    3116              :                     }
    3117          475 :                   if (parms)
    3118          249 :                     temp_store_parm_decls (d, parms);
    3119          489 :                   if (omp_declare_simd_clauses)
    3120          469 :                     c_finish_omp_declare_simd (parser, d, parms,
    3121              :                                                omp_declare_simd_clauses);
    3122          489 :                   if (!specs->constexpr_p
    3123          489 :                       && !omp_dsimd_idattr_clauses.is_empty ())
    3124           22 :                     c_finish_omp_declare_simd (parser, d, parms,
    3125              :                                                &omp_dsimd_idattr_clauses);
    3126          489 :                   if (parms)
    3127          249 :                     temp_pop_parm_decls ();
    3128              :                 }
    3129     21572627 :               if (oacc_routine_data)
    3130           72 :                 c_finish_oacc_routine (oacc_routine_data, d, false);
    3131     21572627 :               if (d)
    3132     21572619 :                 finish_decl (d, UNKNOWN_LOCATION, NULL_TREE,
    3133              :                              NULL_TREE, asm_name);
    3134              : 
    3135     21572627 :               if (c_parser_next_token_is_keyword (parser, RID_IN))
    3136              :                 {
    3137            0 :                   if (d)
    3138            0 :                     *objc_foreach_object_declaration = d;
    3139              :                   else
    3140            0 :                     *objc_foreach_object_declaration = error_mark_node;
    3141              :                 }
    3142              :             }
    3143     27909838 :           if (c_parser_next_token_is (parser, CPP_COMMA))
    3144              :             {
    3145       425279 :               more_than_one_decl = true;
    3146       425279 :               if (any_auto_type_p || specs->constexpr_p)
    3147              :                 {
    3148            4 :                   error_at (here,
    3149              :                             "%qs may only be used with a single declarator",
    3150              :                             any_auto_type_p ? auto_type_keyword : "constexpr");
    3151            3 :                   c_parser_skip_to_end_of_block_or_statement (parser);
    3152            3 :                   return result;
    3153              :                 }
    3154       425276 :               c_parser_consume_token (parser);
    3155       425276 :               if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    3156           19 :                 all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
    3157              :                                             prefix_attrs);
    3158              :               else
    3159              :                 all_prefix_attrs = prefix_attrs;
    3160       425276 :               continue;
    3161              :             }
    3162     27484559 :           else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    3163              :             {
    3164     27484419 :               if (!simple_ok)
    3165     27484320 :                 c_parser_consume_token (parser);
    3166     27484419 :               return result;
    3167              :             }
    3168          140 :           else if (c_parser_next_token_is_keyword (parser, RID_IN))
    3169              :             {
    3170              :               /* This can only happen in Objective-C: we found the
    3171              :                  'in' that terminates the declaration inside an
    3172              :                  Objective-C foreach statement.  Do not consume the
    3173              :                  token, so that the caller can use it to determine
    3174              :                  that this indeed is a foreach context.  */
    3175              :               return result;
    3176              :             }
    3177              :           else
    3178              :             {
    3179          140 :               if (!simple_ok)
    3180              :                 {
    3181           48 :                   c_parser_error (parser, "expected %<,%> or %<;%>");
    3182           48 :                   c_parser_skip_to_end_of_block_or_statement (parser);
    3183              :                 }
    3184              :               /* It's not valid to use if (int i = 2, j = 3).  */
    3185           92 :               else if (more_than_one_decl)
    3186            4 :                 error_at (here, "declaration in condition can only declare "
    3187              :                           "a single object");
    3188          140 :               return result;
    3189              :             }
    3190              :         }
    3191     36250420 :       else if (any_auto_type_p || specs->constexpr_p)
    3192              :         {
    3193            4 :           error_at (here,
    3194              :                     "%qs requires an initialized data declaration",
    3195              :                     any_auto_type_p ? auto_type_keyword : "constexpr");
    3196            4 :           c_parser_skip_to_end_of_block_or_statement (parser);
    3197            4 :           return result;
    3198              :         }
    3199     36250416 :       else if (!fndef_ok)
    3200              :         {
    3201           76 :           if (simple_ok && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    3202              :             /* Let c_parser_selection_header emit the error.  */;
    3203              :           else
    3204              :             {
    3205           36 :               c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, "
    3206              :                               "%<asm%> or %<__attribute__%>");
    3207           36 :               c_parser_skip_to_end_of_block_or_statement (parser);
    3208              :             }
    3209           56 :           return result;
    3210              :         }
    3211              :       /* Function definition (nested or otherwise).  */
    3212     36250360 :       if (nested)
    3213              :         {
    3214         1588 :           pedwarn (here, OPT_Wpedantic, "ISO C forbids nested functions");
    3215         1588 :           c_push_function_context ();
    3216              :         }
    3217              : 
    3218              :       /* If we're in an OpenMP "begin declare variant" block, the
    3219              :          name in the declarator refers to the base function.  We need
    3220              :          to save that and modify the declarator to have the mangled
    3221              :          name for the variant function instead.  */
    3222     36250360 :       tree dv_base = NULL_TREE;
    3223     36250360 :       tree dv_ctx = NULL_TREE;
    3224     36250360 :       if (!vec_safe_is_empty (current_omp_declare_variant_attribute))
    3225              :         {
    3226           24 :           c_omp_declare_variant_attr a
    3227           24 :             = current_omp_declare_variant_attribute->last ();
    3228           24 :           dv_ctx = copy_list (a.selector);
    3229           24 :           dv_base = omp_start_variant_function (declarator, dv_ctx);
    3230              :         }
    3231              : 
    3232     36250360 :       if (!start_function (specs, declarator, all_prefix_attrs))
    3233              :         {
    3234              :           /* At this point we've consumed:
    3235              :                declaration-specifiers declarator
    3236              :              and the next token isn't CPP_EQ, CPP_COMMA, CPP_SEMICOLON,
    3237              :              RID_ASM, RID_ATTRIBUTE, or RID_IN,
    3238              :              but the
    3239              :                declaration-specifiers declarator
    3240              :              aren't grokkable as a function definition, so we have
    3241              :              an error.  */
    3242           38 :           gcc_assert (!c_parser_next_token_is (parser, CPP_SEMICOLON));
    3243           38 :           if (c_parser_next_token_starts_declspecs (parser))
    3244              :             {
    3245              :               /* If we have
    3246              :                    declaration-specifiers declarator decl-specs
    3247              :                  then assume we have a missing semicolon, which would
    3248              :                  give us:
    3249              :                    declaration-specifiers declarator  decl-specs
    3250              :                                                     ^
    3251              :                                                     ;
    3252              :                    <~~~~~~~~~ declaration ~~~~~~~~~~>
    3253              :                  Use c_parser_require to get an error with a fix-it hint.  */
    3254           13 :               c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>");
    3255           13 :               parser->error = false;
    3256              :             }
    3257              :           else
    3258              :             {
    3259              :               /* This can appear in many cases looking nothing like a
    3260              :                  function definition, so we don't give a more specific
    3261              :                  error suggesting there was one.  */
    3262           25 :               c_parser_error (parser, "expected %<=%>, %<,%>, %<;%>, %<asm%> "
    3263              :                               "or %<__attribute__%>");
    3264              :             }
    3265           38 :           if (nested)
    3266            1 :             c_pop_function_context ();
    3267              :           break;
    3268              :         }
    3269              : 
    3270     36250322 :       if (DECL_DECLARED_INLINE_P (current_function_decl))
    3271              :         tv = TV_PARSE_INLINE;
    3272              :       else
    3273       689642 :         tv = TV_PARSE_FUNC;
    3274     36250322 :       auto_timevar at (g_timer, tv);
    3275              : 
    3276              :       /* Parse old-style parameter declarations.  ??? Attributes are
    3277              :          not allowed to start declaration specifiers here because of a
    3278              :          syntax conflict between a function declaration with attribute
    3279              :          suffix and a function definition with an attribute prefix on
    3280              :          first old-style parameter declaration.  Following the old
    3281              :          parser, they are not accepted on subsequent old-style
    3282              :          parameter declarations either.  However, there is no
    3283              :          ambiguity after the first declaration, nor indeed on the
    3284              :          first as long as we don't allow postfix attributes after a
    3285              :          declarator with a nonempty identifier list in a definition;
    3286              :          and postfix attributes have never been accepted here in
    3287              :          function definitions either.  */
    3288     36250322 :       int save_debug_nonbind_markers_p = debug_nonbind_markers_p;
    3289     36250322 :       debug_nonbind_markers_p = 0;
    3290     36250322 :       c_parser_maybe_reclassify_token (parser);
    3291     36250322 :       while (c_parser_next_token_is_not (parser, CPP_EOF)
    3292     72526584 :              && c_parser_next_token_is_not (parser, CPP_OPEN_BRACE))
    3293        12978 :         c_parser_declaration_or_fndef (parser, false, false, false,
    3294              :                                        true, false, false);
    3295     36250322 :       debug_nonbind_markers_p = save_debug_nonbind_markers_p;
    3296     36250322 :       store_parm_decls ();
    3297     36250322 :       if (omp_declare_simd_clauses)
    3298          357 :         c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
    3299              :                                    omp_declare_simd_clauses);
    3300     36250322 :       if (!omp_dsimd_idattr_clauses.is_empty ())
    3301            4 :         c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
    3302              :                                    &omp_dsimd_idattr_clauses);
    3303     36250322 :       if (oacc_routine_data)
    3304          130 :         c_finish_oacc_routine (oacc_routine_data, current_function_decl, true);
    3305     36250322 :       location_t startloc = c_parser_peek_token (parser)->location;
    3306     36250322 :       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
    3307     36250322 :         = startloc;
    3308     36250322 :       location_t endloc = startloc;
    3309              :       /* If this function was in a "begin declare variant" block,
    3310              :          remember it.  We will associate it with the base function at
    3311              :          the end of processing the translation unit, since it is permitted
    3312              :          for the variant definition to appear before the base declaration.  */
    3313     36250322 :       if (dv_base && current_function_decl != error_mark_node)
    3314              :         {
    3315           24 :           omp_begin_declare_variant_map_entry e
    3316           24 :             = { current_function_decl, dv_base, dv_ctx };
    3317           24 :           vec_safe_push (omp_begin_declare_variant_map, e);
    3318              :         }
    3319              : 
    3320              :       /* If the definition was marked with __RTL, use the RTL parser now,
    3321              :          consuming the function body.  */
    3322     36250322 :       if (specs->declspec_il == cdil_rtl)
    3323              :         {
    3324           25 :           endloc = c_parser_parse_rtl_body (parser, specs->gimple_or_rtl_pass);
    3325              : 
    3326              :           /* Normally, store_parm_decls sets next_is_function_body,
    3327              :              anticipating a function body.  We need a push_scope/pop_scope
    3328              :              pair to flush out this state, or subsequent function parsing
    3329              :              will go wrong.  */
    3330           24 :           push_scope ();
    3331           24 :           pop_scope ();
    3332              : 
    3333           24 :           finish_function (endloc);
    3334           24 :           return result;
    3335              :         }
    3336              :       /* If the definition was marked with __GIMPLE then parse the
    3337              :          function body as GIMPLE.  */
    3338     36250297 :       else if (specs->declspec_il != cdil_none)
    3339              :         {
    3340          507 :           bool saved = in_late_binary_op;
    3341          507 :           in_late_binary_op = true;
    3342          507 :           c_parser_parse_gimple_body (parser, specs->gimple_or_rtl_pass,
    3343          507 :                                       specs->declspec_il,
    3344              :                                       specs->entry_bb_count);
    3345          507 :           in_late_binary_op = saved;
    3346              :         }
    3347              :       else
    3348     36249790 :         fnbody = c_parser_compound_statement (parser, &endloc);
    3349     36250296 :       tree fndecl = current_function_decl;
    3350     36250296 :       if (nested && specs->declspec_il == cdil_none)
    3351              :         {
    3352         1586 :           tree decl = current_function_decl;
    3353              :           /* Mark nested functions as needing static-chain initially.
    3354              :              lower_nested_functions will recompute it but the
    3355              :              DECL_STATIC_CHAIN flag is also used before that happens,
    3356              :              by initializer_constant_valid_p.  See gcc.dg/nested-fn-2.c.  */
    3357         1586 :           DECL_STATIC_CHAIN (decl) = 1;
    3358         1586 :           add_stmt (fnbody);
    3359         1586 :           finish_function (endloc);
    3360         1586 :           c_pop_function_context ();
    3361         1586 :           add_stmt (build_stmt (DECL_SOURCE_LOCATION (decl), DECL_EXPR, decl));
    3362         1586 :         }
    3363            1 :       else if (nested)
    3364              :         {
    3365            1 :           if (specs->declspec_il == cdil_rtl)
    3366            0 :             error ("%<__RTL%> function cannot be a nested function");
    3367              :           else
    3368            1 :             error ("%<__GIMPLE%> function cannot be a nested function");
    3369            1 :           finish_function (endloc);
    3370            1 :           c_pop_function_context ();
    3371              :         }
    3372              :       else
    3373              :         {
    3374     36248709 :           if (fnbody)
    3375     36248203 :             add_stmt (fnbody);
    3376     36248709 :           finish_function (endloc);
    3377              :         }
    3378              :       /* Get rid of the empty stmt list for GIMPLE/RTL.  */
    3379     36250296 :       if (specs->declspec_il != cdil_none)
    3380          507 :         DECL_SAVED_TREE (fndecl) = NULL_TREE;
    3381              : 
    3382     36250296 :       break;
    3383     27910141 :     }
    3384              : 
    3385     36250334 :   return result;
    3386              : }
    3387              : 
    3388              : /* Parse an asm-definition (asm() outside a function body).  This is a
    3389              :    GNU extension.
    3390              : 
    3391              :    asm-definition:
    3392              :      simple-asm-expr ;
    3393              :      asm ( toplevel-asm-argument ) ;
    3394              : 
    3395              :    toplevel-asm-argument:
    3396              :      asm-string-literal
    3397              :      asm-string-literal : asm-operands[opt]
    3398              :      asm-string-literal : asm-operands[opt] : asm-operands[opt]
    3399              : 
    3400              :    The :: token is considered equivalent to two consecutive : tokens.  */
    3401              : 
    3402              : static void
    3403          214 : c_parser_asm_definition (c_parser *parser)
    3404              : {
    3405          214 :   location_t asm_loc = c_parser_peek_token (parser)->location;
    3406          214 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
    3407          214 :   c_parser_consume_token (parser);
    3408          214 :   matching_parens parens;
    3409          214 :   tree asm_str = NULL_TREE;
    3410          214 :   tree outputs = NULL_TREE, inputs = NULL_TREE;
    3411          214 :   if (!parens.require_open (parser))
    3412            5 :     goto done;
    3413          209 :   asm_str = c_parser_asm_string_literal (parser);
    3414          209 :   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    3415              :     {
    3416          154 :       parens.require_close (parser);
    3417          154 :       goto done;
    3418              :     }
    3419           73 :   for (int section = 0; section < 2; ++section)
    3420              :     {
    3421           71 :       if (c_parser_next_token_is (parser, CPP_SCOPE))
    3422              :         {
    3423           29 :           ++section;
    3424           29 :           if (section == 2)
    3425              :             {
    3426            0 :               c_parser_error (parser, "expected %<)%>");
    3427            1 :             error_close_paren:
    3428            1 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    3429            1 :               asm_str = NULL_TREE;
    3430            1 :               goto done;
    3431              :             }
    3432           29 :           c_parser_consume_token (parser);
    3433              :         }
    3434           42 :       else if (!c_parser_require (parser, CPP_COLON,
    3435              :                                   "expected %<:%> or %<)%>",
    3436              :                                   UNKNOWN_LOCATION, false))
    3437            1 :         goto error_close_paren;
    3438           70 :       if (!c_parser_next_token_is (parser, CPP_COLON)
    3439           56 :           && !c_parser_next_token_is (parser, CPP_SCOPE)
    3440          126 :           && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    3441              :         {
    3442           56 :           if (section)
    3443           45 :             inputs = c_parser_asm_operands (parser);
    3444              :           else
    3445           11 :             outputs = c_parser_asm_operands (parser);
    3446              :         }
    3447           70 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    3448              :         break;
    3449              :     }
    3450              : 
    3451           54 :   if (!parens.require_close (parser))
    3452              :     {
    3453            2 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    3454            2 :       asm_str = NULL_TREE;
    3455              :     }
    3456              : 
    3457           54 :   if (asm_str)
    3458           52 :     asm_str = build_asm_expr (asm_loc, asm_str, outputs, inputs,
    3459              :                               NULL_TREE, NULL_TREE, false, false);
    3460          212 : done:
    3461          212 :   if (asm_str)
    3462          206 :     symtab->finalize_toplevel_asm (asm_str);
    3463          214 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
    3464          214 : }
    3465              : 
    3466              : /* Parse a static assertion (C11 6.7.10).
    3467              : 
    3468              :    static_assert-declaration:
    3469              :      static_assert-declaration-no-semi ;
    3470              : */
    3471              : 
    3472              : static void
    3473         1948 : c_parser_static_assert_declaration (c_parser *parser)
    3474              : {
    3475         1948 :   c_parser_static_assert_declaration_no_semi (parser);
    3476         1948 :   if (parser->error
    3477         1948 :       || !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
    3478            8 :     c_parser_skip_to_end_of_block_or_statement (parser);
    3479         1948 : }
    3480              : 
    3481              : /* Parse a static assertion (C11 6.7.10), without the trailing
    3482              :    semicolon.
    3483              : 
    3484              :    static_assert-declaration-no-semi:
    3485              :      _Static_assert ( constant-expression , string-literal )
    3486              : 
    3487              :    C23:
    3488              :    static_assert-declaration-no-semi:
    3489              :      _Static_assert ( constant-expression )
    3490              : */
    3491              : 
    3492              : static void
    3493         2133 : c_parser_static_assert_declaration_no_semi (c_parser *parser)
    3494              : {
    3495         2133 :   location_t assert_loc, value_loc;
    3496         2133 :   tree value;
    3497         2133 :   tree string = NULL_TREE;
    3498              : 
    3499         2133 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT));
    3500         2133 :   tree spelling = c_parser_peek_token (parser)->value;
    3501         2133 :   assert_loc = c_parser_peek_token (parser)->location;
    3502         2133 :   if (flag_isoc99)
    3503         2129 :     pedwarn_c99 (assert_loc, OPT_Wpedantic,
    3504              :                  "ISO C99 does not support %qE", spelling);
    3505              :   else
    3506            4 :     pedwarn_c99 (assert_loc, OPT_Wpedantic,
    3507              :                  "ISO C90 does not support %qE", spelling);
    3508         2133 :   c_parser_consume_token (parser);
    3509         2133 :   matching_parens parens;
    3510         2133 :   if (!parens.require_open (parser))
    3511           15 :     return;
    3512         2132 :   location_t value_tok_loc = c_parser_peek_token (parser)->location;
    3513         2132 :   value = convert_lvalue_to_rvalue (value_tok_loc,
    3514              :                                     c_parser_expr_no_commas (parser, NULL),
    3515              :                                     true, true).value;
    3516         2132 :   value_loc = EXPR_LOC_OR_LOC (value, value_tok_loc);
    3517         2132 :   if (c_parser_next_token_is (parser, CPP_COMMA))
    3518              :     {
    3519         1584 :       c_parser_consume_token (parser);
    3520         1584 :       switch (c_parser_peek_token (parser)->type)
    3521              :         {
    3522         1581 :         case CPP_STRING:
    3523         1581 :         case CPP_STRING16:
    3524         1581 :         case CPP_STRING32:
    3525         1581 :         case CPP_WSTRING:
    3526         1581 :         case CPP_UTF8STRING:
    3527         1581 :           string = c_parser_string_literal (parser, false, true).value;
    3528         1581 :           break;
    3529            3 :         default:
    3530            3 :           c_parser_error (parser, "expected string literal");
    3531            3 :           return;
    3532              :         }
    3533              :     }
    3534          548 :   else if (flag_isoc11)
    3535              :     /* If pedantic for pre-C11, the use of _Static_assert itself will
    3536              :        have been diagnosed, so do not also diagnose the use of this
    3537              :        new C23 feature of _Static_assert.  */
    3538          546 :     pedwarn_c11 (assert_loc, OPT_Wpedantic,
    3539              :                  "ISO C11 does not support omitting the string in "
    3540              :                  "%qE", spelling);
    3541         2129 :   parens.require_close (parser);
    3542              : 
    3543         2129 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (value)))
    3544              :     {
    3545            5 :       error_at (value_loc, "expression in static assertion is not an integer");
    3546            5 :       return;
    3547              :     }
    3548         2124 :   if (TREE_CODE (value) != INTEGER_CST)
    3549              :     {
    3550           12 :       value = c_fully_fold (value, false, NULL);
    3551              :       /* Strip no-op conversions.  */
    3552           24 :       STRIP_TYPE_NOPS (value);
    3553           12 :       if (TREE_CODE (value) == INTEGER_CST)
    3554            6 :         pedwarn (value_loc, OPT_Wpedantic, "expression in static assertion "
    3555              :                  "is not an integer constant expression");
    3556              :     }
    3557         2124 :   if (TREE_CODE (value) != INTEGER_CST)
    3558              :     {
    3559            6 :       error_at (value_loc, "expression in static assertion is not constant");
    3560            6 :       return;
    3561              :     }
    3562         2118 :   constant_expression_warning (value);
    3563         2118 :   if (integer_zerop (value))
    3564              :     {
    3565           41 :       if (string)
    3566           22 :         error_at (assert_loc, "static assertion failed: %E", string);
    3567              :       else
    3568           19 :         error_at (assert_loc, "static assertion failed");
    3569              :     }
    3570              : }
    3571              : 
    3572              : /* Parse some declaration specifiers (possibly none) (C90 6.5, C99
    3573              :    6.7, C11 6.7), adding them to SPECS (which may already include some).
    3574              :    Storage class specifiers are accepted iff SCSPEC_OK; type
    3575              :    specifiers are accepted iff TYPESPEC_OK; alignment specifiers are
    3576              :    accepted iff ALIGNSPEC_OK; gnu-attributes are accepted at the start
    3577              :    iff START_ATTR_OK; __auto_type is accepted iff AUTO_TYPE_OK.  In
    3578              :    addition to the syntax shown, standard attributes are accepted at
    3579              :    the start iff START_STD_ATTR_OK and at the end iff END_STD_ATTR_OK;
    3580              :    unlike gnu-attributes, they are not accepted in the middle of the
    3581              :    list.  (This combines various different syntax productions in the C
    3582              :    standard, and in some cases gnu-attributes and standard attributes
    3583              :    at the start may already have been parsed before this function is
    3584              :    called.)
    3585              : 
    3586              :    declaration-specifiers:
    3587              :      storage-class-specifier declaration-specifiers[opt]
    3588              :      type-specifier declaration-specifiers[opt]
    3589              :      type-qualifier declaration-specifiers[opt]
    3590              :      function-specifier declaration-specifiers[opt]
    3591              :      alignment-specifier declaration-specifiers[opt]
    3592              : 
    3593              :    Function specifiers (inline) are from C99, and are currently
    3594              :    handled as storage class specifiers, as is __thread.  Alignment
    3595              :    specifiers are from C11.
    3596              : 
    3597              :    C90 6.5.1, C99 6.7.1, C11 6.7.1:
    3598              :    storage-class-specifier:
    3599              :      typedef
    3600              :      extern
    3601              :      static
    3602              :      auto
    3603              :      register
    3604              :      _Thread_local
    3605              : 
    3606              :    (_Thread_local is new in C11.)
    3607              : 
    3608              :    C99 6.7.4, C11 6.7.4:
    3609              :    function-specifier:
    3610              :      inline
    3611              :      _Noreturn
    3612              : 
    3613              :    (_Noreturn is new in C11.)
    3614              : 
    3615              :    C90 6.5.2, C99 6.7.2, C11 6.7.2:
    3616              :    type-specifier:
    3617              :      void
    3618              :      char
    3619              :      short
    3620              :      int
    3621              :      long
    3622              :      float
    3623              :      double
    3624              :      signed
    3625              :      unsigned
    3626              :      _Bool
    3627              :      _Complex
    3628              :      [_Imaginary removed in C99 TC2]
    3629              :      _BitInt ( constant-expression )
    3630              :      struct-or-union-specifier
    3631              :      enum-specifier
    3632              :      typedef-name
    3633              :      atomic-type-specifier
    3634              : 
    3635              :    (_Bool and _Complex are new in C99.)
    3636              :    (atomic-type-specifier is new in C11.)
    3637              :    (_BitInt is new in C23.)
    3638              : 
    3639              :    C90 6.5.3, C99 6.7.3, C11 6.7.3:
    3640              : 
    3641              :    type-qualifier:
    3642              :      const
    3643              :      restrict
    3644              :      volatile
    3645              :      address-space-qualifier
    3646              :      _Atomic
    3647              : 
    3648              :    (restrict is new in C99.)
    3649              :    (_Atomic is new in C11.)
    3650              : 
    3651              :    GNU extensions:
    3652              : 
    3653              :    declaration-specifiers:
    3654              :      gnu-attributes declaration-specifiers[opt]
    3655              : 
    3656              :    type-qualifier:
    3657              :      address-space
    3658              : 
    3659              :    address-space:
    3660              :      identifier recognized by the target
    3661              : 
    3662              :    storage-class-specifier:
    3663              :      __thread
    3664              : 
    3665              :    type-specifier:
    3666              :      typeof-specifier
    3667              :      __auto_type
    3668              :      __intN
    3669              :      _Decimal32
    3670              :      _Decimal64
    3671              :      _Decimal128
    3672              :      _Fract
    3673              :      _Accum
    3674              :      _Sat
    3675              : 
    3676              :   (_Fract, _Accum, and _Sat are new from ISO/IEC DTR 18037:
    3677              :    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf)
    3678              : 
    3679              :    atomic-type-specifier
    3680              :     _Atomic ( type-name )
    3681              : 
    3682              :    Objective-C:
    3683              : 
    3684              :    type-specifier:
    3685              :      class-name objc-protocol-refs[opt]
    3686              :      typedef-name objc-protocol-refs
    3687              :      objc-protocol-refs
    3688              : */
    3689              : 
    3690              : void
    3691    333052723 : c_parser_declspecs (c_parser *parser, struct c_declspecs *specs,
    3692              :                     bool scspec_ok, bool typespec_ok, bool start_attr_ok,
    3693              :                     bool alignspec_ok, bool auto_type_ok,
    3694              :                     bool start_std_attr_ok, bool end_std_attr_ok,
    3695              :                     enum c_lookahead_kind la)
    3696              : {
    3697    333052723 :   bool attrs_ok = start_attr_ok;
    3698    333052723 :   bool seen_type = specs->typespec_kind != ctsk_none;
    3699              : 
    3700    333052723 :   if (!typespec_ok)
    3701     19362703 :     gcc_assert (la == cla_prefer_id);
    3702              : 
    3703    333052723 :   if (start_std_attr_ok
    3704    333052723 :       && c_parser_nth_token_starts_std_attributes (parser, 1))
    3705              :     {
    3706          640 :       gcc_assert (!specs->non_std_attrs_seen_p);
    3707          640 :       location_t loc = c_parser_peek_token (parser)->location;
    3708          640 :       tree attrs = c_parser_std_attribute_specifier_sequence (parser);
    3709          640 :       declspecs_add_attrs (loc, specs, attrs);
    3710          640 :       specs->non_std_attrs_seen_p = false;
    3711              :     }
    3712              : 
    3713    806973348 :   while (c_parser_next_token_is (parser, CPP_NAME)
    3714    374152998 :          || c_parser_next_token_is (parser, CPP_KEYWORD)
    3715    952725134 :          || (c_dialect_objc () && c_parser_next_token_is (parser, CPP_LESS)))
    3716              :     {
    3717    661221562 :       struct c_typespec t;
    3718    661221562 :       tree attrs;
    3719    661221562 :       tree align;
    3720    661221562 :       location_t loc = c_parser_peek_token (parser)->location;
    3721              : 
    3722              :       /* If we cannot accept a type, exit if the next token must start
    3723              :          one.  Also, if we already have seen a tagged definition,
    3724              :          a typename would be an error anyway and likely the user
    3725              :          has simply forgotten a semicolon, so we exit.  */
    3726    645178964 :       if ((!typespec_ok || specs->typespec_kind == ctsk_tagdef)
    3727     16973602 :           && c_parser_next_tokens_start_typename (parser, la)
    3728      3818706 :           && !c_parser_next_token_is_qualifier (parser)
    3729    661221689 :           && !c_parser_next_token_is_keyword (parser, RID_ALIGNAS))
    3730              :         break;
    3731              : 
    3732    661221444 :       if (c_parser_next_token_is (parser, CPP_NAME))
    3733              :         {
    3734    432820244 :           c_token *name_token = c_parser_peek_token (parser);
    3735    432820244 :           tree value = name_token->value;
    3736    432820244 :           c_id_kind kind = name_token->id_kind;
    3737              : 
    3738    432820244 :           if (kind == C_ID_ADDRSPACE)
    3739              :             {
    3740          177 :               addr_space_t as
    3741          177 :                 = name_token->keyword - RID_FIRST_ADDR_SPACE;
    3742          177 :               declspecs_add_addrspace (name_token->location, specs, as);
    3743          177 :               c_parser_consume_token (parser);
    3744          177 :               attrs_ok = true;
    3745    245522037 :               continue;
    3746          177 :             }
    3747              : 
    3748    432820067 :           gcc_assert (!c_parser_next_token_is_qualifier (parser));
    3749              : 
    3750              :           /* If we cannot accept a type, and the next token must start one,
    3751              :              exit.  Do the same if we already have seen a tagged definition,
    3752              :              since it would be an error anyway and likely the user has simply
    3753              :              forgotten a semicolon.  */
    3754    432820067 :           if (seen_type || !c_parser_next_tokens_start_typename (parser, la))
    3755              :             break;
    3756              : 
    3757              :           /* Now at an unknown typename (C_ID_ID), a C_ID_TYPENAME or
    3758              :              a C_ID_CLASSNAME.  */
    3759    245521860 :           c_parser_consume_token (parser);
    3760    245521860 :           seen_type = true;
    3761    245521860 :           attrs_ok = true;
    3762    245521860 :           if (kind == C_ID_ID)
    3763              :             {
    3764           51 :               auto_diagnostic_group d;
    3765           51 :               name_hint hint = lookup_name_fuzzy (value, FUZZY_LOOKUP_TYPENAME,
    3766           51 :                                                   loc);
    3767           51 :               if (const char *suggestion = hint.suggestion ())
    3768              :                 {
    3769            2 :                   gcc_rich_location richloc (loc);
    3770            2 :                   richloc.add_fixit_replace (suggestion);
    3771            2 :                   error_at (&richloc,
    3772              :                             "unknown type name %qE; did you mean %qs?",
    3773              :                             value, suggestion);
    3774            2 :                 }
    3775              :               else
    3776           49 :                 error_at (loc, "unknown type name %qE", value);
    3777           51 :               t.kind = ctsk_typedef;
    3778           51 :               t.spec = error_mark_node;
    3779           51 :             }
    3780    245521809 :           else if (kind == C_ID_TYPENAME
    3781    245521809 :                    && (!c_dialect_objc ()
    3782            0 :                        || c_parser_next_token_is_not (parser, CPP_LESS)))
    3783              :             {
    3784    245521809 :               t.kind = ctsk_typedef;
    3785              :               /* For a typedef name, record the meaning, not the name.
    3786              :                  In case of 'foo foo, bar;'.  */
    3787    245521809 :               t.spec = lookup_name (value);
    3788              :             }
    3789              :           else
    3790              :             {
    3791            0 :               tree proto = NULL_TREE;
    3792            0 :               gcc_assert (c_dialect_objc ());
    3793            0 :               t.kind = ctsk_objc;
    3794            0 :               if (c_parser_next_token_is (parser, CPP_LESS))
    3795            0 :                 proto = c_parser_objc_protocol_refs (parser);
    3796            0 :               t.spec = objc_get_protocol_qualified_type (value, proto);
    3797              :             }
    3798    245521860 :           t.expr = NULL_TREE;
    3799    245521860 :           t.expr_const_operands = true;
    3800    245521860 :           t.has_enum_type_specifier = false;
    3801    245521860 :           declspecs_add_type (name_token->location, specs, t);
    3802    245521860 :           continue;
    3803    245521860 :         }
    3804    228401200 :       if (c_parser_next_token_is (parser, CPP_LESS))
    3805              :         {
    3806              :           /* Make "<SomeProtocol>" equivalent to "id <SomeProtocol>" -
    3807              :              nisse@lysator.liu.se.  */
    3808            0 :           tree proto;
    3809            0 :           gcc_assert (c_dialect_objc ());
    3810            0 :           if (!typespec_ok || seen_type)
    3811              :             break;
    3812            0 :           proto = c_parser_objc_protocol_refs (parser);
    3813            0 :           t.kind = ctsk_objc;
    3814            0 :           t.spec = objc_get_protocol_qualified_type (NULL_TREE, proto);
    3815            0 :           t.expr = NULL_TREE;
    3816            0 :           t.expr_const_operands = true;
    3817            0 :           t.has_enum_type_specifier = false;
    3818            0 :           declspecs_add_type (loc, specs, t);
    3819            0 :           continue;
    3820            0 :         }
    3821    228401200 :       gcc_assert (c_parser_next_token_is (parser, CPP_KEYWORD));
    3822    228401200 :       switch (c_parser_peek_token (parser)->keyword)
    3823              :         {
    3824     90234623 :         case RID_STATIC:
    3825     90234623 :         case RID_EXTERN:
    3826     90234623 :         case RID_REGISTER:
    3827     90234623 :         case RID_TYPEDEF:
    3828     90234623 :         case RID_INLINE:
    3829     90234623 :         case RID_NORETURN:
    3830     90234623 :         case RID_AUTO:
    3831     90234623 :         case RID_THREAD:
    3832     90234623 :         case RID_CONSTEXPR:
    3833     90234623 :           if (!scspec_ok)
    3834         2612 :             goto out;
    3835     90234490 :           attrs_ok = true;
    3836              :           /* TODO: Distinguish between function specifiers (inline, noreturn)
    3837              :              and storage class specifiers, either here or in
    3838              :              declspecs_add_scspec.  */
    3839     90234490 :           declspecs_add_scspec (loc, specs,
    3840     90234490 :                                 c_parser_peek_token (parser)->value);
    3841     90234490 :           c_parser_consume_token (parser);
    3842     90234490 :           break;
    3843         1884 :         case RID_AUTO_TYPE:
    3844         1884 :           if (!auto_type_ok)
    3845            0 :             goto out;
    3846              :           /* Fall through.  */
    3847     82410726 :         case RID_UNSIGNED:
    3848     82410726 :         case RID_LONG:
    3849     82410726 :         case RID_SHORT:
    3850     82410726 :         case RID_SIGNED:
    3851     82410726 :         case RID_COMPLEX:
    3852     82410726 :         case RID_INT:
    3853     82410726 :         case RID_CHAR:
    3854     82410726 :         case RID_FLOAT:
    3855     82410726 :         case RID_DOUBLE:
    3856     82410726 :         case RID_VOID:
    3857     82410726 :         case RID_DFLOAT32:
    3858     82410726 :         case RID_DFLOAT64:
    3859     82410726 :         case RID_DFLOAT128:
    3860     82410726 :         case RID_DFLOAT64X:
    3861     82410726 :         CASE_RID_FLOATN_NX:
    3862     82410726 :         case RID_BOOL:
    3863     82410726 :         case RID_FRACT:
    3864     82410726 :         case RID_ACCUM:
    3865     82410726 :         case RID_SAT:
    3866     82410726 :         case RID_INT_N_0:
    3867     82410726 :         case RID_INT_N_1:
    3868     82410726 :         case RID_INT_N_2:
    3869     82410726 :         case RID_INT_N_3:
    3870     82410726 :           if (!typespec_ok)
    3871            0 :             goto out;
    3872     82410726 :           attrs_ok = true;
    3873     82410726 :           seen_type = true;
    3874     82410726 :           if (c_dialect_objc ())
    3875            0 :             parser->objc_need_raw_identifier = true;
    3876     82410726 :           t.kind = ctsk_resword;
    3877     82410726 :           t.spec = c_parser_peek_token (parser)->value;
    3878     82410726 :           t.expr = NULL_TREE;
    3879     82410726 :           t.expr_const_operands = true;
    3880     82410726 :           t.has_enum_type_specifier = false;
    3881     82410726 :           declspecs_add_type (loc, specs, t);
    3882     82410726 :           c_parser_consume_token (parser);
    3883     82410726 :           break;
    3884       238421 :         case RID_ENUM:
    3885       238421 :           if (!typespec_ok)
    3886            0 :             goto out;
    3887       238421 :           attrs_ok = true;
    3888       238421 :           seen_type = true;
    3889       238421 :           t = c_parser_enum_specifier (parser);
    3890       238421 :           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
    3891       238421 :           declspecs_add_type (loc, specs, t);
    3892       238421 :           break;
    3893      2202281 :         case RID_STRUCT:
    3894      2202281 :         case RID_UNION:
    3895      2202281 :           if (!typespec_ok)
    3896            0 :             goto out;
    3897      2202281 :           attrs_ok = true;
    3898      2202281 :           seen_type = true;
    3899      2202281 :           t = c_parser_struct_or_union_specifier (parser);
    3900      2202281 :           invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec);
    3901      2202281 :           declspecs_add_type (loc, specs, t);
    3902      2202281 :           break;
    3903       819812 :         case RID_TYPEOF:
    3904       819812 :         case RID_TYPEOF_UNQUAL:
    3905              :           /* ??? The old parser rejected typeof after other type
    3906              :              specifiers, but is a syntax error the best way of
    3907              :              handling this?  */
    3908       819812 :           if (!typespec_ok || seen_type)
    3909            2 :             goto out;
    3910       819810 :           attrs_ok = true;
    3911       819810 :           seen_type = true;
    3912       819810 :           t = c_parser_typeof_specifier (parser);
    3913       819810 :           declspecs_add_type (loc, specs, t);
    3914       819810 :           break;
    3915        45651 :         case RID_BITINT:
    3916        45651 :           if (!typespec_ok)
    3917            0 :             goto out;
    3918              :           else
    3919              :             {
    3920        45651 :               attrs_ok = true;
    3921        45651 :               seen_type = true;
    3922        45651 :               t.kind = ctsk_resword;
    3923        45651 :               t.spec = c_parser_peek_token (parser)->value;
    3924        45651 :               t.expr = error_mark_node;
    3925        45651 :               t.expr_const_operands = true;
    3926        45651 :               t.has_enum_type_specifier = false;
    3927        45651 :               c_parser_consume_token (parser);
    3928        45651 :               matching_parens parens;
    3929        45651 :               if (parens.require_open (parser))
    3930              :                 {
    3931        45651 :                   c_expr expr = c_parser_expr_no_commas (parser, NULL);
    3932        45651 :                   t.expr = convert_lvalue_to_rvalue (loc, expr, true,
    3933        45651 :                                                      true).value;
    3934        45651 :                   parens.skip_until_found_close (parser);
    3935              :                 }
    3936        45651 :               declspecs_add_type (loc, specs, t);
    3937              :             }
    3938        45651 :           break;
    3939        33791 :         case RID_ATOMIC:
    3940              :           /* C parser handling of Objective-C constructs needs
    3941              :              checking for correct lvalue-to-rvalue conversions, and
    3942              :              the code in build_modify_expr handling various
    3943              :              Objective-C cases, and that in build_unary_op handling
    3944              :              Objective-C cases for increment / decrement, also needs
    3945              :              updating; uses of TYPE_MAIN_VARIANT in objc_compare_types
    3946              :              and objc_types_are_equivalent may also need updates.  */
    3947        33791 :           if (c_dialect_objc ())
    3948            0 :             sorry ("%<_Atomic%> in Objective-C");
    3949        33791 :           if (flag_isoc99)
    3950        33740 :             pedwarn_c99 (loc, OPT_Wpedantic,
    3951              :                          "ISO C99 does not support the %<_Atomic%> qualifier");
    3952              :           else
    3953           51 :             pedwarn_c99 (loc, OPT_Wpedantic,
    3954              :                          "ISO C90 does not support the %<_Atomic%> qualifier");
    3955        33791 :           attrs_ok = true;
    3956        33791 :           tree value;
    3957        33791 :           value = c_parser_peek_token (parser)->value;
    3958        33791 :           c_parser_consume_token (parser);
    3959        67372 :           if (typespec_ok && c_parser_next_token_is (parser, CPP_OPEN_PAREN))
    3960              :             {
    3961              :               /* _Atomic ( type-name ).  */
    3962        13430 :               seen_type = true;
    3963        13430 :               c_parser_consume_token (parser);
    3964        13430 :               struct c_type_name *type = c_parser_type_name (parser);
    3965        13430 :               t.kind = ctsk_typeof;
    3966        13430 :               t.spec = error_mark_node;
    3967        13430 :               t.expr = NULL_TREE;
    3968        13430 :               t.expr_const_operands = true;
    3969        13430 :               t.has_enum_type_specifier = false;
    3970        13430 :               if (type != NULL)
    3971        13429 :                 t.spec = groktypename (type, &t.expr,
    3972              :                                        &t.expr_const_operands);
    3973        13430 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    3974              :                                          "expected %<)%>");
    3975        13430 :               if (t.spec != error_mark_node)
    3976              :                 {
    3977        13429 :                   if (TREE_CODE (t.spec) == ARRAY_TYPE)
    3978            1 :                     error_at (loc, "%<_Atomic%>-qualified array type");
    3979        13428 :                   else if (TREE_CODE (t.spec) == FUNCTION_TYPE)
    3980            1 :                     error_at (loc, "%<_Atomic%>-qualified function type");
    3981        13427 :                   else if (TYPE_QUALS (t.spec) != TYPE_UNQUALIFIED)
    3982            4 :                     error_at (loc, "%<_Atomic%> applied to a qualified type");
    3983              :                   else
    3984        13423 :                     t.spec = c_build_qualified_type (t.spec, TYPE_QUAL_ATOMIC);
    3985              :                 }
    3986        13430 :               declspecs_add_type (loc, specs, t);
    3987              :             }
    3988              :           else
    3989        20361 :             declspecs_add_qual (loc, specs, value);
    3990              :           break;
    3991     16540495 :         case RID_CONST:
    3992     16540495 :         case RID_VOLATILE:
    3993     16540495 :         case RID_RESTRICT:
    3994     16540495 :           attrs_ok = true;
    3995     16540495 :           declspecs_add_qual (loc, specs, c_parser_peek_token (parser)->value);
    3996     16540495 :           c_parser_consume_token (parser);
    3997     16540495 :           break;
    3998     35872188 :         case RID_ATTRIBUTE:
    3999     35872188 :           if (!attrs_ok)
    4000            0 :             goto out;
    4001     35872188 :           attrs = c_parser_gnu_attributes (parser);
    4002     35872188 :           declspecs_add_attrs (loc, specs, attrs);
    4003     35872188 :           break;
    4004          218 :         case RID_ALIGNAS:
    4005          218 :           if (!alignspec_ok)
    4006           16 :             goto out;
    4007          202 :           align = c_parser_alignas_specifier (parser);
    4008          202 :           declspecs_add_alignas (loc, specs, align);
    4009          202 :           break;
    4010          508 :         case RID_GIMPLE:
    4011          508 :           if (! flag_gimple)
    4012            0 :             error_at (loc, "%<__GIMPLE%> only valid with %<-fgimple%>");
    4013          508 :           c_parser_consume_token (parser);
    4014          508 :           specs->declspec_il = cdil_gimple;
    4015          508 :           specs->locations[cdw_gimple] = loc;
    4016          508 :           c_parser_gimple_or_rtl_pass_list (parser, specs);
    4017          508 :           break;
    4018           25 :         case RID_RTL:
    4019           25 :           c_parser_consume_token (parser);
    4020           25 :           specs->declspec_il = cdil_rtl;
    4021           25 :           specs->locations[cdw_rtl] = loc;
    4022           25 :           c_parser_gimple_or_rtl_pass_list (parser, specs);
    4023           25 :           break;
    4024         2461 :         default:
    4025         2461 :           goto out;
    4026              :         }
    4027              :     }
    4028    333052723 :  out:
    4029    333052723 :   if (end_std_attr_ok
    4030    333052723 :       && c_parser_nth_token_starts_std_attributes (parser, 1))
    4031          117 :     specs->postfix_attrs = c_parser_std_attribute_specifier_sequence (parser);
    4032    333052723 : }
    4033              : 
    4034              : /* Complain about a non-CPP_NAME within an enumerator list.  */
    4035              : 
    4036              : static void
    4037           11 : report_bad_enum_name (c_parser *parser)
    4038              : {
    4039           11 :   if (!parser->error)
    4040              :     {
    4041           11 :       c_token *token = c_parser_peek_token (parser);
    4042           11 :       switch (token->type)
    4043              :         {
    4044              :         default:
    4045              :           break;
    4046            6 :         case CPP_CLOSE_BRACE:
    4047              :           /* Give a nicer error for "enum {}".  */
    4048            6 :           error_at (token->location,
    4049              :                     "empty enum is invalid");
    4050            6 :           parser->error = true;
    4051            6 :           return;
    4052            3 :         case CPP_KEYWORD:
    4053              :           /* Give a nicer error for attempts to use "true" and "false"
    4054              :              in enums with C23 onwards.  */
    4055            3 :           if (token->keyword == RID_FALSE
    4056            2 :               || token->keyword == RID_TRUE)
    4057              :             {
    4058            2 :               auto_diagnostic_group d;
    4059            4 :               error_at (token->location,
    4060              :                         "cannot use keyword %qs as enumeration constant",
    4061            2 :                         IDENTIFIER_POINTER (token->value));
    4062            2 :               add_note_about_new_keyword (token->location,
    4063              :                                           token->value);
    4064            2 :               parser->error = true;
    4065            2 :               return;
    4066            2 :             }
    4067              :           break;
    4068              :         }
    4069              :     }
    4070              : 
    4071              :   /* Otherwise, a more generic error message.  */
    4072            3 :   c_parser_error (parser, "expected identifier");
    4073              : }
    4074              : 
    4075              : /* Parse an enum specifier (C90 6.5.2.2, C99 6.7.2.2, C11 6.7.2.2).
    4076              : 
    4077              :    enum-specifier:
    4078              :      enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
    4079              :        { enumerator-list } gnu-attributes[opt]
    4080              :      enum gnu-attributes[opt] identifier[opt] enum-type-specifier[opt]
    4081              :        { enumerator-list , } gnu-attributes[opt] enum-type-specifier[opt]
    4082              :      enum gnu-attributes[opt] identifier
    4083              : 
    4084              :    The form with trailing comma is new in C99; enum-type-specifiers
    4085              :    are new in C23.  The forms with gnu-attributes are GNU extensions.
    4086              :    In GNU C, we accept any expression without commas in the syntax
    4087              :    (assignment expressions, not just conditional expressions);
    4088              :    assignment expressions will be diagnosed as non-constant.
    4089              : 
    4090              :    enum-type-specifier:
    4091              :      : specifier-qualifier-list
    4092              : 
    4093              :    enumerator-list:
    4094              :      enumerator
    4095              :      enumerator-list , enumerator
    4096              : 
    4097              :    enumerator:
    4098              :      enumeration-constant attribute-specifier-sequence[opt]
    4099              :      enumeration-constant attribute-specifier-sequence[opt]
    4100              :        = constant-expression
    4101              : 
    4102              :    GNU Extensions:
    4103              : 
    4104              :    enumerator:
    4105              :      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
    4106              :      enumeration-constant attribute-specifier-sequence[opt] gnu-attributes[opt]
    4107              :        = constant-expression
    4108              : 
    4109              : */
    4110              : 
    4111              : static struct c_typespec
    4112       238421 : c_parser_enum_specifier (c_parser *parser)
    4113              : {
    4114       238421 :   struct c_typespec ret;
    4115       238421 :   bool have_std_attrs;
    4116       238421 :   bool potential_nesting_p = false;
    4117       238421 :   tree std_attrs = NULL_TREE;
    4118       238421 :   tree attrs;
    4119       238421 :   tree ident = NULL_TREE;
    4120       238421 :   tree fixed_underlying_type = NULL_TREE;
    4121       238421 :   location_t enum_loc;
    4122       238421 :   location_t ident_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
    4123       238421 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ENUM));
    4124       238421 :   c_parser_consume_token (parser);
    4125       238421 :   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
    4126       238421 :   if (have_std_attrs)
    4127           14 :     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    4128       238421 :   attrs = c_parser_gnu_attributes (parser);
    4129       238421 :   enum_loc = c_parser_peek_token (parser)->location;
    4130              :   /* Set the location in case we create a decl now.  */
    4131       238421 :   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
    4132       238421 :   if (c_parser_next_token_is (parser, CPP_NAME))
    4133              :     {
    4134       129728 :       ident = c_parser_peek_token (parser)->value;
    4135       129728 :       ident_loc = c_parser_peek_token (parser)->location;
    4136       129728 :       enum_loc = ident_loc;
    4137       129728 :       c_parser_consume_token (parser);
    4138              :     }
    4139       238421 :   if (c_parser_next_token_is (parser, CPP_COLON)
    4140              :       /* Distinguish an enum-type-specifier from a bit-field
    4141              :          declaration of the form "enum e : constant-expression;".  */
    4142       238421 :       && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
    4143              :     {
    4144          169 :       pedwarn_c11 (enum_loc, OPT_Wpedantic,
    4145              :                    "ISO C does not support specifying %<enum%> underlying "
    4146              :                    "types before C23");
    4147          169 :       if (ident)
    4148              :         {
    4149              :           /* The tag is in scope during the enum-type-specifier (which
    4150              :              may refer to the tag inside typeof).  */
    4151          165 :           ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident,
    4152              :                                  have_std_attrs, std_attrs, true);
    4153          165 :           if (!ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec))
    4154            3 :             error_at (enum_loc, "%<enum%> declared both with and without "
    4155              :                       "fixed underlying type");
    4156          165 :           potential_nesting_p = NULL_TREE == TYPE_VALUES (ret.spec);
    4157              :         }
    4158              :       else
    4159              :         {
    4160              :           /* There must be an enum definition, so this initialization
    4161              :              (to avoid possible warnings about uninitialized data)
    4162              :              will be replaced later (either with the results of that
    4163              :              definition, or with the results of error handling for the
    4164              :              case of no tag and no definition).  */
    4165            4 :           ret.spec = NULL_TREE;
    4166            4 :           ret.kind = ctsk_tagdef;
    4167            4 :           ret.expr = NULL_TREE;
    4168            4 :           ret.expr_const_operands = true;
    4169            4 :           ret.has_enum_type_specifier = true;
    4170              :         }
    4171          169 :       c_parser_consume_token (parser);
    4172          169 :       struct c_declspecs *specs = build_null_declspecs ();
    4173          169 :       c_parser_declspecs (parser, specs, false, true, false, false, false,
    4174              :                           false, true, cla_prefer_id);
    4175          169 :       finish_declspecs (specs);
    4176          169 :       if (specs->default_int_p)
    4177            1 :         error_at (enum_loc, "no %<enum%> underlying type specified");
    4178          168 :       else if (TREE_CODE (specs->type) != INTEGER_TYPE
    4179          168 :                && TREE_CODE (specs->type) != BOOLEAN_TYPE)
    4180              :         {
    4181            9 :           error_at (enum_loc, "invalid %<enum%> underlying type");
    4182            9 :           specs->type = integer_type_node;
    4183              :         }
    4184          159 :       else if (specs->restrict_p)
    4185            1 :         error_at (enum_loc, "invalid use of %<restrict%>");
    4186          169 :       fixed_underlying_type = TYPE_MAIN_VARIANT (specs->type);
    4187          169 :       if (ident)
    4188              :         {
    4189              :           /* The type specified must be consistent with any previously
    4190              :              specified underlying type.  If this is a newly declared
    4191              :              type, it is now a complete type.  */
    4192          165 :           if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
    4193          165 :               && ENUM_UNDERLYING_TYPE (ret.spec) == NULL_TREE)
    4194              :             {
    4195          432 :               TYPE_MIN_VALUE (ret.spec) =
    4196          144 :                 TYPE_MIN_VALUE (fixed_underlying_type);
    4197          432 :               TYPE_MAX_VALUE (ret.spec) =
    4198          144 :                 TYPE_MAX_VALUE (fixed_underlying_type);
    4199          144 :               TYPE_UNSIGNED (ret.spec) = TYPE_UNSIGNED (fixed_underlying_type);
    4200          144 :               SET_TYPE_ALIGN (ret.spec, TYPE_ALIGN (fixed_underlying_type));
    4201          144 :               TYPE_SIZE (ret.spec) = NULL_TREE;
    4202          144 :               TYPE_PRECISION (ret.spec) =
    4203          144 :                 TYPE_PRECISION (fixed_underlying_type);
    4204          144 :               ENUM_UNDERLYING_TYPE (ret.spec) = fixed_underlying_type;
    4205          144 :               layout_type (ret.spec);
    4206              :             }
    4207           21 :           else if (ENUM_FIXED_UNDERLYING_TYPE_P (ret.spec)
    4208           37 :                    && !comptypes (fixed_underlying_type,
    4209           16 :                                   ENUM_UNDERLYING_TYPE (ret.spec)))
    4210              :             {
    4211            3 :               error_at (enum_loc, "%<enum%> underlying type incompatible with "
    4212              :                         "previous declaration");
    4213            3 :               fixed_underlying_type = ENUM_UNDERLYING_TYPE (ret.spec);
    4214              :             }
    4215              :         }
    4216              :     }
    4217       238421 :   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    4218              :     {
    4219              :       /* Parse an enum definition.  */
    4220       180381 :       struct c_enum_contents the_enum;
    4221       180381 :       tree type;
    4222       180381 :       tree postfix_attrs;
    4223              :       /* We chain the enumerators in reverse order, then put them in
    4224              :          forward order at the end.  */
    4225       180381 :       tree values;
    4226       180381 :       timevar_push (TV_PARSE_ENUM);
    4227       180381 :       type = start_enum (enum_loc, &the_enum, ident, fixed_underlying_type,
    4228              :                          potential_nesting_p);
    4229       180381 :       values = NULL_TREE;
    4230       180381 :       c_parser_consume_token (parser);
    4231      5709584 :       while (true)
    4232              :         {
    4233      5709584 :           tree enum_id;
    4234      5709584 :           tree enum_value;
    4235      5709584 :           tree enum_decl;
    4236      5709584 :           bool seen_comma;
    4237      5709584 :           c_token *token;
    4238      5709584 :           location_t comma_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
    4239      5709584 :           location_t decl_loc, value_loc;
    4240      5709584 :           if (c_parser_next_token_is_not (parser, CPP_NAME))
    4241              :             {
    4242           11 :               report_bad_enum_name (parser);
    4243           11 :               c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
    4244           11 :               values = error_mark_node;
    4245           11 :               break;
    4246              :             }
    4247      5709573 :           token = c_parser_peek_token (parser);
    4248      5709573 :           enum_id = token->value;
    4249              :           /* Set the location in case we create a decl now.  */
    4250      5709573 :           c_parser_set_source_position_from_token (token);
    4251      5709573 :           decl_loc = value_loc = token->location;
    4252      5709573 :           c_parser_consume_token (parser);
    4253              :           /* Parse any specified attributes.  */
    4254      5709573 :           tree std_attrs = NULL_TREE;
    4255      5709573 :           if (c_parser_nth_token_starts_std_attributes (parser, 1))
    4256           12 :             std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    4257      5709573 :           tree enum_attrs = chainon (std_attrs,
    4258              :                                      c_parser_gnu_attributes (parser));
    4259      5709573 :           if (c_parser_next_token_is (parser, CPP_EQ))
    4260              :             {
    4261      3549731 :               c_parser_consume_token (parser);
    4262      3549731 :               value_loc = c_parser_peek_token (parser)->location;
    4263      3549731 :               enum_value = convert_lvalue_to_rvalue (value_loc,
    4264              :                                                      (c_parser_expr_no_commas
    4265              :                                                       (parser, NULL)),
    4266              :                                                      true, true).value;
    4267              :             }
    4268              :           else
    4269              :             enum_value = NULL_TREE;
    4270      5709573 :           enum_decl = build_enumerator (decl_loc, value_loc,
    4271              :                                         &the_enum, enum_id, enum_value);
    4272      5709573 :           if (enum_attrs)
    4273         3324 :             decl_attributes (&TREE_PURPOSE (enum_decl), enum_attrs, 0);
    4274      5709573 :           TREE_CHAIN (enum_decl) = values;
    4275      5709573 :           values = enum_decl;
    4276      5709573 :           seen_comma = false;
    4277      5709573 :           if (c_parser_next_token_is (parser, CPP_COMMA))
    4278              :             {
    4279      5549826 :               comma_loc = c_parser_peek_token (parser)->location;
    4280      5549826 :               seen_comma = true;
    4281      5549826 :               c_parser_consume_token (parser);
    4282              :             }
    4283      5709573 :           if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    4284              :             {
    4285       180355 :               if (seen_comma)
    4286        20623 :                 pedwarn_c90 (comma_loc, OPT_Wpedantic,
    4287              :                              "comma at end of enumerator list");
    4288       180355 :               c_parser_consume_token (parser);
    4289       180355 :               break;
    4290              :             }
    4291      5529218 :           if (!seen_comma)
    4292              :             {
    4293           15 :               c_parser_error (parser, "expected %<,%> or %<}%>");
    4294           15 :               c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
    4295           15 :               values = error_mark_node;
    4296           15 :               break;
    4297              :             }
    4298              :         }
    4299       180381 :       postfix_attrs = c_parser_gnu_attributes (parser);
    4300       180381 :       ret.spec = finish_enum (type, nreverse (values),
    4301              :                               chainon (std_attrs,
    4302              :                                        chainon (attrs, postfix_attrs)));
    4303       180381 :       ret.kind = ctsk_tagdef;
    4304       180381 :       ret.expr = NULL_TREE;
    4305       180381 :       ret.expr_const_operands = true;
    4306       180381 :       ret.has_enum_type_specifier = fixed_underlying_type != NULL_TREE;
    4307       180381 :       timevar_pop (TV_PARSE_ENUM);
    4308       180381 :       return ret;
    4309              :     }
    4310        58040 :   else if (!ident)
    4311              :     {
    4312            1 :       c_parser_error (parser, "expected %<{%>");
    4313            1 :       ret.spec = error_mark_node;
    4314            1 :       ret.kind = ctsk_tagref;
    4315            1 :       ret.expr = NULL_TREE;
    4316            1 :       ret.expr_const_operands = true;
    4317            1 :       ret.has_enum_type_specifier = false;
    4318            1 :       return ret;
    4319              :     }
    4320              :   /* Attributes may only appear when the members are defined or in
    4321              :      certain forward declarations (treat enum forward declarations in
    4322              :      GNU C analogously to struct and union forward declarations in
    4323              :      standard C).  */
    4324        58040 :   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
    4325            1 :     c_parser_error (parser, "expected %<;%>");
    4326        58039 :   if (fixed_underlying_type == NULL_TREE)
    4327              :     {
    4328        57990 :       ret = parser_xref_tag (ident_loc, ENUMERAL_TYPE, ident, have_std_attrs,
    4329              :                              std_attrs, false);
    4330              :       /* In ISO C, enumerated types without a fixed underlying type
    4331              :          can be referred to only if already defined.  */
    4332        57990 :       if (pedantic && !COMPLETE_TYPE_P (ret.spec))
    4333              :         {
    4334           11 :           gcc_assert (ident);
    4335           11 :           pedwarn (enum_loc, OPT_Wpedantic,
    4336              :                    "ISO C forbids forward references to %<enum%> types");
    4337              :         }
    4338              :     }
    4339              :   return ret;
    4340              : }
    4341              : 
    4342              : /* Parse a struct or union specifier (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1).
    4343              : 
    4344              :    struct-or-union-specifier:
    4345              :      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
    4346              :        identifier[opt] { struct-contents } gnu-attributes[opt]
    4347              :      struct-or-union attribute-specifier-sequence[opt] gnu-attributes[opt]
    4348              :        identifier
    4349              : 
    4350              :    struct-contents:
    4351              :      struct-declaration-list
    4352              : 
    4353              :    struct-declaration-list:
    4354              :      struct-declaration ;
    4355              :      struct-declaration-list struct-declaration ;
    4356              : 
    4357              :    GNU extensions:
    4358              : 
    4359              :    struct-contents:
    4360              :      empty
    4361              :      struct-declaration
    4362              :      struct-declaration-list struct-declaration
    4363              : 
    4364              :    struct-declaration-list:
    4365              :      struct-declaration-list ;
    4366              :      ;
    4367              : 
    4368              :    (Note that in the syntax here, unlike that in ISO C, the semicolons
    4369              :    are included here rather than in struct-declaration, in order to
    4370              :    describe the syntax with extra semicolons and missing semicolon at
    4371              :    end.)
    4372              : 
    4373              :    Objective-C:
    4374              : 
    4375              :    struct-declaration-list:
    4376              :      @defs ( class-name )
    4377              : 
    4378              :    (Note this does not include a trailing semicolon, but can be
    4379              :    followed by further declarations, and gets a pedwarn-if-pedantic
    4380              :    when followed by a semicolon.)  */
    4381              : 
    4382              : static struct c_typespec
    4383      2202281 : c_parser_struct_or_union_specifier (c_parser *parser)
    4384              : {
    4385      2202281 :   struct c_typespec ret;
    4386      2202281 :   bool have_std_attrs;
    4387      2202281 :   tree std_attrs = NULL_TREE;
    4388      2202281 :   tree attrs;
    4389      2202281 :   tree ident = NULL_TREE;
    4390      2202281 :   location_t struct_loc;
    4391      2202281 :   location_t ident_loc = UNKNOWN_LOCATION;
    4392      2202281 :   enum tree_code code;
    4393      2202281 :   switch (c_parser_peek_token (parser)->keyword)
    4394              :     {
    4395              :     case RID_STRUCT:
    4396              :       code = RECORD_TYPE;
    4397              :       break;
    4398       417599 :     case RID_UNION:
    4399       417599 :       code = UNION_TYPE;
    4400       417599 :       break;
    4401            0 :     default:
    4402            0 :       gcc_unreachable ();
    4403              :     }
    4404      2202281 :   struct_loc = c_parser_peek_token (parser)->location;
    4405      2202281 :   c_parser_consume_token (parser);
    4406      2202281 :   have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
    4407      2202281 :   if (have_std_attrs)
    4408           34 :     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    4409      2202281 :   attrs = c_parser_gnu_attributes (parser);
    4410              : 
    4411              :   /* Set the location in case we create a decl now.  */
    4412      2202281 :   c_parser_set_source_position_from_token (c_parser_peek_token (parser));
    4413              : 
    4414      2202281 :   if (c_parser_next_token_is (parser, CPP_NAME))
    4415              :     {
    4416      1509023 :       ident = c_parser_peek_token (parser)->value;
    4417      1509023 :       ident_loc = c_parser_peek_token (parser)->location;
    4418      1509023 :       struct_loc = ident_loc;
    4419      1509023 :       c_parser_consume_token (parser);
    4420              :     }
    4421      2202281 :   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    4422              :     {
    4423              :       /* Parse a struct or union definition.  Start the scope of the
    4424              :          tag before parsing components.  */
    4425      1177497 :       class c_struct_parse_info *struct_info;
    4426      1177497 :       tree type = start_struct (struct_loc, code, ident, &struct_info);
    4427      1177497 :       tree postfix_attrs;
    4428              :       /* We chain the components in reverse order, then put them in
    4429              :          forward order at the end.  Each struct-declaration may
    4430              :          declare multiple components (comma-separated), so we must use
    4431              :          chainon to join them, although when parsing each
    4432              :          struct-declaration we can use TREE_CHAIN directly.
    4433              : 
    4434              :          The theory behind all this is that there will be more
    4435              :          semicolon separated fields than comma separated fields, and
    4436              :          so we'll be minimizing the number of node traversals required
    4437              :          by chainon.  */
    4438      1177497 :       tree contents;
    4439      1177497 :       tree expr = NULL;
    4440      1177497 :       timevar_push (TV_PARSE_STRUCT);
    4441      1177497 :       contents = NULL_TREE;
    4442      1177497 :       c_parser_consume_token (parser);
    4443              :       /* Handle the Objective-C @defs construct,
    4444              :          e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
    4445      1177497 :       if (c_parser_next_token_is_keyword (parser, RID_AT_DEFS))
    4446              :         {
    4447            0 :           tree name;
    4448            0 :           gcc_assert (c_dialect_objc ());
    4449            0 :           c_parser_consume_token (parser);
    4450            0 :           matching_parens parens;
    4451            0 :           if (!parens.require_open (parser))
    4452            0 :             goto end_at_defs;
    4453            0 :           if (c_parser_next_token_is (parser, CPP_NAME)
    4454            0 :               && c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME)
    4455              :             {
    4456            0 :               name = c_parser_peek_token (parser)->value;
    4457            0 :               c_parser_consume_token (parser);
    4458              :             }
    4459              :           else
    4460              :             {
    4461            0 :               c_parser_error (parser, "expected class name");
    4462            0 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    4463            0 :               goto end_at_defs;
    4464              :             }
    4465            0 :           parens.skip_until_found_close (parser);
    4466            0 :           contents = nreverse (objc_get_class_ivars (name));
    4467              :         }
    4468      1177497 :     end_at_defs:
    4469              :       /* Parse the struct-declarations and semicolons.  Problems with
    4470              :          semicolons are diagnosed here; empty structures are diagnosed
    4471              :          elsewhere.  */
    4472      5438530 :       while (true)
    4473              :         {
    4474      5438530 :           tree decls;
    4475              :           /* Parse any stray semicolon.  */
    4476      5438530 :           if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    4477              :             {
    4478           14 :               location_t semicolon_loc
    4479           14 :                 = c_parser_peek_token (parser)->location;
    4480           14 :               gcc_rich_location richloc (semicolon_loc);
    4481           14 :               richloc.add_fixit_remove ();
    4482           14 :               pedwarn (&richloc, OPT_Wpedantic,
    4483              :                        "extra semicolon in struct or union specified");
    4484           14 :               c_parser_consume_token (parser);
    4485           14 :               continue;
    4486           14 :             }
    4487              :           /* Stop if at the end of the struct or union contents.  */
    4488      5438516 :           if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    4489              :             {
    4490      1177488 :               c_parser_consume_token (parser);
    4491      1177488 :               break;
    4492              :             }
    4493              :           /* Accept #pragmas at struct scope.  */
    4494      4261028 :           if (c_parser_next_token_is (parser, CPP_PRAGMA))
    4495              :             {
    4496           20 :               c_parser_pragma (parser, pragma_struct, NULL, NULL_TREE);
    4497           20 :               continue;
    4498              :             }
    4499              :           /* Parse some comma-separated declarations, but not the
    4500              :              trailing semicolon if any.  */
    4501      4261008 :           decls = c_parser_struct_declaration (parser, &expr);
    4502      4261008 :           contents = chainon (decls, contents);
    4503              :           /* If no semicolon follows, either we have a parse error or
    4504              :              are at the end of the struct or union and should
    4505              :              pedwarn.  */
    4506      4261008 :           if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    4507      4260969 :             c_parser_consume_token (parser);
    4508              :           else
    4509              :             {
    4510           39 :               if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    4511           28 :                 pedwarn (c_parser_peek_token (parser)->location, 0,
    4512              :                          "no semicolon at end of struct or union");
    4513           11 :               else if (parser->error
    4514           11 :                        || !c_parser_next_token_starts_declspecs (parser))
    4515              :                 {
    4516            9 :                   c_parser_error (parser, "expected %<;%>");
    4517            9 :                   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
    4518            9 :                   break;
    4519              :                 }
    4520              : 
    4521              :               /* If we come here, we have already emitted an error
    4522              :                  for an expected `;', identifier or `(', and we also
    4523              :                  recovered already.  Go on with the next field. */
    4524              :             }
    4525              :         }
    4526      1177497 :       postfix_attrs = c_parser_gnu_attributes (parser);
    4527      1177497 :       ret.spec = finish_struct (struct_loc, type, nreverse (contents),
    4528              :                                 chainon (std_attrs,
    4529              :                                          chainon (attrs, postfix_attrs)),
    4530              :                                 struct_info, &expr);
    4531      1177497 :       ret.kind = ctsk_tagdef;
    4532      1177497 :       ret.expr = expr;
    4533      1177497 :       ret.expr_const_operands = true;
    4534      1177497 :       ret.has_enum_type_specifier = false;
    4535      1177497 :       timevar_pop (TV_PARSE_STRUCT);
    4536      1177497 :       return ret;
    4537              :     }
    4538      1024784 :   else if (!ident)
    4539              :     {
    4540           10 :       c_parser_error (parser, "expected %<{%>");
    4541           10 :       ret.spec = error_mark_node;
    4542           10 :       ret.kind = ctsk_tagref;
    4543           10 :       ret.expr = NULL_TREE;
    4544           10 :       ret.expr_const_operands = true;
    4545           10 :       ret.has_enum_type_specifier = false;
    4546           10 :       return ret;
    4547              :     }
    4548              :   /* Attributes may only appear when the members are defined or in
    4549              :      certain forward declarations.  */
    4550      1024784 :   if (have_std_attrs && c_parser_next_token_is_not (parser, CPP_SEMICOLON))
    4551            2 :     c_parser_error (parser, "expected %<;%>");
    4552              :   /* ??? Existing practice is that GNU attributes are ignored after
    4553              :      the struct or union keyword when not defining the members.  */
    4554      1024774 :   ret = parser_xref_tag (ident_loc, code, ident, have_std_attrs, std_attrs,
    4555              :                          false);
    4556      1024774 :   return ret;
    4557              : }
    4558              : 
    4559              : /* Parse a struct-declaration (C90 6.5.2.1, C99 6.7.2.1, C11 6.7.2.1),
    4560              :    *without* the trailing semicolon.
    4561              : 
    4562              :    struct-declaration:
    4563              :      attribute-specifier-sequence[opt] specifier-qualifier-list
    4564              :        attribute-specifier-sequence[opt] struct-declarator-list
    4565              :      static_assert-declaration-no-semi
    4566              : 
    4567              :    specifier-qualifier-list:
    4568              :      type-specifier specifier-qualifier-list[opt]
    4569              :      type-qualifier specifier-qualifier-list[opt]
    4570              :      alignment-specifier specifier-qualifier-list[opt]
    4571              :      gnu-attributes specifier-qualifier-list[opt]
    4572              : 
    4573              :    struct-declarator-list:
    4574              :      struct-declarator
    4575              :      struct-declarator-list , gnu-attributes[opt] struct-declarator
    4576              : 
    4577              :    struct-declarator:
    4578              :      declarator gnu-attributes[opt]
    4579              :      declarator[opt] : constant-expression gnu-attributes[opt]
    4580              : 
    4581              :    GNU extensions:
    4582              : 
    4583              :    struct-declaration:
    4584              :      __extension__ struct-declaration
    4585              :      specifier-qualifier-list
    4586              : 
    4587              :    Unlike the ISO C syntax, semicolons are handled elsewhere.  The use
    4588              :    of gnu-attributes where shown is a GNU extension.  In GNU C, we accept
    4589              :    any expression without commas in the syntax (assignment
    4590              :    expressions, not just conditional expressions); assignment
    4591              :    expressions will be diagnosed as non-constant.  */
    4592              : 
    4593              : static tree
    4594      4326250 : c_parser_struct_declaration (c_parser *parser, tree *expr)
    4595              : {
    4596      4326250 :   struct c_declspecs *specs;
    4597      4326250 :   tree prefix_attrs;
    4598      4326250 :   tree all_prefix_attrs;
    4599      4326250 :   tree decls;
    4600      4326250 :   location_t decl_loc;
    4601      4326250 :   if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
    4602              :     {
    4603        65242 :       int ext;
    4604        65242 :       tree decl;
    4605        65242 :       ext = disable_extension_diagnostics ();
    4606        65242 :       c_parser_consume_token (parser);
    4607        65242 :       decl = c_parser_struct_declaration (parser, expr);
    4608        65242 :       restore_extension_diagnostics (ext);
    4609        65242 :       return decl;
    4610              :     }
    4611      4261008 :   if (c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
    4612              :     {
    4613           17 :       c_parser_static_assert_declaration_no_semi (parser);
    4614           17 :       return NULL_TREE;
    4615              :     }
    4616      4260991 :   specs = build_null_declspecs ();
    4617      4260991 :   decl_loc = c_parser_peek_token (parser)->location;
    4618              :   /* Strictly by the standard, we shouldn't allow _Alignas here,
    4619              :      but it appears to have been intended to allow it there, so
    4620              :      we're keeping it as it is until WG14 reaches a conclusion
    4621              :      of N1731.
    4622              :      <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1731.pdf>  */
    4623      4260991 :   c_parser_declspecs (parser, specs, false, true, true,
    4624              :                       true, false, true, true, cla_nonabstract_decl);
    4625      4260991 :   if (parser->error)
    4626              :     return NULL_TREE;
    4627      4260983 :   if (!specs->declspecs_seen_p)
    4628              :     {
    4629            1 :       c_parser_error (parser, "expected specifier-qualifier-list");
    4630            1 :       return NULL_TREE;
    4631              :     }
    4632      4260982 :   finish_declspecs (specs);
    4633      4260982 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
    4634      8511057 :       || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    4635              :     {
    4636        10911 :       tree ret;
    4637        10911 :       if (specs->typespec_kind == ctsk_none)
    4638              :         {
    4639            3 :           pedwarn (decl_loc, OPT_Wpedantic,
    4640              :                    "ISO C forbids member declarations with no members");
    4641            3 :           shadow_tag_warned (specs, pedantic);
    4642            3 :           ret = NULL_TREE;
    4643              :         }
    4644              :       else
    4645              :         {
    4646              :           /* Support for unnamed structs or unions as members of
    4647              :              structs or unions (which is [a] useful and [b] supports
    4648              :              MS P-SDK).  */
    4649        10908 :           tree attrs = NULL;
    4650              : 
    4651        10908 :           ret = grokfield (c_parser_peek_token (parser)->location,
    4652              :                            build_id_declarator (NULL_TREE), specs,
    4653              :                            NULL_TREE, &attrs, expr);
    4654        10908 :           if (ret)
    4655        10879 :             decl_attributes (&ret, attrs, 0);
    4656              :         }
    4657        10911 :       return ret;
    4658              :     }
    4659              : 
    4660              :   /* Provide better error recovery.  Note that a type name here is valid,
    4661              :      and will be treated as a field name.  */
    4662      4250071 :   if (specs->typespec_kind == ctsk_tagdef
    4663       153018 :       && TREE_CODE (specs->type) != ENUMERAL_TYPE
    4664       152865 :       && c_parser_next_token_starts_declspecs (parser)
    4665      4250074 :       && !c_parser_next_token_is (parser, CPP_NAME))
    4666              :     {
    4667            2 :       c_parser_error (parser, "expected %<;%>, identifier or %<(%>");
    4668            2 :       parser->error = false;
    4669            2 :       return NULL_TREE;
    4670              :     }
    4671              : 
    4672      4250069 :   pending_xref_error ();
    4673      4250069 :   prefix_attrs = specs->attrs;
    4674      4250069 :   all_prefix_attrs = prefix_attrs;
    4675      4250069 :   specs->attrs = NULL_TREE;
    4676      4250069 :   decls = NULL_TREE;
    4677        57663 :   while (true)
    4678              :     {
    4679              :       /* Declaring one or more declarators or un-named bit-fields.  */
    4680      4307732 :       struct c_declarator *declarator;
    4681      4307732 :       bool dummy = false;
    4682      4307732 :       if (c_parser_next_token_is (parser, CPP_COLON))
    4683         9740 :         declarator = build_id_declarator (NULL_TREE);
    4684              :       else
    4685      4297992 :         declarator = c_parser_declarator (parser,
    4686      4297992 :                                           specs->typespec_kind != ctsk_none,
    4687              :                                           C_DTR_NORMAL, &dummy);
    4688      4307732 :       if (declarator == NULL)
    4689              :         {
    4690            1 :           c_parser_skip_to_end_of_block_or_statement (parser);
    4691            1 :           break;
    4692              :         }
    4693      4307731 :       if (c_parser_next_token_is (parser, CPP_COLON)
    4694      4255151 :           || c_parser_next_token_is (parser, CPP_COMMA)
    4695      4199686 :           || c_parser_next_token_is (parser, CPP_SEMICOLON)
    4696        33331 :           || c_parser_next_token_is (parser, CPP_CLOSE_BRACE)
    4697      4341039 :           || c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    4698              :         {
    4699      4307731 :           tree postfix_attrs = NULL_TREE;
    4700      4307731 :           tree width = NULL_TREE;
    4701      4307731 :           tree d;
    4702      4307731 :           if (c_parser_next_token_is (parser, CPP_COLON))
    4703              :             {
    4704        52580 :               c_parser_consume_token (parser);
    4705        52580 :               location_t loc = c_parser_peek_token (parser)->location;
    4706        52580 :               width = convert_lvalue_to_rvalue (loc,
    4707              :                                                 (c_parser_expr_no_commas
    4708              :                                                  (parser, NULL)),
    4709              :                                                 true, true).value;
    4710              :             }
    4711      4307731 :           if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    4712        33491 :             postfix_attrs = c_parser_gnu_attributes (parser);
    4713      4307731 :           d = grokfield (c_parser_peek_token (parser)->location,
    4714              :                          declarator, specs, width, &all_prefix_attrs, expr);
    4715      4307731 :           decl_attributes (&d, chainon (postfix_attrs,
    4716              :                                         all_prefix_attrs), 0);
    4717      4307731 :           DECL_CHAIN (d) = decls;
    4718      4307731 :           decls = d;
    4719      4307731 :           if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    4720            0 :             all_prefix_attrs = chainon (c_parser_gnu_attributes (parser),
    4721              :                                         prefix_attrs);
    4722              :           else
    4723      4307731 :             all_prefix_attrs = prefix_attrs;
    4724      4307731 :           if (c_parser_next_token_is (parser, CPP_COMMA))
    4725        57663 :             c_parser_consume_token (parser);
    4726      4250068 :           else if (c_parser_next_token_is (parser, CPP_SEMICOLON)
    4727      4250091 :                    || c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    4728              :             {
    4729              :               /* Semicolon consumed in caller.  */
    4730              :               break;
    4731              :             }
    4732              :           else
    4733              :             {
    4734            0 :               c_parser_error (parser, "expected %<,%>, %<;%> or %<}%>");
    4735            0 :               break;
    4736              :             }
    4737              :         }
    4738              :       else
    4739              :         {
    4740            0 :           c_parser_error (parser,
    4741              :                           "expected %<:%>, %<,%>, %<;%>, %<}%> or "
    4742              :                           "%<__attribute__%>");
    4743            0 :           break;
    4744              :         }
    4745              :     }
    4746      4250069 :   return decls;
    4747              : }
    4748              : 
    4749              : /* Parse a typeof specifier (a GNU extension adopted in C23).
    4750              : 
    4751              :    typeof-specifier:
    4752              :      typeof ( expression )
    4753              :      typeof ( type-name )
    4754              :      typeof_unqual ( expression )
    4755              :      typeof_unqual ( type-name )
    4756              : */
    4757              : 
    4758              : static struct c_typespec
    4759       819810 : c_parser_typeof_specifier (c_parser *parser)
    4760              : {
    4761       819810 :   bool is_unqual;
    4762       819810 :   bool is_std;
    4763       819810 :   struct c_typespec ret;
    4764       819810 :   ret.kind = ctsk_typeof;
    4765       819810 :   ret.spec = error_mark_node;
    4766       819810 :   ret.expr = NULL_TREE;
    4767       819810 :   ret.expr_const_operands = true;
    4768       819810 :   ret.has_enum_type_specifier = false;
    4769       819810 :   if (c_parser_next_token_is_keyword (parser, RID_TYPEOF))
    4770              :     {
    4771       819718 :       is_unqual = false;
    4772       819718 :       tree spelling = c_parser_peek_token (parser)->value;
    4773       819718 :       is_std = (flag_isoc23
    4774       920596 :                 && strcmp (IDENTIFIER_POINTER (spelling), "typeof") == 0);
    4775              :     }
    4776              :   else
    4777              :     {
    4778           92 :       gcc_assert (c_parser_next_token_is_keyword (parser, RID_TYPEOF_UNQUAL));
    4779           92 :       is_unqual = true;
    4780           92 :       tree spelling = c_parser_peek_token (parser)->value;
    4781           92 :       is_std = strcmp (IDENTIFIER_POINTER (spelling), "typeof_unqual") == 0;
    4782              :     }
    4783       819810 :   c_parser_consume_token (parser);
    4784       819810 :   c_inhibit_evaluation_warnings++;
    4785       819810 :   in_typeof++;
    4786       819810 :   matching_parens parens;
    4787       819810 :   if (!parens.require_open (parser))
    4788              :     {
    4789            0 :       c_inhibit_evaluation_warnings--;
    4790            0 :       in_typeof--;
    4791            0 :       return ret;
    4792              :     }
    4793       819810 :   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
    4794              :     {
    4795          689 :       struct c_type_name *type = c_parser_type_name (parser);
    4796          689 :       c_inhibit_evaluation_warnings--;
    4797          689 :       in_typeof--;
    4798          689 :       if (type != NULL)
    4799              :         {
    4800          689 :           ret.spec = groktypename (type, &ret.expr, &ret.expr_const_operands);
    4801          689 :           pop_maybe_used (c_type_variably_modified_p (ret.spec));
    4802              :         }
    4803              :     }
    4804              :   else
    4805              :     {
    4806       819121 :       bool was_vm;
    4807       819121 :       location_t here = c_parser_peek_token (parser)->location;
    4808       819121 :       struct c_expr expr = c_parser_expression (parser);
    4809       819121 :       c_inhibit_evaluation_warnings--;
    4810       819121 :       in_typeof--;
    4811       819121 :       if (TREE_CODE (expr.value) == COMPONENT_REF
    4812       819121 :           && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
    4813           13 :         error_at (here, "%<typeof%> applied to a bit-field");
    4814       819121 :       mark_exp_read (expr.value);
    4815       819121 :       ret.spec = TREE_TYPE (expr.value);
    4816       819121 :       was_vm = c_type_variably_modified_p (ret.spec);
    4817              :       /* This is returned with the type so that when the type is
    4818              :          evaluated, this can be evaluated.  */
    4819       819121 :       if (was_vm)
    4820          218 :         ret.expr = c_fully_fold (expr.value, false, &ret.expr_const_operands);
    4821       819121 :       pop_maybe_used (was_vm);
    4822              :     }
    4823       819810 :   parens.skip_until_found_close (parser);
    4824       819810 :   if (ret.spec != error_mark_node)
    4825              :     {
    4826       819799 :       if (is_unqual)
    4827              :         {
    4828           92 :           bool is_array = TREE_CODE (ret.spec) == ARRAY_TYPE;
    4829           92 :           int quals = TYPE_QUALS (strip_array_types (ret.spec));
    4830           92 :           if ((is_array ? quals & ~TYPE_QUAL_ATOMIC : quals)
    4831              :               != TYPE_UNQUALIFIED)
    4832              :             {
    4833           51 :               ret.spec = TYPE_MAIN_VARIANT (ret.spec);
    4834           51 :               if (quals & TYPE_QUAL_ATOMIC && is_array)
    4835            4 :                 ret.spec = c_build_qualified_type (ret.spec,
    4836              :                                                    TYPE_QUAL_ATOMIC);
    4837              :             }
    4838              :         }
    4839       819799 :       if (is_std)
    4840              :         {
    4841              :           /* In ISO C terms, _Noreturn is not part of the type of
    4842              :              expressions such as &abort, but in GCC it is represented
    4843              :              internally as a type qualifier.  */
    4844         4282 :           if (TREE_CODE (ret.spec) == FUNCTION_TYPE
    4845         4282 :               && TYPE_QUALS (ret.spec) != TYPE_UNQUALIFIED)
    4846            2 :             ret.spec = TYPE_MAIN_VARIANT (ret.spec);
    4847         2917 :           else if (FUNCTION_POINTER_TYPE_P (ret.spec)
    4848         7108 :                    && TYPE_QUALS (TREE_TYPE (ret.spec)) != TYPE_UNQUALIFIED)
    4849            2 :             ret.spec
    4850            2 :               = c_build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (ret.spec)));
    4851              :         }
    4852              :     }
    4853              :   return ret;
    4854              : }
    4855              : 
    4856              : /* Parse an alignment-specifier.
    4857              : 
    4858              :    C11 6.7.5:
    4859              : 
    4860              :    alignment-specifier:
    4861              :      _Alignas ( type-name )
    4862              :      _Alignas ( constant-expression )
    4863              : */
    4864              : 
    4865              : static tree
    4866          202 : c_parser_alignas_specifier (c_parser * parser)
    4867              : {
    4868          202 :   tree ret = error_mark_node;
    4869          202 :   location_t loc = c_parser_peek_token (parser)->location;
    4870          202 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNAS));
    4871          202 :   tree spelling = c_parser_peek_token (parser)->value;
    4872          202 :   c_parser_consume_token (parser);
    4873          202 :   if (flag_isoc99)
    4874          199 :     pedwarn_c99 (loc, OPT_Wpedantic,
    4875              :                  "ISO C99 does not support %qE", spelling);
    4876              :   else
    4877            3 :     pedwarn_c99 (loc, OPT_Wpedantic,
    4878              :                  "ISO C90 does not support %qE", spelling);
    4879          202 :   matching_parens parens;
    4880          202 :   if (!parens.require_open (parser))
    4881              :     return ret;
    4882          202 :   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
    4883              :     {
    4884          132 :       struct c_type_name *type = c_parser_type_name (parser);
    4885          132 :       if (type != NULL)
    4886          131 :         ret = c_sizeof_or_alignof_type (loc, groktypename (type, NULL, NULL),
    4887              :                                         false, true, 1);
    4888              :     }
    4889              :   else
    4890           70 :     ret = convert_lvalue_to_rvalue (loc,
    4891              :                                     c_parser_expr_no_commas (parser, NULL),
    4892              :                                     true, true).value;
    4893          202 :   parens.skip_until_found_close (parser);
    4894          202 :   return ret;
    4895              : }
    4896              : 
    4897              : /* Parse a declarator, possibly an abstract declarator (C90 6.5.4,
    4898              :    6.5.5, C99 6.7.5, 6.7.6, C11 6.7.6, 6.7.7).  If TYPE_SEEN_P then
    4899              :    a typedef name may be redeclared; otherwise it may not.  KIND
    4900              :    indicates which kind of declarator is wanted.  Returns a valid
    4901              :    declarator except in the case of a syntax error in which case NULL is
    4902              :    returned.  *SEEN_ID is set to true if an identifier being declared is
    4903              :    seen; this is used to diagnose bad forms of abstract array declarators
    4904              :    and to determine whether an identifier list is syntactically permitted.
    4905              : 
    4906              :    declarator:
    4907              :      pointer[opt] direct-declarator
    4908              : 
    4909              :    direct-declarator:
    4910              :      identifier
    4911              :      ( gnu-attributes[opt] declarator )
    4912              :      direct-declarator array-declarator
    4913              :      direct-declarator ( parameter-type-list )
    4914              :      direct-declarator ( identifier-list[opt] )
    4915              : 
    4916              :    pointer:
    4917              :      * type-qualifier-list[opt]
    4918              :      * type-qualifier-list[opt] pointer
    4919              : 
    4920              :    type-qualifier-list:
    4921              :      type-qualifier
    4922              :      gnu-attributes
    4923              :      type-qualifier-list type-qualifier
    4924              :      type-qualifier-list gnu-attributes
    4925              : 
    4926              :    array-declarator:
    4927              :      [ type-qualifier-list[opt] assignment-expression[opt] ]
    4928              :      [ static type-qualifier-list[opt] assignment-expression ]
    4929              :      [ type-qualifier-list static assignment-expression ]
    4930              :      [ type-qualifier-list[opt] * ]
    4931              : 
    4932              :    parameter-type-list:
    4933              :      parameter-list
    4934              :      parameter-list , ...
    4935              : 
    4936              :    parameter-list:
    4937              :      parameter-declaration
    4938              :      parameter-list , parameter-declaration
    4939              : 
    4940              :    parameter-declaration:
    4941              :      declaration-specifiers declarator gnu-attributes[opt]
    4942              :      declaration-specifiers abstract-declarator[opt] gnu-attributes[opt]
    4943              : 
    4944              :    identifier-list:
    4945              :      identifier
    4946              :      identifier-list , identifier
    4947              : 
    4948              :    abstract-declarator:
    4949              :      pointer
    4950              :      pointer[opt] direct-abstract-declarator
    4951              : 
    4952              :    direct-abstract-declarator:
    4953              :      ( gnu-attributes[opt] abstract-declarator )
    4954              :      direct-abstract-declarator[opt] array-declarator
    4955              :      direct-abstract-declarator[opt] ( parameter-type-list[opt] )
    4956              : 
    4957              :    GNU extensions:
    4958              : 
    4959              :    direct-declarator:
    4960              :      direct-declarator ( parameter-forward-declarations
    4961              :                          parameter-type-list[opt] )
    4962              : 
    4963              :    direct-abstract-declarator:
    4964              :      direct-abstract-declarator[opt] ( parameter-forward-declarations
    4965              :                                        parameter-type-list[opt] )
    4966              : 
    4967              :    parameter-forward-declarations:
    4968              :      parameter-list ;
    4969              :      parameter-forward-declarations parameter-list ;
    4970              : 
    4971              :    The uses of gnu-attributes shown above are GNU extensions.
    4972              : 
    4973              :    Some forms of array declarator are not included in C99 in the
    4974              :    syntax for abstract declarators; these are disallowed elsewhere.
    4975              :    This may be a defect (DR#289).
    4976              : 
    4977              :    This function also accepts an omitted abstract declarator as being
    4978              :    an abstract declarator, although not part of the formal syntax.  */
    4979              : 
    4980              : struct c_declarator *
    4981    332088435 : c_parser_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
    4982              :                      bool *seen_id)
    4983              : {
    4984              :   /* Parse any initial pointer part.  */
    4985    332088435 :   if (c_parser_next_token_is (parser, CPP_MULT))
    4986              :     {
    4987     18211099 :       struct c_declspecs *quals_attrs = build_null_declspecs ();
    4988     18211099 :       struct c_declarator *inner;
    4989     18211099 :       c_parser_consume_token (parser);
    4990     18211099 :       c_parser_declspecs (parser, quals_attrs, false, false, true,
    4991              :                           false, false, true, false, cla_prefer_id);
    4992     18211099 :       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
    4993     18211099 :       if (inner == NULL)
    4994              :         return NULL;
    4995              :       else
    4996     18211090 :         return make_pointer_declarator (quals_attrs, inner);
    4997              :     }
    4998              :   /* Now we have a direct declarator, direct abstract declarator or
    4999              :      nothing (which counts as a direct abstract declarator here).  */
    5000    313877336 :   return c_parser_direct_declarator (parser, type_seen_p, kind, seen_id);
    5001              : }
    5002              : 
    5003              : /* Parse a direct declarator or direct abstract declarator; arguments
    5004              :    as c_parser_declarator.  */
    5005              : 
    5006              : static struct c_declarator *
    5007    313877336 : c_parser_direct_declarator (c_parser *parser, bool type_seen_p, c_dtr_syn kind,
    5008              :                             bool *seen_id)
    5009              : {
    5010              :   /* The direct declarator must start with an identifier (possibly
    5011              :      omitted) or a parenthesized declarator (possibly abstract).  In
    5012              :      an ordinary declarator, initial parentheses must start a
    5013              :      parenthesized declarator.  In an abstract declarator or parameter
    5014              :      declarator, they could start a parenthesized declarator or a
    5015              :      parameter list.  To tell which, the open parenthesis and any
    5016              :      following gnu-attributes must be read.  If a declaration
    5017              :      specifier or standard attributes follow, then it is a parameter
    5018              :      list; if the specifier is a typedef name, there might be an
    5019              :      ambiguity about redeclaring it, which is resolved in the
    5020              :      direction of treating it as a typedef name.  If a close
    5021              :      parenthesis follows, it is also an empty parameter list, as the
    5022              :      syntax does not permit empty abstract declarators.  Otherwise, it
    5023              :      is a parenthesized declarator (in which case the analysis may be
    5024              :      repeated inside it, recursively).
    5025              : 
    5026              :      ??? There is an ambiguity in a parameter declaration "int
    5027              :      (__attribute__((foo)) x)", where x is not a typedef name: it
    5028              :      could be an abstract declarator for a function, or declare x with
    5029              :      parentheses.  The proper resolution of this ambiguity needs
    5030              :      documenting.  At present we follow an accident of the old
    5031              :      parser's implementation, whereby the first parameter must have
    5032              :      some declaration specifiers other than just gnu-attributes.  Thus as
    5033              :      a parameter declaration it is treated as a parenthesized
    5034              :      parameter named x, and as an abstract declarator it is
    5035              :      rejected.
    5036              : 
    5037              :      ??? Also following the old parser, gnu-attributes inside an empty
    5038              :      parameter list are ignored, making it a list not yielding a
    5039              :      prototype, rather than giving an error or making it have one
    5040              :      parameter with implicit type int.
    5041              : 
    5042              :      ??? Also following the old parser, typedef names may be
    5043              :      redeclared in declarators, but not Objective-C class names.  */
    5044              : 
    5045    313877336 :   if (kind != C_DTR_ABSTRACT
    5046    192545008 :       && c_parser_next_token_is (parser, CPP_NAME)
    5047    501616293 :       && ((type_seen_p
    5048    187729097 :            && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
    5049    187681829 :                || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
    5050    187691689 :           || c_parser_peek_token (parser)->id_kind == C_ID_ID))
    5051              :     {
    5052    187738957 :       struct c_declarator *inner
    5053    187738957 :         = build_id_declarator (c_parser_peek_token (parser)->value);
    5054    187738957 :       *seen_id = true;
    5055    187738957 :       inner->id_loc = c_parser_peek_token (parser)->location;
    5056    187738957 :       c_parser_consume_token (parser);
    5057    187738957 :       if (c_parser_nth_token_starts_std_attributes (parser, 1))
    5058           84 :         inner->u.id.attrs = c_parser_std_attribute_specifier_sequence (parser);
    5059    187738957 :       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
    5060              :     }
    5061              : 
    5062    126138379 :   if (kind != C_DTR_NORMAL
    5063    125997315 :       && c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
    5064    126162538 :       && !c_parser_nth_token_starts_std_attributes (parser, 1))
    5065              :     {
    5066        24159 :       struct c_declarator *inner = build_id_declarator (NULL_TREE);
    5067        24159 :       inner->id_loc = c_parser_peek_token (parser)->location;
    5068        24159 :       return c_parser_direct_declarator_inner (parser, *seen_id, inner);
    5069              :     }
    5070              : 
    5071              :   /* Either we are at the end of an abstract declarator, or we have
    5072              :      parentheses.  */
    5073              : 
    5074    126114220 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
    5075              :     {
    5076       227292 :       tree attrs;
    5077       227292 :       struct c_declarator *inner;
    5078       227292 :       c_parser_consume_token (parser);
    5079       227292 :       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
    5080              :                                                             RID_ATTRIBUTE);
    5081       227292 :       attrs = c_parser_gnu_attributes (parser);
    5082       227292 :       if (kind != C_DTR_NORMAL
    5083       227292 :           && (c_parser_next_token_starts_declspecs (parser)
    5084        86296 :               || (!have_gnu_attrs
    5085        86138 :                   && (c_parser_nth_token_starts_std_attributes (parser, 1)
    5086        86138 :                       || c_parser_next_token_is (parser, CPP_ELLIPSIS)))
    5087        86291 :               || c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))
    5088              :         {
    5089           64 :           struct c_arg_info *args
    5090           64 :             = c_parser_parms_declarator (parser, kind == C_DTR_NORMAL,
    5091              :                                          attrs, have_gnu_attrs);
    5092           64 :           if (args == NULL)
    5093              :             return NULL;
    5094              :           else
    5095              :             {
    5096           64 :               inner = build_id_declarator (NULL_TREE);
    5097           89 :               if (!(args->types
    5098           25 :                     && args->types != error_mark_node
    5099           25 :                     && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
    5100           89 :                   && c_parser_nth_token_starts_std_attributes (parser, 1))
    5101              :                 {
    5102            4 :                   tree std_attrs
    5103            4 :                     = c_parser_std_attribute_specifier_sequence (parser);
    5104            4 :                   if (std_attrs)
    5105            2 :                     inner = build_attrs_declarator (std_attrs, inner);
    5106              :                 }
    5107           64 :               inner = build_function_declarator (args, inner);
    5108           64 :               return c_parser_direct_declarator_inner (parser, *seen_id,
    5109           64 :                                                        inner);
    5110              :             }
    5111              :         }
    5112              :       /* A parenthesized declarator.  */
    5113       227228 :       inner = c_parser_declarator (parser, type_seen_p, kind, seen_id);
    5114       227228 :       if (inner != NULL && attrs != NULL)
    5115          179 :         inner = build_attrs_declarator (attrs, inner);
    5116       227228 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5117              :         {
    5118       227212 :           c_parser_consume_token (parser);
    5119       227212 :           if (inner == NULL)
    5120              :             return NULL;
    5121              :           else
    5122       227212 :             return c_parser_direct_declarator_inner (parser, *seen_id, inner);
    5123              :         }
    5124              :       else
    5125              :         {
    5126           16 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5127              :                                      "expected %<)%>");
    5128           16 :           return NULL;
    5129              :         }
    5130              :     }
    5131              :   else
    5132              :     {
    5133    125886928 :       if (kind == C_DTR_NORMAL)
    5134              :         {
    5135           93 :           c_parser_error (parser, "expected identifier or %<(%>");
    5136           93 :           return NULL;
    5137              :         }
    5138              :       else
    5139    125886835 :         return build_id_declarator (NULL_TREE);
    5140              :     }
    5141              : }
    5142              : 
    5143              : /* Parse part of a direct declarator or direct abstract declarator,
    5144              :    given that some (in INNER) has already been parsed; ID_PRESENT is
    5145              :    true if an identifier is present, false for an abstract
    5146              :    declarator.  */
    5147              : 
    5148              : static struct c_declarator *
    5149    239638334 : c_parser_direct_declarator_inner (c_parser *parser, bool id_present,
    5150              :                                   struct c_declarator *inner)
    5151              : {
    5152              :   /* Parse a sequence of array declarators and parameter lists.  */
    5153    239638334 :   if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
    5154    239638334 :       && !c_parser_nth_token_starts_std_attributes (parser, 1))
    5155              :     {
    5156      1151493 :       location_t brace_loc = c_parser_peek_token (parser)->location;
    5157      1151493 :       struct c_declarator *declarator;
    5158      1151493 :       struct c_declspecs *quals_attrs = build_null_declspecs ();
    5159      1151493 :       struct c_expr dimen;
    5160      1151493 :       dimen.value = NULL_TREE;
    5161      1151493 :       dimen.original_code = ERROR_MARK;
    5162      1151493 :       dimen.original_type = NULL_TREE;
    5163      1151493 :       c_parser_consume_token (parser);
    5164      1151493 :       c_parser_declspecs (parser, quals_attrs, false, false, true,
    5165              :                           false, false, false, false, cla_prefer_id);
    5166              : 
    5167      1151493 :       location_t static_loc = UNKNOWN_LOCATION;
    5168      1151493 :       if (c_parser_next_token_is_keyword (parser, RID_STATIC))
    5169              :         {
    5170          131 :           static_loc = c_parser_peek_token (parser)->location;
    5171          131 :           c_parser_consume_token (parser);
    5172          131 :           if (!quals_attrs->declspecs_seen_p)
    5173          111 :             c_parser_declspecs (parser, quals_attrs, false, false, true,
    5174              :                                 false, false, false, false, cla_prefer_id);
    5175              :         }
    5176      1151493 :       if (!quals_attrs->declspecs_seen_p)
    5177      1150522 :         quals_attrs = NULL;
    5178              :       /* If "static" is present, there must be an array dimension.
    5179              :          Otherwise, there may be a dimension, "*", or no
    5180              :          dimension.  */
    5181      1151493 :       const bool static_seen = (static_loc != UNKNOWN_LOCATION);
    5182      1151493 :       bool star_seen = false;
    5183      1151493 :       if (c_parser_next_token_is (parser, CPP_MULT)
    5184      1151493 :           && c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_SQUARE)
    5185              :         {
    5186          154 :           star_seen = true;
    5187          154 :           c_parser_consume_token (parser);
    5188              :         }
    5189      1151339 :       else if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
    5190       980394 :         dimen = c_parser_expr_no_commas (parser, NULL);
    5191              : 
    5192      1151493 :       if (static_seen)
    5193              :         {
    5194          131 :           if (star_seen)
    5195              :             {
    5196            3 :               error_at (static_loc,
    5197              :                         "%<static%> may not be used with an unspecified "
    5198              :                         "variable length array size");
    5199              :               /* Prevent further errors.  */
    5200            3 :               star_seen = false;
    5201            3 :               dimen.value = error_mark_node;
    5202              :             }
    5203          128 :           else if (!dimen.value)
    5204            2 :             error_at (static_loc,
    5205              :                       "%<static%> may not be used without an array size");
    5206              :         }
    5207              : 
    5208      1151493 :       if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
    5209      1151478 :         c_parser_consume_token (parser);
    5210              :       else
    5211              :         {
    5212           15 :           c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
    5213              :                                      "expected %<]%>");
    5214           15 :           return NULL;
    5215              :         }
    5216      1151478 :       if (dimen.value)
    5217       980382 :         dimen = convert_lvalue_to_rvalue (brace_loc, dimen, true, true);
    5218      1151478 :       declarator = build_array_declarator (brace_loc, dimen.value, quals_attrs,
    5219              :                                            static_seen, star_seen);
    5220      1151478 :       if (declarator == NULL)
    5221              :         return NULL;
    5222      1151478 :       if (c_parser_nth_token_starts_std_attributes (parser, 1))
    5223              :         {
    5224           16 :           tree std_attrs
    5225           16 :             = c_parser_std_attribute_specifier_sequence (parser);
    5226           16 :           if (std_attrs)
    5227           10 :             inner = build_attrs_declarator (std_attrs, inner);
    5228              :         }
    5229      1151478 :       inner = set_array_declarator_inner (declarator, inner);
    5230      1151478 :       return c_parser_direct_declarator_inner (parser, id_present, inner);
    5231              :     }
    5232    238486841 :   else if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
    5233              :     {
    5234     50496572 :       tree attrs;
    5235     50496572 :       struct c_arg_info *args;
    5236     50496572 :       c_parser_consume_token (parser);
    5237     50496572 :       bool have_gnu_attrs = c_parser_next_token_is_keyword (parser,
    5238              :                                                             RID_ATTRIBUTE);
    5239     50496572 :       attrs = c_parser_gnu_attributes (parser);
    5240     50496572 :       args = c_parser_parms_declarator (parser, id_present, attrs,
    5241              :                                         have_gnu_attrs);
    5242     50496572 :       if (args == NULL)
    5243              :         return NULL;
    5244              :       else
    5245              :         {
    5246    100220719 :           if (!(args->types
    5247     49724255 :                 && args->types != error_mark_node
    5248     49724255 :                 && TREE_CODE (TREE_VALUE (args->types)) == IDENTIFIER_NODE)
    5249    100212032 :               && c_parser_nth_token_starts_std_attributes (parser, 1))
    5250              :             {
    5251           98 :               tree std_attrs
    5252           98 :                 = c_parser_std_attribute_specifier_sequence (parser);
    5253           98 :               if (std_attrs)
    5254           81 :                 inner = build_attrs_declarator (std_attrs, inner);
    5255              :             }
    5256     50496464 :           inner = build_function_declarator (args, inner);
    5257     50496464 :           return c_parser_direct_declarator_inner (parser, id_present, inner);
    5258              :         }
    5259              :     }
    5260              :   return inner;
    5261              : }
    5262              : 
    5263              : /* Parse a parameter list or identifier list, including the closing
    5264              :    parenthesis but not the opening one.  ATTRS are the gnu-attributes
    5265              :    at the start of the list.  ID_LIST_OK is true if an identifier list
    5266              :    is acceptable; such a list must not have attributes at the start.
    5267              :    HAVE_GNU_ATTRS says whether any gnu-attributes (including empty
    5268              :    attributes) were present (in which case standard attributes cannot
    5269              :    occur).  */
    5270              : 
    5271              : static struct c_arg_info *
    5272     50496636 : c_parser_parms_declarator (c_parser *parser, bool id_list_ok, tree attrs,
    5273              :                            bool have_gnu_attrs)
    5274              : {
    5275     50496636 :   push_scope ();
    5276     50496636 :   declare_parm_level ();
    5277              :   /* If the list starts with an identifier, it is an identifier list.
    5278              :      Otherwise, it is either a prototype list or an empty list.  */
    5279     50496636 :   if (id_list_ok
    5280     50496636 :       && !attrs
    5281     50484483 :       && c_parser_next_token_is (parser, CPP_NAME)
    5282     33765974 :       && c_parser_peek_token (parser)->id_kind == C_ID_ID
    5283              : 
    5284              :       /* Look ahead to detect typos in type names.  */
    5285         8698 :       && c_parser_peek_2nd_token (parser)->type != CPP_NAME
    5286         8691 :       && c_parser_peek_2nd_token (parser)->type != CPP_MULT
    5287         8690 :       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
    5288         8689 :       && c_parser_peek_2nd_token (parser)->type != CPP_OPEN_SQUARE
    5289     50505324 :       && c_parser_peek_2nd_token (parser)->type != CPP_KEYWORD)
    5290              :     {
    5291         8687 :       tree list = NULL_TREE, *nextp = &list;
    5292         8687 :       while (c_parser_next_token_is (parser, CPP_NAME)
    5293        34292 :              && c_parser_peek_token (parser)->id_kind == C_ID_ID)
    5294              :         {
    5295        34292 :           *nextp = build_tree_list (NULL_TREE,
    5296        34292 :                                     c_parser_peek_token (parser)->value);
    5297        34292 :           nextp = & TREE_CHAIN (*nextp);
    5298        34292 :           c_parser_consume_token (parser);
    5299        34292 :           if (c_parser_next_token_is_not (parser, CPP_COMMA))
    5300              :             break;
    5301        25605 :           c_parser_consume_token (parser);
    5302        25605 :           if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5303              :             {
    5304            0 :               c_parser_error (parser, "expected identifier");
    5305            0 :               break;
    5306              :             }
    5307              :         }
    5308         8687 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5309              :         {
    5310         8687 :           struct c_arg_info *ret = build_arg_info ();
    5311         8687 :           ret->types = list;
    5312         8687 :           c_parser_consume_token (parser);
    5313         8687 :           pop_scope ();
    5314         8687 :           return ret;
    5315              :         }
    5316              :       else
    5317              :         {
    5318            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5319              :                                      "expected %<)%>");
    5320            0 :           pop_scope ();
    5321            0 :           return NULL;
    5322              :         }
    5323              :     }
    5324              :   else
    5325              :     {
    5326     50487949 :       struct c_arg_info *ret
    5327     50487949 :         = c_parser_parms_list_declarator (parser, attrs, NULL, have_gnu_attrs);
    5328     50487949 :       pop_scope ();
    5329     50487949 :       return ret;
    5330              :     }
    5331              : }
    5332              : 
    5333              : /* Parse a parameter list (possibly empty), including the closing
    5334              :    parenthesis but not the opening one.  ATTRS are the gnu-attributes
    5335              :    at the start of the list; if HAVE_GNU_ATTRS, there were some such
    5336              :    attributes (possibly empty, in which case ATTRS is NULL_TREE),
    5337              :    which means standard attributes cannot start the list.  EXPR is
    5338              :    NULL or an expression that needs to be evaluated for the side
    5339              :    effects of array size expressions in the parameters.  */
    5340              : 
    5341              : static struct c_arg_info *
    5342     50487991 : c_parser_parms_list_declarator (c_parser *parser, tree attrs, tree expr,
    5343              :                                 bool have_gnu_attrs)
    5344              : {
    5345     50487991 :   bool bad_parm = false;
    5346              : 
    5347              :   /* ??? Following the old parser, forward parameter declarations may
    5348              :      use abstract declarators, and if no real parameter declarations
    5349              :      follow the forward declarations then this is not diagnosed.  Also
    5350              :      note as above that gnu-attributes are ignored as the only contents of
    5351              :      the parentheses, or as the only contents after forward
    5352              :      declarations.  */
    5353     50487991 :   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5354              :     {
    5355       772089 :       struct c_arg_info *ret = build_arg_info ();
    5356       772089 :       c_parser_consume_token (parser);
    5357       772089 :       return ret;
    5358              :     }
    5359     49715902 :   if (c_parser_next_token_is (parser, CPP_ELLIPSIS) && !have_gnu_attrs)
    5360              :     {
    5361          136 :       struct c_arg_info *ret = build_arg_info ();
    5362              : 
    5363          136 :       ret->types = NULL_TREE;
    5364          136 :       pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wpedantic,
    5365              :                    "ISO C requires a named argument before %<...%> "
    5366              :                    "before C23");
    5367          136 :       c_parser_consume_token (parser);
    5368          136 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5369              :         {
    5370          136 :           ret->no_named_args_stdarg_p = true;
    5371          136 :           c_parser_consume_token (parser);
    5372          136 :           return ret;
    5373              :         }
    5374              :       else
    5375              :         {
    5376            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5377              :                                      "expected %<)%>");
    5378            0 :           return NULL;
    5379              :         }
    5380              :     }
    5381              :   /* Nonempty list of parameters, either terminated with semicolon
    5382              :      (forward declarations; recurse) or with close parenthesis (normal
    5383              :      function) or with ", ... )" (variadic function).  */
    5384    123862934 :   while (true)
    5385              :     {
    5386              :       /* Parse a parameter.  */
    5387    123862934 :       struct c_parm *parm = c_parser_parameter_declaration (parser, attrs,
    5388              :                                                             have_gnu_attrs);
    5389    123862934 :       attrs = NULL_TREE;
    5390    123862934 :       have_gnu_attrs = false;
    5391    123862934 :       if (parm == NULL)
    5392              :         bad_parm = true;
    5393              :       else
    5394    123862825 :         push_parm_decl (parm, &expr);
    5395    123862934 :       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    5396              :         {
    5397           42 :           tree new_attrs;
    5398           42 :           c_parser_consume_token (parser);
    5399           42 :           mark_forward_parm_decls ();
    5400           42 :           bool new_have_gnu_attrs
    5401           42 :             = c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE);
    5402           42 :           new_attrs = c_parser_gnu_attributes (parser);
    5403           42 :           return c_parser_parms_list_declarator (parser, new_attrs, expr,
    5404           42 :                                                  new_have_gnu_attrs);
    5405              :         }
    5406    123862892 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5407              :         {
    5408     49502989 :           c_parser_consume_token (parser);
    5409     49502989 :           if (bad_parm)
    5410              :             return NULL;
    5411              :           else
    5412     49502904 :             return get_parm_info (false, expr);
    5413              :         }
    5414     74359903 :       if (!c_parser_require (parser, CPP_COMMA,
    5415              :                              "expected %<;%>, %<,%> or %<)%>",
    5416              :                              UNKNOWN_LOCATION, false))
    5417              :         {
    5418            8 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    5419            8 :           return NULL;
    5420              :         }
    5421     74359895 :       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
    5422              :         {
    5423       212727 :           c_parser_consume_token (parser);
    5424       212727 :           if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5425              :             {
    5426       212720 :               c_parser_consume_token (parser);
    5427       212720 :               if (bad_parm)
    5428              :                 return NULL;
    5429              :               else
    5430       212712 :                 return get_parm_info (true, expr);
    5431              :             }
    5432              :           else
    5433              :             {
    5434            7 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5435              :                                          "expected %<)%>");
    5436            7 :               return NULL;
    5437              :             }
    5438              :         }
    5439              :     }
    5440              : }
    5441              : 
    5442              : /* Parse a parameter declaration.  ATTRS are the gnu-attributes at the
    5443              :    start of the declaration if it is the first parameter;
    5444              :    HAVE_GNU_ATTRS is true if there were any gnu-attributes there (even
    5445              :    empty) there.  */
    5446              : 
    5447              : static struct c_parm *
    5448    123862934 : c_parser_parameter_declaration (c_parser *parser, tree attrs,
    5449              :                                 bool have_gnu_attrs)
    5450              : {
    5451    123862934 :   struct c_declspecs *specs;
    5452    123862934 :   struct c_declarator *declarator;
    5453    123862934 :   tree prefix_attrs;
    5454    123862934 :   tree postfix_attrs = NULL_TREE;
    5455    123862934 :   bool dummy = false;
    5456              : 
    5457              :   /* Accept #pragmas between parameter declarations.  */
    5458    123862936 :   while (c_parser_next_token_is (parser, CPP_PRAGMA))
    5459            2 :     c_parser_pragma (parser, pragma_param, NULL, NULL_TREE);
    5460              : 
    5461    123862934 :   if (!c_parser_next_token_starts_declspecs (parser)
    5462    123862934 :       && !c_parser_nth_token_starts_std_attributes (parser, 1))
    5463              :     {
    5464           97 :       c_token *token = c_parser_peek_token (parser);
    5465           97 :       if (parser->error)
    5466              :         return NULL;
    5467           97 :       c_parser_set_source_position_from_token (token);
    5468           97 :       if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
    5469              :         {
    5470           79 :           auto_diagnostic_group d;
    5471           79 :           name_hint hint = lookup_name_fuzzy (token->value,
    5472              :                                               FUZZY_LOOKUP_TYPENAME,
    5473           79 :                                               token->location);
    5474           79 :           if (const char *suggestion = hint.suggestion ())
    5475              :             {
    5476           30 :               gcc_rich_location richloc (token->location);
    5477           30 :               richloc.add_fixit_replace (suggestion);
    5478           30 :               error_at (&richloc,
    5479              :                         "unknown type name %qE; did you mean %qs?",
    5480              :                         token->value, suggestion);
    5481           30 :             }
    5482              :           else
    5483           49 :             error_at (token->location, "unknown type name %qE", token->value);
    5484           79 :           parser->error = true;
    5485           79 :         }
    5486              :       /* ??? In some Objective-C cases '...' isn't applicable so there
    5487              :          should be a different message.  */
    5488              :       else
    5489           18 :         c_parser_error (parser,
    5490              :                         "expected declaration specifiers or %<...%>");
    5491           97 :       c_parser_skip_to_end_of_parameter (parser);
    5492           97 :       return NULL;
    5493              :     }
    5494              : 
    5495    123862837 :   location_t start_loc = c_parser_peek_token (parser)->location;
    5496              : 
    5497    123862837 :   specs = build_null_declspecs ();
    5498    123862837 :   if (attrs)
    5499              :     {
    5500          339 :       declspecs_add_attrs (input_location, specs, attrs);
    5501          339 :       attrs = NULL_TREE;
    5502              :     }
    5503    123862837 :   c_parser_declspecs (parser, specs, true, true, true, true, false,
    5504    123862837 :                       !have_gnu_attrs, true, cla_nonabstract_decl);
    5505    123862837 :   finish_declspecs (specs);
    5506              :   /* When the param is declared, its type is a top level type, we should
    5507              :      call verify_counted_by_for_top_anonymous_type.  */
    5508    123862837 :   if (specs->typespec_kind == ctsk_tagdef)
    5509           65 :     verify_counted_by_for_top_anonymous_type (specs->type);
    5510              : 
    5511    123862837 :   pending_xref_error ();
    5512    123862837 :   prefix_attrs = specs->attrs;
    5513    123862837 :   specs->attrs = NULL_TREE;
    5514    247725674 :   declarator = c_parser_declarator (parser,
    5515    123862837 :                                     specs->typespec_kind != ctsk_none,
    5516              :                                     C_DTR_PARM, &dummy);
    5517    123862837 :   if (declarator == NULL)
    5518              :     {
    5519           12 :       c_parser_skip_until_found (parser, CPP_COMMA, NULL);
    5520           12 :       return NULL;
    5521              :     }
    5522    123862825 :   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    5523        17287 :     postfix_attrs = c_parser_gnu_attributes (parser);
    5524              : 
    5525              :   /* Generate a location for the parameter, ranging from the start of the
    5526              :      initial token to the end of the final token.
    5527              : 
    5528              :      If we have a identifier, then use it for the caret location, e.g.
    5529              : 
    5530              :        extern int callee (int one, int (*two)(int, int), float three);
    5531              :                                    ~~~~~~^~~~~~~~~~~~~~
    5532              : 
    5533              :      otherwise, reuse the start location for the caret location e.g.:
    5534              : 
    5535              :        extern int callee (int one, int (*)(int, int), float three);
    5536              :                                    ^~~~~~~~~~~~~~~~~
    5537              :   */
    5538    123862825 :   location_t end_loc = parser->last_token_location;
    5539              : 
    5540              :   /* Find any cdk_id declarator; determine if we have an identifier.  */
    5541    123862825 :   c_declarator *id_declarator = declarator;
    5542    136754652 :   while (id_declarator && id_declarator->kind != cdk_id)
    5543     12891827 :     id_declarator = id_declarator->declarator;
    5544    119278451 :   location_t caret_loc = (id_declarator->u.id.id
    5545    123862825 :                           ? id_declarator->id_loc
    5546              :                           : start_loc);
    5547    123862825 :   location_t param_loc = make_location (caret_loc, start_loc, end_loc);
    5548              : 
    5549    123862825 :   return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
    5550    123862825 :                        declarator, param_loc);
    5551              : }
    5552              : 
    5553              : /* Parse a string literal in an asm expression.  It should not be
    5554              :    translated, and wide string literals are an error although
    5555              :    permitted by the syntax.  This is a GNU extension.
    5556              : 
    5557              :    asm-string-literal:
    5558              :      string-literal
    5559              : */
    5560              : 
    5561              : static tree
    5562      1967962 : c_parser_asm_string_literal (c_parser *parser)
    5563              : {
    5564      1967962 :   tree str;
    5565      1967962 :   int save_flag = warn_overlength_strings;
    5566      1967962 :   warn_overlength_strings = 0;
    5567      1967962 :   str = c_parser_string_literal (parser, false, false).value;
    5568      1967962 :   warn_overlength_strings = save_flag;
    5569      1967962 :   return str;
    5570              : }
    5571              : 
    5572              : /* Parse a simple asm expression.  This is used in restricted
    5573              :    contexts, where a full expression with inputs and outputs does not
    5574              :    make sense.  This is a GNU extension.
    5575              : 
    5576              :    simple-asm-expr:
    5577              :      asm ( asm-string-literal )
    5578              : */
    5579              : 
    5580              : static tree
    5581       871446 : c_parser_simple_asm_expr (c_parser *parser)
    5582              : {
    5583       871446 :   tree str;
    5584       871446 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
    5585       871446 :   c_parser_consume_token (parser);
    5586       871446 :   matching_parens parens;
    5587       871446 :   if (!parens.require_open (parser))
    5588              :     return NULL_TREE;
    5589       871446 :   str = c_parser_asm_string_literal (parser);
    5590       871446 :   if (!parens.require_close (parser))
    5591              :     {
    5592            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    5593            0 :       return NULL_TREE;
    5594              :     }
    5595              :   return str;
    5596              : }
    5597              : 
    5598              : static tree
    5599    135224691 : c_parser_gnu_attribute_any_word (c_parser *parser)
    5600              : {
    5601    135224691 :   tree attr_name = NULL_TREE;
    5602              : 
    5603    135224691 :   if (c_parser_next_token_is (parser, CPP_KEYWORD))
    5604              :     {
    5605              :       /* ??? See comment above about what keywords are accepted here.  */
    5606       864424 :       bool ok;
    5607       864424 :       switch (c_parser_peek_token (parser)->keyword)
    5608              :         {
    5609              :         case RID_STATIC:
    5610              :         case RID_UNSIGNED:
    5611              :         case RID_LONG:
    5612              :         case RID_CONST:
    5613              :         case RID_EXTERN:
    5614              :         case RID_REGISTER:
    5615              :         case RID_TYPEDEF:
    5616              :         case RID_SHORT:
    5617              :         case RID_INLINE:
    5618              :         case RID_NORETURN:
    5619              :         case RID_VOLATILE:
    5620              :         case RID_SIGNED:
    5621              :         case RID_AUTO:
    5622              :         case RID_RESTRICT:
    5623              :         case RID_COMPLEX:
    5624              :         case RID_THREAD:
    5625              :         case RID_INT:
    5626              :         case RID_CHAR:
    5627              :         case RID_FLOAT:
    5628              :         case RID_DOUBLE:
    5629              :         case RID_VOID:
    5630              :         case RID_DFLOAT32:
    5631              :         case RID_DFLOAT64:
    5632              :         case RID_DFLOAT128:
    5633              :         case RID_DFLOAT64X:
    5634              :         CASE_RID_FLOATN_NX:
    5635              :         case RID_BOOL:
    5636              :         case RID_BITINT:
    5637              :         case RID_FRACT:
    5638              :         case RID_ACCUM:
    5639              :         case RID_SAT:
    5640              :         case RID_TRANSACTION_ATOMIC:
    5641              :         case RID_TRANSACTION_CANCEL:
    5642              :         case RID_ATOMIC:
    5643              :         case RID_AUTO_TYPE:
    5644              :         case RID_CONSTEXPR:
    5645              :         case RID_INT_N_0:
    5646              :         case RID_INT_N_1:
    5647              :         case RID_INT_N_2:
    5648              :         case RID_INT_N_3:
    5649              :           ok = true;
    5650              :           break;
    5651              :         default:
    5652              :           ok = false;
    5653              :           break;
    5654              :         }
    5655       864424 :       if (!ok)
    5656              :         return NULL_TREE;
    5657              : 
    5658              :       /* Accept __attribute__((__const)) as __attribute__((const)) etc.  */
    5659       864424 :       attr_name = ridpointers[(int) c_parser_peek_token (parser)->keyword];
    5660              :     }
    5661    134360267 :   else if (c_parser_next_token_is (parser, CPP_NAME))
    5662    134360264 :     attr_name = c_parser_peek_token (parser)->value;
    5663              : 
    5664              :   return attr_name;
    5665              : }
    5666              : 
    5667              : /* Parse attribute arguments.  This is a common form of syntax
    5668              :    covering all currently valid GNU and standard attributes.
    5669              : 
    5670              :    gnu-attribute-arguments:
    5671              :      identifier
    5672              :      identifier , nonempty-expr-list
    5673              :      expr-list
    5674              : 
    5675              :    where the "identifier" must not be declared as a type.  ??? Why not
    5676              :    allow identifiers declared as types to start the arguments?  */
    5677              : 
    5678              : static tree
    5679      4520221 : c_parser_attribute_arguments (c_parser *parser, bool takes_identifier,
    5680              :                               bool require_string, bool assume_attr,
    5681              :                               bool allow_empty_args)
    5682              : {
    5683      4520221 :   vec<tree, va_gc> *expr_list;
    5684      4520221 :   tree attr_args;
    5685              :   /* Parse the attribute contents.  If they start with an
    5686              :      identifier which is followed by a comma or close
    5687              :      parenthesis, then the arguments start with that
    5688              :      identifier; otherwise they are an expression list.
    5689              :      In objective-c the identifier may be a classname.  */
    5690      4520221 :   if (c_parser_next_token_is (parser, CPP_NAME)
    5691       570086 :       && (c_parser_peek_token (parser)->id_kind == C_ID_ID
    5692            1 :           || (c_dialect_objc ()
    5693            0 :               && c_parser_peek_token (parser)->id_kind
    5694              :               == C_ID_CLASSNAME))
    5695       570085 :       && ((c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
    5696        40016 :           || (c_parser_peek_2nd_token (parser)->type
    5697              :               == CPP_CLOSE_PAREN))
    5698      5090267 :       && (takes_identifier
    5699       143938 :           || (c_dialect_objc ()
    5700            0 :               && !assume_attr
    5701            0 :               && c_parser_peek_token (parser)->id_kind
    5702              :               == C_ID_CLASSNAME)))
    5703              :     {
    5704       426108 :       tree arg1 = c_parser_peek_token (parser)->value;
    5705       426108 :       c_parser_consume_token (parser);
    5706       426108 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5707        35869 :         attr_args = build_tree_list (NULL_TREE, arg1);
    5708              :       else
    5709              :         {
    5710       390239 :           tree tree_list;
    5711       390239 :           c_parser_consume_token (parser);
    5712       390239 :           expr_list = c_parser_expr_list (parser, false, true,
    5713              :                                           NULL, NULL, NULL, NULL);
    5714       390239 :           tree_list = build_tree_list_vec (expr_list);
    5715       390239 :           attr_args = tree_cons (NULL_TREE, arg1, tree_list);
    5716       390239 :           release_tree_vector (expr_list);
    5717              :         }
    5718              :     }
    5719              :   else
    5720              :     {
    5721      4094113 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5722              :         {
    5723           16 :           if (!allow_empty_args)
    5724            3 :             error_at (c_parser_peek_token (parser)->location,
    5725              :                       "parentheses must be omitted if "
    5726              :                       "attribute argument list is empty");
    5727              :           attr_args = NULL_TREE;
    5728              :         }
    5729      4094097 :       else if (require_string)
    5730              :         {
    5731              :           /* The only valid argument for this attribute is a string
    5732              :              literal.  Handle this specially here to avoid accepting
    5733              :              string literals with excess parentheses.  */
    5734           19 :           tree string = c_parser_string_literal (parser, false, true).value;
    5735           19 :           attr_args = build_tree_list (NULL_TREE, string);
    5736              :         }
    5737      4094078 :       else if (assume_attr)
    5738              :         {
    5739           45 :           tree cond
    5740           45 :             = c_parser_conditional_expression (parser, NULL, NULL_TREE).value;
    5741           45 :           if (!c_parser_next_token_is (parser, CPP_COMMA))
    5742           43 :             attr_args = build_tree_list (NULL_TREE, cond);
    5743              :           else
    5744              :             {
    5745            2 :               tree tree_list;
    5746            2 :               c_parser_consume_token (parser);
    5747            2 :               expr_list = c_parser_expr_list (parser, false, true,
    5748              :                                               NULL, NULL, NULL, NULL);
    5749            2 :               tree_list = build_tree_list_vec (expr_list);
    5750            2 :               attr_args = tree_cons (NULL_TREE, cond, tree_list);
    5751            2 :               release_tree_vector (expr_list);
    5752              :             }
    5753              :         }
    5754              :       else
    5755              :         {
    5756      4094033 :           expr_list = c_parser_expr_list (parser, false, true,
    5757              :                                           NULL, NULL, NULL, NULL);
    5758      4094033 :           attr_args = build_tree_list_vec (expr_list);
    5759      4094033 :           release_tree_vector (expr_list);
    5760              :         }
    5761              :     }
    5762      4520221 :   return attr_args;
    5763              : }
    5764              : 
    5765              : /* Parse (possibly empty) gnu-attributes.  This is a GNU extension.
    5766              : 
    5767              :    gnu-attributes:
    5768              :      empty
    5769              :      gnu-attributes gnu-attribute
    5770              : 
    5771              :    gnu-attribute:
    5772              :      __attribute__ ( ( gnu-attribute-list ) )
    5773              : 
    5774              :    gnu-attribute-list:
    5775              :      gnu-attrib
    5776              :      gnu-attribute_list , gnu-attrib
    5777              : 
    5778              :    gnu-attrib:
    5779              :      empty
    5780              :      any-word
    5781              :      any-word ( gnu-attribute-arguments )
    5782              : 
    5783              :    where "any-word" may be any identifier (including one declared as a
    5784              :    type), a reserved word storage class specifier, type specifier or
    5785              :    type qualifier.  ??? This still leaves out most reserved keywords
    5786              :    (following the old parser), shouldn't we include them?
    5787              :    When EXPECT_COMMA is true, expect the attribute to be preceded
    5788              :    by a comma and fail if it isn't.
    5789              :    When EMPTY_OK is true, allow and consume any number of consecutive
    5790              :    commas with no attributes in between.  */
    5791              : 
    5792              : static tree
    5793    188222913 : c_parser_gnu_attribute (c_parser *parser, tree attrs,
    5794              :                         bool expect_comma = false, bool empty_ok = true)
    5795              : {
    5796    188222913 :   bool comma_first = c_parser_next_token_is (parser, CPP_COMMA);
    5797    188222913 :   if (!comma_first
    5798    105997203 :       && !c_parser_next_token_is (parser, CPP_NAME)
    5799    242085452 :       && !c_parser_next_token_is (parser, CPP_KEYWORD))
    5800              :     return NULL_TREE;
    5801              : 
    5802    217450408 :   while (c_parser_next_token_is (parser, CPP_COMMA))
    5803              :     {
    5804     82225717 :       c_parser_consume_token (parser);
    5805     82225717 :       if (!empty_ok)
    5806              :         return attrs;
    5807              :     }
    5808              : 
    5809    135224691 :   tree attr_name = c_parser_gnu_attribute_any_word (parser);
    5810    135224691 :   if (attr_name == NULL_TREE)
    5811              :     return NULL_TREE;
    5812              : 
    5813    135224688 :   attr_name = canonicalize_attr_name (attr_name);
    5814    135224688 :   c_parser_consume_token (parser);
    5815              : 
    5816    135224688 :   tree attr;
    5817    135224688 :   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
    5818              :     {
    5819    130704563 :       if (expect_comma && !comma_first)
    5820              :         {
    5821              :           /* A comma is missing between the last attribute on the chain
    5822              :              and this one.  */
    5823            7 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5824              :                                      "expected %<)%>");
    5825            7 :           return error_mark_node;
    5826              :         }
    5827    130704556 :       attr = build_tree_list (attr_name, NULL_TREE);
    5828              :       /* Add this attribute to the list.  */
    5829    130704556 :       attrs = chainon (attrs, attr);
    5830    130704556 :       return attrs;
    5831              :     }
    5832      4520125 :   c_parser_consume_token (parser);
    5833              : 
    5834      4520125 :   tree attr_args
    5835      4520125 :     = c_parser_attribute_arguments (parser,
    5836      4520125 :                                     attribute_takes_identifier_p (attr_name),
    5837              :                                     false,
    5838      4520125 :                                     is_attribute_p ("assume", attr_name),
    5839              :                                     true);
    5840              : 
    5841      4520125 :   attr = build_tree_list (attr_name, attr_args);
    5842      4520125 :   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5843      4520123 :     c_parser_consume_token (parser);
    5844              :   else
    5845              :     {
    5846            2 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5847              :                                  "expected %<)%>");
    5848            2 :       return error_mark_node;
    5849              :     }
    5850              : 
    5851      4520123 :   if (expect_comma && !comma_first)
    5852              :     {
    5853              :       /* A comma is missing between the last attribute on the chain
    5854              :          and this one.  */
    5855            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5856              :                                  "expected %<)%>");
    5857            0 :       return error_mark_node;
    5858              :     }
    5859              : 
    5860              :   /* Add this attribute to the list.  */
    5861      4520123 :   attrs = chainon (attrs, attr);
    5862      4520123 :   return attrs;
    5863              : }
    5864              : 
    5865              : static tree
    5866    109360182 : c_parser_gnu_attributes (c_parser *parser)
    5867              : {
    5868    109360182 :   tree attrs = NULL_TREE;
    5869    162358403 :   while (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
    5870              :     {
    5871     52998231 :       bool save_translate_strings_p = parser->translate_strings_p;
    5872     52998231 :       parser->translate_strings_p = false;
    5873              :       /* Consume the `__attribute__' keyword.  */
    5874     52998231 :       c_parser_consume_token (parser);
    5875              :       /* Look for the two `(' tokens.  */
    5876     52998231 :       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
    5877              :         {
    5878            0 :           parser->translate_strings_p = save_translate_strings_p;
    5879            0 :           return attrs;
    5880              :         }
    5881     52998231 :       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
    5882              :         {
    5883            0 :           parser->translate_strings_p = save_translate_strings_p;
    5884            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    5885            0 :           return attrs;
    5886              :         }
    5887              :       /* Parse the attribute list.  Require a comma between successive
    5888              :          (possibly empty) attributes.  */
    5889              :       for (bool expect_comma = false; ; expect_comma = true)
    5890              :         {
    5891              :           /* Parse a single attribute.  */
    5892    188222153 :           tree attr = c_parser_gnu_attribute (parser, attrs, expect_comma);
    5893    188222153 :           if (attr == error_mark_node)
    5894              :             return attrs;
    5895    188222144 :           if (!attr)
    5896              :             break;
    5897              :           attrs = attr;
    5898              :       }
    5899              : 
    5900              :       /* Look for the two `)' tokens.  */
    5901     52998222 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5902     52998222 :         c_parser_consume_token (parser);
    5903              :       else
    5904              :         {
    5905            0 :           parser->translate_strings_p = save_translate_strings_p;
    5906            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5907              :                                      "expected %<)%>");
    5908            0 :           return attrs;
    5909              :         }
    5910     52998222 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    5911     52998221 :         c_parser_consume_token (parser);
    5912              :       else
    5913              :         {
    5914            1 :           parser->translate_strings_p = save_translate_strings_p;
    5915            1 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
    5916              :                                      "expected %<)%>");
    5917            1 :           return attrs;
    5918              :         }
    5919     52998221 :       parser->translate_strings_p = save_translate_strings_p;
    5920              :     }
    5921              : 
    5922              :   return attrs;
    5923              : }
    5924              : 
    5925              : /* Parse an optional balanced token sequence.
    5926              : 
    5927              :    balanced-token-sequence:
    5928              :      balanced-token
    5929              :      balanced-token-sequence balanced-token
    5930              : 
    5931              :    balanced-token:
    5932              :      ( balanced-token-sequence[opt] )
    5933              :      [ balanced-token-sequence[opt] ]
    5934              :      { balanced-token-sequence[opt] }
    5935              :      any token other than ()[]{}
    5936              : */
    5937              : 
    5938              : static void
    5939          142 : c_parser_balanced_token_sequence (c_parser *parser)
    5940              : {
    5941          551 :   while (true)
    5942              :     {
    5943          551 :       c_token *token = c_parser_peek_token (parser);
    5944          551 :       switch (token->type)
    5945              :         {
    5946            4 :         case CPP_OPEN_BRACE:
    5947            4 :           {
    5948            4 :             matching_braces braces;
    5949            4 :             braces.consume_open (parser);
    5950            4 :             c_parser_balanced_token_sequence (parser);
    5951            4 :             braces.require_close (parser);
    5952            4 :             break;
    5953              :           }
    5954              : 
    5955           42 :         case CPP_OPEN_PAREN:
    5956           42 :           {
    5957           42 :             matching_parens parens;
    5958           42 :             parens.consume_open (parser);
    5959           42 :             c_parser_balanced_token_sequence (parser);
    5960           42 :             parens.require_close (parser);
    5961           42 :             break;
    5962              :           }
    5963              : 
    5964           33 :         case CPP_OPEN_SQUARE:
    5965           33 :           c_parser_consume_token (parser);
    5966           33 :           c_parser_balanced_token_sequence (parser);
    5967           33 :           c_parser_require (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
    5968           33 :           break;
    5969              : 
    5970          142 :         case CPP_CLOSE_BRACE:
    5971          142 :         case CPP_CLOSE_PAREN:
    5972          142 :         case CPP_CLOSE_SQUARE:
    5973          142 :         case CPP_EOF:
    5974          142 :           return;
    5975              : 
    5976            1 :         case CPP_PRAGMA:
    5977            1 :           c_parser_consume_pragma (parser);
    5978            1 :           c_parser_skip_to_pragma_eol (parser, false);
    5979            1 :           break;
    5980              : 
    5981          329 :         default:
    5982          329 :           c_parser_consume_token (parser);
    5983          329 :           break;
    5984              :         }
    5985              :     }
    5986              : }
    5987              : 
    5988              : /* Parse arguments of omp::directive or omp::decl attribute.
    5989              : 
    5990              :    directive-name ,[opt] clause-list[opt]
    5991              : 
    5992              :    For directive just remember the tokens in a vector for subsequent
    5993              :    parsing.  */
    5994              : 
    5995              : static void
    5996          914 : c_parser_omp_directive_args (c_parser *parser, tree attribute, bool decl_p)
    5997              : {
    5998          914 :   unsigned int n = 1;
    5999          914 :   c_token *first = c_parser_peek_token (parser);
    6000          914 :   if (!c_parser_check_balanced_raw_token_sequence (parser, &n)
    6001          914 :       || (c_parser_peek_nth_token_raw (parser, n)->type
    6002              :           != CPP_CLOSE_PAREN))
    6003              :     {
    6004            1 :       c_parser_balanced_token_sequence (parser);
    6005            1 :       TREE_VALUE (attribute) = NULL_TREE;
    6006            3 :       return;
    6007              :     }
    6008          913 :   if (n == 1)
    6009              :     {
    6010            2 :       error_at (first->location, "expected OpenMP directive name");
    6011            2 :       TREE_VALUE (attribute) = NULL_TREE;
    6012            2 :       return;
    6013              :     }
    6014          911 :   vec<c_token, va_gc> *v;
    6015          911 :   vec_alloc (v, n - 1);
    6016        18777 :   for (--n; n; --n)
    6017              :     {
    6018        17866 :       c_token *tok = c_parser_peek_token (parser);
    6019        17866 :       v->quick_push (*tok);
    6020        17866 :       c_parser_consume_token (parser);
    6021              :     }
    6022          911 :   tree arg = make_node (C_TOKEN_VEC);
    6023          911 :   C_TOKEN_VEC_TOKENS (arg) = v;
    6024          911 :   if (decl_p)
    6025           58 :     TREE_PUBLIC (arg) = 1;
    6026          911 :   TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
    6027              : }
    6028              : 
    6029              : /* Parse arguments of omp::sequence attribute.
    6030              : 
    6031              :    omp::[opt] directive-attr [ , omp::[opt] directive-attr ]...  */
    6032              : 
    6033              : static void
    6034          157 : c_parser_omp_sequence_args (c_parser *parser, tree attribute)
    6035              : {
    6036          314 :   do
    6037              :     {
    6038          314 :       c_token *token = c_parser_peek_token (parser);
    6039          314 :       if (token->type == CPP_NAME
    6040          313 :           && strcmp (IDENTIFIER_POINTER (token->value), "omp") == 0
    6041          378 :           && c_parser_peek_2nd_token (parser)->type == CPP_SCOPE)
    6042              :         {
    6043           64 :           c_parser_consume_token (parser);
    6044           64 :           c_parser_consume_token (parser);
    6045           64 :           token = c_parser_peek_token (parser);
    6046              :         }
    6047          314 :       bool directive = false;
    6048          314 :       const char *p;
    6049          314 :       if (token->type != CPP_NAME)
    6050              :         p = "";
    6051              :       else
    6052          313 :         p = IDENTIFIER_POINTER (token->value);
    6053          314 :       if (strcmp (p, "directive") == 0)
    6054              :         directive = true;
    6055           12 :       else if (strcmp (p, "sequence") != 0)
    6056              :         {
    6057            7 :           error_at (token->location, "expected %<directive%> or %<sequence%>");
    6058            7 :           unsigned nesting_depth = 0;
    6059              : 
    6060           47 :           while (true)
    6061              :             {
    6062              :               /* Peek at the next token.  */
    6063           27 :               token = c_parser_peek_token (parser);
    6064              :               /* If we've reached the token we want, consume it and stop.  */
    6065           27 :               if ((token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
    6066           13 :                   && !nesting_depth)
    6067              :                 break;
    6068              :               /* If we've run out of tokens, stop.  */
    6069           20 :               if (token->type == CPP_EOF)
    6070              :                 break;
    6071           20 :               if (token->type == CPP_PRAGMA_EOL && parser->in_pragma)
    6072              :                 break;
    6073           20 :               if (token->type == CPP_OPEN_BRACE
    6074              :                   || token->type == CPP_OPEN_PAREN
    6075              :                   || token->type == CPP_OPEN_SQUARE)
    6076            6 :                 ++nesting_depth;
    6077              :               else if (token->type == CPP_CLOSE_BRACE
    6078              :                        || token->type == CPP_CLOSE_PAREN
    6079              :                        || token->type == CPP_CLOSE_SQUARE)
    6080              :                 {
    6081            6 :                   if (nesting_depth-- == 0)
    6082              :                     break;
    6083              :                 }
    6084              :               /* Consume this token.  */
    6085           20 :               c_parser_consume_token (parser);
    6086              :             }
    6087            7 :           if (c_parser_next_token_is_not (parser, CPP_COMMA))
    6088              :             break;
    6089            0 :           c_parser_consume_token (parser);
    6090            0 :           continue;
    6091            0 :         }
    6092          307 :       c_parser_consume_token (parser);
    6093          307 :       matching_parens parens;
    6094          307 :       if (parens.require_open (parser))
    6095              :         {
    6096          305 :           if (directive)
    6097          301 :             c_parser_omp_directive_args (parser, attribute, false);
    6098              :           else
    6099            4 :             c_parser_omp_sequence_args (parser, attribute);
    6100          305 :           parens.skip_until_found_close (parser);
    6101          305 :           if (c_parser_next_token_is_not (parser, CPP_COMMA))
    6102              :             break;
    6103          157 :           c_parser_consume_token (parser);
    6104              :         }
    6105            2 :       else if (c_parser_next_token_is_not (parser, CPP_COMMA))
    6106              :         break;
    6107              :       else
    6108            0 :         c_parser_consume_token (parser);
    6109              :     }
    6110              :   while (1);
    6111          157 : }
    6112              : 
    6113              : /* Parse standard (C23) attributes (including GNU attributes in the
    6114              :    gnu:: namespace).
    6115              : 
    6116              :    attribute-specifier-sequence:
    6117              :      attribute-specifier-sequence[opt] attribute-specifier
    6118              : 
    6119              :    attribute-specifier:
    6120              :      [ [ attribute-list ] ]
    6121              : 
    6122              :    attribute-list:
    6123              :      attribute[opt]
    6124              :      attribute-list, attribute[opt]
    6125              : 
    6126              :    attribute:
    6127              :      attribute-token attribute-argument-clause[opt]
    6128              : 
    6129              :    attribute-token:
    6130              :      standard-attribute
    6131              :      attribute-prefixed-token
    6132              : 
    6133              :    standard-attribute:
    6134              :      identifier
    6135              : 
    6136              :    attribute-prefixed-token:
    6137              :      attribute-prefix :: identifier
    6138              : 
    6139              :    attribute-prefix:
    6140              :      identifier
    6141              : 
    6142              :    attribute-argument-clause:
    6143              :      ( balanced-token-sequence[opt] )
    6144              : 
    6145              :    Keywords are accepted as identifiers for this purpose.
    6146              : 
    6147              :    As an extension, we permit an attribute-specifier to be:
    6148              : 
    6149              :      [ [ __extension__ attribute-list ] ]
    6150              : 
    6151              :    Two colons are then accepted as a synonym for ::.  No attempt is made
    6152              :    to check whether the colons are immediately adjacent.  LOOSE_SCOPE_P
    6153              :    indicates whether this relaxation is in effect.  */
    6154              : 
    6155              : static tree
    6156         2007 : c_parser_std_attribute (c_parser *parser, bool for_tm)
    6157              : {
    6158         2007 :   c_token *token = c_parser_peek_token (parser);
    6159         2007 :   tree ns, name, attribute;
    6160              : 
    6161              :   /* Parse the attribute-token.  */
    6162         2007 :   if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
    6163              :     {
    6164            2 :       c_parser_error (parser, "expected identifier");
    6165            2 :       return error_mark_node;
    6166              :     }
    6167         2005 :   name = canonicalize_attr_name (token->value);
    6168         2005 :   c_parser_consume_token (parser);
    6169         2005 :   if (c_parser_next_token_is (parser, CPP_SCOPE)
    6170         2467 :       || (c_parser_next_token_is (parser, CPP_COLON)
    6171           36 :           && (c_parser_peek_token (parser)->flags & COLON_SCOPE) != 0
    6172           10 :           && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
    6173              :     {
    6174         1553 :       ns = name;
    6175         1553 :       if (c_parser_next_token_is (parser, CPP_COLON))
    6176           10 :         c_parser_consume_token (parser);
    6177         1553 :       c_parser_consume_token (parser);
    6178         1553 :       token = c_parser_peek_token (parser);
    6179         1553 :       if (token->type != CPP_NAME && token->type != CPP_KEYWORD)
    6180              :         {
    6181            0 :           c_parser_error (parser, "expected identifier");
    6182            0 :           return error_mark_node;
    6183              :         }
    6184         1553 :       name = canonicalize_attr_name (token->value);
    6185         1553 :       c_parser_consume_token (parser);
    6186              :     }
    6187              :   else
    6188              :     ns = NULL_TREE;
    6189         2005 :   attribute = build_tree_list (build_tree_list (ns, name), NULL_TREE);
    6190              : 
    6191              :   /* Parse the arguments, if any.  */
    6192         2005 :   const attribute_spec *as = lookup_attribute_spec (TREE_PURPOSE (attribute));
    6193         2005 :   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
    6194              :     {
    6195         1056 :       if ((flag_openmp || flag_openmp_simd)
    6196            9 :           && ns
    6197            7 :           && is_attribute_p ("omp", ns)
    6198         1068 :           && (is_attribute_p ("directive", name)
    6199            2 :               || is_attribute_p ("sequence", name)
    6200            1 :               || is_attribute_p ("decl", name)))
    6201              :         {
    6202            3 :           error ("%<omp::%E%> attribute requires argument", name);
    6203            3 :           return error_mark_node;
    6204              :         }
    6205         1062 :       goto out;
    6206              :     }
    6207          940 :   {
    6208          940 :     location_t open_loc = c_parser_peek_token (parser)->location;
    6209          940 :     matching_parens parens;
    6210          940 :     parens.consume_open (parser);
    6211          132 :     if ((as && as->max_length == 0)
    6212              :         /* Special-case the transactional-memory attribute "outer",
    6213              :            which is specially handled but not registered as an
    6214              :            attribute, to avoid allowing arbitrary balanced token
    6215              :            sequences as arguments.  */
    6216         1049 :         || is_attribute_p ("outer", name))
    6217              :       {
    6218           24 :         error_at (open_loc, "%qE attribute does not take any arguments", name);
    6219           24 :         parens.skip_until_found_close (parser);
    6220          790 :         return error_mark_node;
    6221              :       }
    6222              :     /* If this is a fake attribute created to handle -Wno-attributes,
    6223              :        we must skip parsing the arguments.  */
    6224          916 :     if (as && !attribute_ignored_p (as))
    6225              :       {
    6226           96 :         bool takes_identifier
    6227              :           = (ns != NULL_TREE
    6228           75 :              && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
    6229          171 :              && attribute_takes_identifier_p (name));
    6230           21 :         bool require_string
    6231              :           = (ns == NULL_TREE
    6232           21 :              && (strcmp (IDENTIFIER_POINTER (name), "deprecated") == 0
    6233           11 :                  || strcmp (IDENTIFIER_POINTER (name), "nodiscard") == 0));
    6234           75 :         bool assume_attr
    6235              :           = (ns != NULL_TREE
    6236           75 :              && strcmp (IDENTIFIER_POINTER (ns), "gnu") == 0
    6237           75 :              && strcmp (IDENTIFIER_POINTER (name), "assume") == 0);
    6238          192 :         TREE_VALUE (attribute)
    6239           96 :           = c_parser_attribute_arguments (parser, takes_identifier,
    6240              :                                           require_string, assume_attr, false);
    6241              :       }
    6242              :     else
    6243              :       {
    6244           54 :         if ((flag_openmp || flag_openmp_simd)
    6245          766 :             && ns
    6246         1586 :             && is_attribute_p ("omp", ns))
    6247              :           {
    6248          766 :             if (is_attribute_p ("directive", name))
    6249              :               {
    6250          554 :                 c_parser_omp_directive_args (parser, attribute, false);
    6251          554 :                 parens.skip_until_found_close (parser);
    6252          554 :                 return attribute;
    6253              :               }
    6254          212 :             else if (is_attribute_p ("decl", name))
    6255              :               {
    6256           59 :                 TREE_VALUE (TREE_PURPOSE (attribute))
    6257           59 :                   = get_identifier ("directive");
    6258           59 :                 c_parser_omp_directive_args (parser, attribute, true);
    6259           59 :                 parens.skip_until_found_close (parser);
    6260           59 :                 return attribute;
    6261              :               }
    6262          153 :             else if (is_attribute_p ("sequence", name))
    6263              :               {
    6264          153 :                 TREE_VALUE (TREE_PURPOSE (attribute))
    6265          153 :                   = get_identifier ("directive");
    6266          153 :                 c_parser_omp_sequence_args (parser, attribute);
    6267          153 :                 parens.skip_until_found_close (parser);
    6268          153 :                 TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
    6269          153 :                 return attribute;
    6270              :               }
    6271              :           }
    6272           54 :         c_parser_balanced_token_sequence (parser);
    6273              :       }
    6274          150 :     parens.require_close (parser);
    6275              :   }
    6276         1212 :  out:
    6277         1212 :   if (ns == NULL_TREE && !for_tm && !as)
    6278              :     {
    6279              :       /* An attribute with standard syntax and no namespace specified
    6280              :          is a constraint violation if it is not one of the known
    6281              :          standard attributes.  Diagnose it here with a pedwarn and
    6282              :          then discard it to prevent a duplicate warning later.  */
    6283           72 :       pedwarn (input_location, OPT_Wattributes, "%qE attribute ignored",
    6284              :                name);
    6285           72 :       return error_mark_node;
    6286              :     }
    6287              :   return attribute;
    6288              : }
    6289              : 
    6290              : static tree
    6291         2117 : c_parser_std_attribute_list (c_parser *parser, bool for_tm)
    6292              : {
    6293         2117 :   tree attributes = NULL_TREE;
    6294         2351 :   while (true)
    6295              :     {
    6296         2351 :       c_token *token = c_parser_peek_token (parser);
    6297         2351 :       if (token->type == CPP_CLOSE_SQUARE)
    6298              :         break;
    6299         2135 :       if (token->type == CPP_COMMA)
    6300              :         {
    6301          128 :           c_parser_consume_token (parser);
    6302          128 :           continue;
    6303              :         }
    6304         2007 :       tree attribute = c_parser_std_attribute (parser, for_tm);
    6305         2007 :       if (attribute != error_mark_node)
    6306              :         {
    6307         1906 :           TREE_CHAIN (attribute) = attributes;
    6308         1906 :           attributes = attribute;
    6309              :         }
    6310         2007 :       if (c_parser_next_token_is_not (parser, CPP_COMMA))
    6311              :         break;
    6312              :     }
    6313         2117 :   return attributes;
    6314              : }
    6315              : 
    6316              : static tree
    6317         2117 : c_parser_std_attribute_specifier (c_parser *parser, bool for_tm)
    6318              : {
    6319         2117 :   location_t loc = c_parser_peek_token (parser)->location;
    6320         2117 :   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
    6321              :     return NULL_TREE;
    6322         2117 :   if (!c_parser_require (parser, CPP_OPEN_SQUARE, "expected %<[%>"))
    6323              :     {
    6324            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
    6325            0 :       return NULL_TREE;
    6326              :     }
    6327         2117 :   tree attributes;
    6328         2117 :   if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
    6329              :     {
    6330           42 :       auto ext = disable_extension_diagnostics ();
    6331           42 :       c_parser_consume_token (parser);
    6332           42 :       attributes = c_parser_std_attribute_list (parser, for_tm);
    6333           42 :       restore_extension_diagnostics (ext);
    6334              :     }
    6335              :   else
    6336              :     {
    6337         2075 :       if (!for_tm)
    6338         2055 :         pedwarn_c11 (loc, OPT_Wpedantic,
    6339              :                      "ISO C does not support %<[[]]%> attributes before C23");
    6340         2075 :       attributes = c_parser_std_attribute_list (parser, for_tm);
    6341              :     }
    6342         2117 :   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
    6343         2117 :   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, "expected %<]%>");
    6344         2117 :   return nreverse (attributes);
    6345              : }
    6346              : 
    6347              : /* Look past an optional balanced token sequence of raw look-ahead
    6348              :    tokens starting with the *Nth token.  *N is updated to point to the
    6349              :    following token.  Return true if such a sequence was found, false
    6350              :    if the tokens parsed were not balanced.  */
    6351              : 
    6352              : static bool
    6353        13319 : c_parser_check_balanced_raw_token_sequence (c_parser *parser, unsigned int *n)
    6354              : {
    6355        59022 :   while (true)
    6356              :     {
    6357        59022 :       c_token *token = c_parser_peek_nth_token_raw (parser, *n);
    6358        59022 :       switch (token->type)
    6359              :         {
    6360           66 :         case CPP_OPEN_BRACE:
    6361           66 :           {
    6362           66 :             ++*n;
    6363           66 :             if (c_parser_check_balanced_raw_token_sequence (parser, n))
    6364              :               {
    6365           66 :                 token = c_parser_peek_nth_token_raw (parser, *n);
    6366           66 :                 if (token->type == CPP_CLOSE_BRACE)
    6367           66 :                   ++*n;
    6368              :                 else
    6369              :                   return false;
    6370              :               }
    6371              :             else
    6372              :               return false;
    6373           66 :             break;
    6374              :           }
    6375              : 
    6376        10693 :         case CPP_OPEN_PAREN:
    6377        10693 :           {
    6378        10693 :             ++*n;
    6379        10693 :             if (c_parser_check_balanced_raw_token_sequence (parser, n))
    6380              :               {
    6381        10693 :                 token = c_parser_peek_nth_token_raw (parser, *n);
    6382        10693 :                 if (token->type == CPP_CLOSE_PAREN)
    6383        10693 :                   ++*n;
    6384              :                 else
    6385              :                   return false;
    6386              :               }
    6387              :             else
    6388              :               return false;
    6389        10693 :             break;
    6390              :           }
    6391              : 
    6392           79 :         case CPP_OPEN_SQUARE:
    6393           79 :           {
    6394           79 :             ++*n;
    6395           79 :             if (c_parser_check_balanced_raw_token_sequence (parser, n))
    6396              :               {
    6397           79 :                 token = c_parser_peek_nth_token_raw (parser, *n);
    6398           79 :                 if (token->type == CPP_CLOSE_SQUARE)
    6399           79 :                   ++*n;
    6400              :                 else
    6401              :                   return false;
    6402              :               }
    6403              :             else
    6404              :               return false;
    6405           79 :             break;
    6406              :           }
    6407              : 
    6408              :         case CPP_CLOSE_BRACE:
    6409              :         case CPP_CLOSE_PAREN:
    6410              :         case CPP_CLOSE_SQUARE:
    6411              :         case CPP_EOF:
    6412              :           return true;
    6413              : 
    6414        34865 :         default:
    6415        34865 :           ++*n;
    6416        34865 :           break;
    6417              :         }
    6418              :     }
    6419              : }
    6420              : 
    6421              : /* Return whether standard attributes start with the Nth token.  */
    6422              : 
    6423              : static bool
    6424    891447559 : c_parser_nth_token_starts_std_attributes (c_parser *parser, unsigned int n)
    6425              : {
    6426    891447559 :   if (!(c_parser_peek_nth_token (parser, n)->type == CPP_OPEN_SQUARE
    6427      2322717 :         && c_parser_peek_nth_token (parser, n + 1)->type == CPP_OPEN_SQUARE))
    6428    891444836 :     return false;
    6429              :   /* In C, '[[' must start attributes.  In Objective-C, we need to
    6430              :      check whether '[[' is matched by ']]'.  */
    6431         2723 :   if (!c_dialect_objc ())
    6432              :     return true;
    6433            0 :   n += 2;
    6434            0 :   if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
    6435              :     return false;
    6436            0 :   c_token *token = c_parser_peek_nth_token_raw (parser, n);
    6437            0 :   if (token->type != CPP_CLOSE_SQUARE)
    6438              :     return false;
    6439            0 :   token = c_parser_peek_nth_token_raw (parser, n + 1);
    6440            0 :   return token->type == CPP_CLOSE_SQUARE;
    6441              : }
    6442              : 
    6443              : /* Skip standard attribute tokens starting at Nth token (with 1 as the
    6444              :    next token), return index of the first token after the standard
    6445              :    attribute tokens, or N on failure.  */
    6446              : 
    6447              : static size_t
    6448          329 : c_parser_skip_std_attribute_spec_seq (c_parser *parser, size_t n)
    6449              : {
    6450          329 :   size_t orig_n = n;
    6451          361 :   while (true)
    6452              :     {
    6453          345 :       if (c_parser_peek_nth_token_raw (parser, n)->type == CPP_OPEN_SQUARE
    6454          345 :           && (c_parser_peek_nth_token_raw (parser, n + 1)->type
    6455              :               == CPP_OPEN_SQUARE))
    6456              :         {
    6457           16 :           unsigned int m = n + 2;
    6458           16 :           if (!c_parser_check_balanced_raw_token_sequence (parser, &m))
    6459            0 :             return orig_n;
    6460           16 :           c_token *token = c_parser_peek_nth_token_raw (parser, m);
    6461           16 :           if (token->type != CPP_CLOSE_SQUARE)
    6462              :             return orig_n;
    6463           16 :           token = c_parser_peek_nth_token_raw (parser, m + 1);
    6464           16 :           if (token->type != CPP_CLOSE_SQUARE)
    6465              :             return orig_n;
    6466           16 :           n = m + 2;
    6467              :         }
    6468              :       else
    6469              :         break;
    6470           16 :     }
    6471              :   return n;
    6472              : }
    6473              : 
    6474              : static tree
    6475         2036 : c_parser_std_attribute_specifier_sequence (c_parser *parser)
    6476              : {
    6477         2036 :   tree attributes = NULL_TREE;
    6478         2097 :   do
    6479              :     {
    6480         2097 :       tree attrs = c_parser_std_attribute_specifier (parser, false);
    6481         2097 :       attributes = chainon (attributes, attrs);
    6482              :     }
    6483         2097 :   while (c_parser_nth_token_starts_std_attributes (parser, 1));
    6484         2036 :   return attributes;
    6485              : }
    6486              : 
    6487              : /* Parse a type name (C90 6.5.5, C99 6.7.6, C11 6.7.7).  ALIGNAS_OK
    6488              :    says whether alignment specifiers are OK (only in cases that might
    6489              :    be the type name of a compound literal).
    6490              : 
    6491              :    type-name:
    6492              :      specifier-qualifier-list abstract-declarator[opt]
    6493              : */
    6494              : 
    6495              : struct c_type_name *
    6496    121326681 : c_parser_type_name (c_parser *parser, bool alignas_ok)
    6497              : {
    6498    121326681 :   struct c_declspecs *specs = build_null_declspecs ();
    6499    121326681 :   struct c_declarator *declarator;
    6500    121326681 :   struct c_type_name *ret;
    6501    121326681 :   bool dummy = false;
    6502    121326681 :   c_parser_declspecs (parser, specs, false, true, true, alignas_ok, false,
    6503              :                       false, true, cla_prefer_type);
    6504    121326681 :   if (!specs->declspecs_seen_p)
    6505              :     {
    6506            4 :       c_parser_error (parser, "expected specifier-qualifier-list");
    6507            4 :       return NULL;
    6508              :     }
    6509    121326677 :   if (specs->type != error_mark_node)
    6510              :     {
    6511    121326660 :       pending_xref_error ();
    6512    121326660 :       finish_declspecs (specs);
    6513              :       /* When the typename is declared, its type is a top level type, we should
    6514              :          call verify_counted_by_for_top_anonymous_type.  */
    6515    121326660 :       if (specs->typespec_kind == ctsk_tagdef)
    6516         1664 :         verify_counted_by_for_top_anonymous_type (specs->type);
    6517              :     }
    6518    242653354 :   declarator = c_parser_declarator (parser,
    6519    121326677 :                                     specs->typespec_kind != ctsk_none,
    6520              :                                     C_DTR_ABSTRACT, &dummy);
    6521    121326677 :   if (declarator == NULL)
    6522              :     return NULL;
    6523    121326672 :   ret = XOBNEW (&parser_obstack, struct c_type_name);
    6524    121326672 :   ret->specs = specs;
    6525    121326672 :   ret->declarator = declarator;
    6526    121326672 :   return ret;
    6527              : }
    6528              : 
    6529              : /* Parse an initializer (C90 6.5.7, C99 6.7.8, C11 6.7.9).
    6530              : 
    6531              :    initializer:
    6532              :      assignment-expression
    6533              :      { initializer-list }
    6534              :      { initializer-list , }
    6535              : 
    6536              :    initializer-list:
    6537              :      designation[opt] initializer
    6538              :      initializer-list , designation[opt] initializer
    6539              : 
    6540              :    designation:
    6541              :      designator-list =
    6542              : 
    6543              :    designator-list:
    6544              :      designator
    6545              :      designator-list designator
    6546              : 
    6547              :    designator:
    6548              :      array-designator
    6549              :      . identifier
    6550              : 
    6551              :    array-designator:
    6552              :      [ constant-expression ]
    6553              : 
    6554              :    GNU extensions:
    6555              : 
    6556              :    initializer:
    6557              :      { }
    6558              : 
    6559              :    designation:
    6560              :      array-designator
    6561              :      identifier :
    6562              : 
    6563              :    array-designator:
    6564              :      [ constant-expression ... constant-expression ]
    6565              : 
    6566              :    Any expression without commas is accepted in the syntax for the
    6567              :    constant-expressions, with non-constant expressions rejected later.
    6568              : 
    6569              :    DECL is the declaration we're parsing this initializer for.
    6570              : 
    6571              :    This function is only used for top-level initializers; for nested
    6572              :    ones, see c_parser_initval.  */
    6573              : 
    6574              : static struct c_expr
    6575      6335315 : c_parser_initializer (c_parser *parser, tree decl)
    6576              : {
    6577      6335315 :   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    6578       105376 :     return c_parser_braced_init (parser, NULL_TREE, false, NULL,
    6579       105376 :                                  decl != error_mark_node
    6580       210752 :                                  && C_DECL_VARIABLE_SIZE (decl));
    6581              :   else
    6582              :     {
    6583      6229939 :       struct c_expr ret;
    6584      6229939 :       location_t loc = c_parser_peek_token (parser)->location;
    6585      6229939 :       ret = c_parser_expr_no_commas (parser, NULL);
    6586      6229937 :       if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl))
    6587              :         {
    6588            2 :           error_at (loc,
    6589              :                     "variable-sized object may not be initialized except "
    6590              :                     "with an empty initializer");
    6591            2 :           ret.set_error ();
    6592              :         }
    6593              :       /* This is handled mostly by gimplify.cc, but we have to deal with
    6594              :          not warning about int x = x; as it is a GCC extension to turn off
    6595              :          this warning but only if warn_init_self is zero.  */
    6596      6229937 :       if (VAR_P (decl)
    6597      6229889 :           && !DECL_EXTERNAL (decl)
    6598      6229889 :           && !TREE_STATIC (decl)
    6599      6110716 :           && ret.value == decl
    6600      6319119 :           && !warning_enabled_at (DECL_SOURCE_LOCATION (decl), OPT_Winit_self))
    6601        89175 :         suppress_warning (decl, OPT_Winit_self);
    6602      6229937 :       if (TREE_CODE (ret.value) != STRING_CST
    6603      6229937 :           && (TREE_CODE (ret.value) != COMPOUND_LITERAL_EXPR
    6604        95398 :               || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
    6605              :                                             (ret.value))))
    6606      6120553 :         ret = convert_lvalue_to_rvalue (loc, ret, true, true, true);
    6607      6229937 :       return ret;
    6608              :     }
    6609              : }
    6610              : 
    6611              : /* The location of the last comma within the current initializer list,
    6612              :    or UNKNOWN_LOCATION if not within one.  */
    6613              : 
    6614              : location_t last_init_list_comma;
    6615              : 
    6616              : /* Parse a braced initializer list.  TYPE is the type specified for a
    6617              :    compound literal, and NULL_TREE for other initializers and for
    6618              :    nested braced lists.  NESTED_P is true for nested braced lists,
    6619              :    false for the list of a compound literal or the list that is the
    6620              :    top-level initializer in a declaration.  VARSIZE_P indicates
    6621              :    wether the object to be initialized has a variable size.  */
    6622              : 
    6623              : static struct c_expr
    6624      1362714 : c_parser_braced_init (c_parser *parser, tree type, bool nested_p,
    6625              :                       struct obstack *outer_obstack, bool varsize_p)
    6626              : {
    6627      1362714 :   struct c_expr ret;
    6628      1362714 :   struct obstack braced_init_obstack;
    6629      1362714 :   location_t brace_loc = c_parser_peek_token (parser)->location;
    6630      1362714 :   gcc_obstack_init (&braced_init_obstack);
    6631      1362714 :   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
    6632      1362714 :   bool save_c_omp_array_section_p = c_omp_array_section_p;
    6633      1362714 :   c_omp_array_section_p = false;
    6634      1362714 :   bool zero_init_padding_bits = false;
    6635      1362714 :   matching_braces braces;
    6636      1362714 :   braces.consume_open (parser);
    6637      1362714 :   if (nested_p)
    6638              :     {
    6639       339617 :       finish_implicit_inits (brace_loc, outer_obstack);
    6640       339617 :       push_init_level (brace_loc, 0, &braced_init_obstack);
    6641              :     }
    6642              :   else
    6643      1023097 :     really_start_incremental_init (type);
    6644      1362714 :   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    6645              :     {
    6646         2615 :       pedwarn_c11 (brace_loc, OPT_Wpedantic,
    6647              :                    "ISO C forbids empty initializer braces before C23");
    6648         2615 :       if (flag_isoc23)
    6649      1362714 :         zero_init_padding_bits = true;
    6650              :     }
    6651              :   else
    6652              :     {
    6653      1360099 :       if (varsize_p)
    6654           61 :         error_at (brace_loc,
    6655              :                   "variable-sized object may not be initialized except "
    6656              :                   "with an empty initializer");
    6657              :       /* Parse a non-empty initializer list, possibly with a trailing
    6658              :          comma.  */
    6659      8891123 :       while (true)
    6660              :         {
    6661      8891123 :           c_parser_initelt (parser, &braced_init_obstack);
    6662      8891123 :           if (parser->error)
    6663              :             break;
    6664      8891093 :           if (c_parser_next_token_is (parser, CPP_COMMA))
    6665              :             {
    6666      7533730 :               last_init_list_comma = c_parser_peek_token (parser)->location;
    6667      7533730 :               c_parser_consume_token (parser);
    6668              :               /* CPP_EMBED should be always in between two CPP_COMMA
    6669              :                  tokens.  */
    6670     15067563 :               while (c_parser_next_token_is (parser, CPP_EMBED))
    6671              :                 {
    6672          103 :                   c_token *embed = c_parser_peek_token (parser);
    6673          103 :                   c_parser_consume_token (parser);
    6674          103 :                   c_expr embed_val;
    6675          103 :                   embed_val.value = embed->value;
    6676          103 :                   embed_val.original_code = RAW_DATA_CST;
    6677          103 :                   embed_val.original_type = integer_type_node;
    6678          103 :                   set_c_expr_source_range (&embed_val, embed->get_range ());
    6679          103 :                   embed_val.m_decimal = 0;
    6680          103 :                   process_init_element (embed->location, embed_val, false,
    6681              :                                         &braced_init_obstack);
    6682          103 :                   gcc_checking_assert (c_parser_next_token_is (parser,
    6683              :                                                                CPP_COMMA));
    6684          103 :                   last_init_list_comma = c_parser_peek_token (parser)->location;
    6685          103 :                   c_parser_consume_token (parser);
    6686              :                 }
    6687              :             }
    6688              :           else
    6689              :             break;
    6690      7533730 :           if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    6691              :             break;
    6692              :         }
    6693              :     }
    6694      1362714 :   c_omp_array_section_p = save_c_omp_array_section_p;
    6695      1362714 :   c_token *next_tok = c_parser_peek_token (parser);
    6696      1362714 :   if (next_tok->type != CPP_CLOSE_BRACE)
    6697              :     {
    6698           31 :       ret.set_error ();
    6699           31 :       ret.original_code = ERROR_MARK;
    6700           31 :       ret.original_type = NULL;
    6701           31 :       braces.skip_until_found_close (parser);
    6702           31 :       pop_init_level (brace_loc, 0, &braced_init_obstack, last_init_list_comma);
    6703           31 :       obstack_free (&braced_init_obstack, NULL);
    6704              :       return ret;
    6705              :     }
    6706      1362683 :   location_t close_loc = next_tok->location;
    6707      1362683 :   c_parser_consume_token (parser);
    6708      1362683 :   ret = pop_init_level (brace_loc, 0, &braced_init_obstack, close_loc);
    6709      1362683 :   if (zero_init_padding_bits
    6710         2358 :       && ret.value
    6711         2291 :       && TREE_CODE (ret.value) == CONSTRUCTOR)
    6712         2196 :     CONSTRUCTOR_ZERO_PADDING_BITS (ret.value) = 1;
    6713      1362683 :   obstack_free (&braced_init_obstack, NULL);
    6714      1362683 :   set_c_expr_source_range (&ret, brace_loc, close_loc);
    6715      1362683 :   return ret;
    6716              : }
    6717              : 
    6718              : /* Parse a nested initializer, including designators.  */
    6719              : 
    6720              : static void
    6721      8891123 : c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
    6722              : {
    6723              :   /* Parse any designator or designator list.  A single array
    6724              :      designator may have the subsequent "=" omitted in GNU C, but a
    6725              :      longer list or a structure member designator may not.  */
    6726      8891123 :   if (c_parser_next_token_is (parser, CPP_NAME)
    6727      8891123 :       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
    6728              :     {
    6729              :       /* Old-style structure member designator.  */
    6730          156 :       set_init_label (c_parser_peek_token (parser)->location,
    6731          156 :                       c_parser_peek_token (parser)->value,
    6732          156 :                       c_parser_peek_token (parser)->location,
    6733              :                       braced_init_obstack);
    6734              :       /* Use the colon as the error location.  */
    6735          156 :       pedwarn (c_parser_peek_2nd_token (parser)->location, OPT_Wpedantic,
    6736              :                "obsolete use of designated initializer with %<:%>");
    6737          156 :       c_parser_consume_token (parser);
    6738          156 :       c_parser_consume_token (parser);
    6739              :     }
    6740              :   else
    6741              :     {
    6742              :       /* des_seen is 0 if there have been no designators, 1 if there
    6743              :          has been a single array designator and 2 otherwise.  */
    6744              :       int des_seen = 0;
    6745              :       /* Location of a designator.  */
    6746              :       location_t des_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
    6747      8924763 :       while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE)
    6748     17848377 :              || c_parser_next_token_is (parser, CPP_DOT))
    6749              :         {
    6750        33796 :           int des_prev = des_seen;
    6751        33796 :           if (!des_seen)
    6752        33218 :             des_loc = c_parser_peek_token (parser)->location;
    6753        33796 :           if (des_seen < 2)
    6754        33296 :             des_seen++;
    6755        33796 :           if (c_parser_next_token_is (parser, CPP_DOT))
    6756              :             {
    6757        32647 :               des_seen = 2;
    6758        32647 :               c_parser_consume_token (parser);
    6759        32647 :               if (c_parser_next_token_is (parser, CPP_NAME))
    6760              :                 {
    6761        32647 :                   set_init_label (des_loc, c_parser_peek_token (parser)->value,
    6762        32647 :                                   c_parser_peek_token (parser)->location,
    6763              :                                   braced_init_obstack);
    6764        32647 :                   c_parser_consume_token (parser);
    6765              :                 }
    6766              :               else
    6767              :                 {
    6768            0 :                   struct c_expr init;
    6769            0 :                   init.set_error ();
    6770            0 :                   init.original_code = ERROR_MARK;
    6771            0 :                   init.original_type = NULL;
    6772            0 :                   c_parser_error (parser, "expected identifier");
    6773            0 :                   c_parser_skip_until_found (parser, CPP_COMMA, NULL);
    6774            0 :                   process_init_element (input_location, init, false,
    6775              :                                         braced_init_obstack);
    6776            0 :                   return;
    6777              :                 }
    6778              :             }
    6779              :           else
    6780              :             {
    6781         1149 :               struct c_expr first_expr;
    6782         1149 :               tree first, second;
    6783         1149 :               location_t ellipsis_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
    6784         1149 :               location_t array_index_loc = UNKNOWN_LOCATION;
    6785              :               /* ??? Following the old parser, [ objc-receiver
    6786              :                  objc-message-args ] is accepted as an initializer,
    6787              :                  being distinguished from a designator by what follows
    6788              :                  the first assignment expression inside the square
    6789              :                  brackets, but after a first array designator a
    6790              :                  subsequent square bracket is for Objective-C taken to
    6791              :                  start an expression, using the obsolete form of
    6792              :                  designated initializer without '=', rather than
    6793              :                  possibly being a second level of designation: in LALR
    6794              :                  terms, the '[' is shifted rather than reducing
    6795              :                  designator to designator-list.  */
    6796         1149 :               if (des_prev == 1 && c_dialect_objc ())
    6797              :                 {
    6798            0 :                   des_seen = des_prev;
    6799            0 :                   break;
    6800              :                 }
    6801         1149 :               if (des_prev == 0 && c_dialect_objc ())
    6802              :                 {
    6803              :                   /* This might be an array designator or an
    6804              :                      Objective-C message expression.  If the former,
    6805              :                      continue parsing here; if the latter, parse the
    6806              :                      remainder of the initializer given the starting
    6807              :                      primary-expression.  ??? It might make sense to
    6808              :                      distinguish when des_prev == 1 as well; see
    6809              :                      previous comment.  */
    6810            0 :                   tree rec, args;
    6811            0 :                   struct c_expr mexpr;
    6812            0 :                   c_parser_consume_token (parser);
    6813            0 :                   if (c_parser_peek_token (parser)->type == CPP_NAME
    6814            0 :                       && ((c_parser_peek_token (parser)->id_kind
    6815              :                            == C_ID_TYPENAME)
    6816            0 :                           || (c_parser_peek_token (parser)->id_kind
    6817              :                               == C_ID_CLASSNAME)))
    6818              :                     {
    6819              :                       /* Type name receiver.  */
    6820            0 :                       tree id = c_parser_peek_token (parser)->value;
    6821            0 :                       c_parser_consume_token (parser);
    6822            0 :                       rec = objc_get_class_reference (id);
    6823            0 :                       goto parse_message_args;
    6824              :                     }
    6825            0 :                   array_index_loc = c_parser_peek_token (parser)->location;
    6826            0 :                   first_expr = c_parser_expr_no_commas (parser, NULL);
    6827            0 :                   mark_exp_read (first_expr.value);
    6828            0 :                   if (c_parser_next_token_is (parser, CPP_ELLIPSIS)
    6829            0 :                       || c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
    6830            0 :                     goto array_desig_after_first;
    6831            0 :                   first = first_expr.value;
    6832              :                   /* Expression receiver.  So far only one part
    6833              :                      without commas has been parsed; there might be
    6834              :                      more of the expression.  */
    6835              :                   rec = first;
    6836            0 :                   while (c_parser_next_token_is (parser, CPP_COMMA))
    6837              :                     {
    6838            0 :                       struct c_expr next;
    6839            0 :                       location_t comma_loc, exp_loc;
    6840            0 :                       comma_loc = c_parser_peek_token (parser)->location;
    6841            0 :                       c_parser_consume_token (parser);
    6842            0 :                       exp_loc = c_parser_peek_token (parser)->location;
    6843            0 :                       next = c_parser_expr_no_commas (parser, NULL);
    6844            0 :                       next = convert_lvalue_to_rvalue (exp_loc, next,
    6845              :                                                        true, true);
    6846            0 :                       rec = build_compound_expr (comma_loc, rec, next.value);
    6847              :                     }
    6848            0 :                 parse_message_args:
    6849              :                   /* Now parse the objc-message-args.  */
    6850            0 :                   args = c_parser_objc_message_args (parser);
    6851            0 :                   c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
    6852              :                                              "expected %<]%>");
    6853            0 :                   mexpr.value
    6854            0 :                     = objc_build_message_expr (rec, args);
    6855            0 :                   mexpr.original_code = ERROR_MARK;
    6856            0 :                   mexpr.original_type = NULL;
    6857            0 :                   mexpr.m_decimal = 0;
    6858              :                   /* Now parse and process the remainder of the
    6859              :                      initializer, starting with this message
    6860              :                      expression as a primary-expression.  */
    6861            0 :                   c_parser_initval (parser, &mexpr, braced_init_obstack);
    6862            0 :                   return;
    6863              :                 }
    6864         1149 :               c_parser_consume_token (parser);
    6865         1149 :               array_index_loc = c_parser_peek_token (parser)->location;
    6866         1149 :               first_expr = c_parser_expr_no_commas (parser, NULL);
    6867         1149 :               mark_exp_read (first_expr.value);
    6868         1149 :             array_desig_after_first:
    6869         1149 :               first_expr = convert_lvalue_to_rvalue (array_index_loc,
    6870              :                                                      first_expr,
    6871              :                                                      true, true);
    6872         1149 :               first = first_expr.value;
    6873         1149 :               if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
    6874              :                 {
    6875          397 :                   ellipsis_loc = c_parser_peek_token (parser)->location;
    6876          397 :                   c_parser_consume_token (parser);
    6877          397 :                   second = convert_lvalue_to_rvalue (ellipsis_loc,
    6878              :                                                      (c_parser_expr_no_commas
    6879              :                                                       (parser, NULL)),
    6880              :                                                      true, true).value;
    6881          397 :                   mark_exp_read (second);
    6882              :                 }
    6883              :               else
    6884              :                 second = NULL_TREE;
    6885         1149 :               if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
    6886              :                 {
    6887         1149 :                   c_parser_consume_token (parser);
    6888         1149 :                   set_init_index (array_index_loc, first, second,
    6889              :                                   braced_init_obstack);
    6890         1149 :                   if (second)
    6891          397 :                     pedwarn (ellipsis_loc, OPT_Wpedantic,
    6892              :                              "ISO C forbids specifying range of elements to initialize");
    6893              :                 }
    6894              :               else
    6895            0 :                 c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
    6896              :                                            "expected %<]%>");
    6897              :             }
    6898              :         }
    6899      8890967 :       if (des_seen >= 1)
    6900              :         {
    6901        33218 :           if (c_parser_next_token_is (parser, CPP_EQ))
    6902              :             {
    6903        33197 :               pedwarn_c90 (des_loc, OPT_Wpedantic,
    6904              :                            "ISO C90 forbids specifying subobject "
    6905              :                            "to initialize");
    6906        33197 :               c_parser_consume_token (parser);
    6907              :             }
    6908              :           else
    6909              :             {
    6910           21 :               if (des_seen == 1)
    6911           19 :                 pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
    6912              :                          "obsolete use of designated initializer without %<=%>");
    6913              :               else
    6914              :                 {
    6915            2 :                   struct c_expr init;
    6916            2 :                   init.set_error ();
    6917            2 :                   init.original_code = ERROR_MARK;
    6918            2 :                   init.original_type = NULL;
    6919            2 :                   c_parser_error (parser, "expected %<=%>");
    6920            2 :                   c_parser_skip_until_found (parser, CPP_COMMA, NULL);
    6921            2 :                   process_init_element (input_location, init, false,
    6922              :                                         braced_init_obstack);
    6923            2 :                   return;
    6924              :                 }
    6925              :             }
    6926              :         }
    6927              :     }
    6928      8891121 :   c_parser_initval (parser, NULL, braced_init_obstack);
    6929              : }
    6930              : 
    6931              : /* Parse a nested initializer; as c_parser_initializer but parses
    6932              :    initializers within braced lists, after any designators have been
    6933              :    applied.  If AFTER is not NULL then it is an Objective-C message
    6934              :    expression which is the primary-expression starting the
    6935              :    initializer.  */
    6936              : 
    6937              : static void
    6938      8891121 : c_parser_initval (c_parser *parser, struct c_expr *after,
    6939              :                   struct obstack * braced_init_obstack)
    6940              : {
    6941      8891121 :   struct c_expr init;
    6942      8891121 :   gcc_assert (!after || c_dialect_objc ());
    6943      8891121 :   location_t loc = c_parser_peek_token (parser)->location;
    6944              : 
    6945      8891121 :   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
    6946       339617 :     init = c_parser_braced_init (parser, NULL_TREE, true,
    6947              :                                  braced_init_obstack, false);
    6948              :   else
    6949              :     {
    6950      8551504 :       init = c_parser_expr_no_commas (parser, after);
    6951      8551504 :       if (init.value != NULL_TREE
    6952      8551504 :           && TREE_CODE (init.value) != STRING_CST
    6953     17061487 :           && (TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR
    6954          177 :               || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL
    6955              :                                             (init.value))))
    6956      8509811 :         init = convert_lvalue_to_rvalue (loc, init, true, true, true);
    6957              :     }
    6958      8891121 :   tree val = init.value;
    6959      8891121 :   process_init_element (loc, init, false, braced_init_obstack);
    6960              : 
    6961              :   /* Attempt to optimize large char array initializers into RAW_DATA_CST
    6962              :      to save compile time and memory even when not using #embed.  */
    6963      8891121 :   static unsigned vals_to_ignore;
    6964      8891121 :   if (vals_to_ignore)
    6965              :     /* If earlier call determined there is certain number of CPP_COMMA
    6966              :        CPP_NUMBER tokens with 0-255 int values, but not enough for
    6967              :        RAW_DATA_CST to be beneficial, don't try to check it again until
    6968              :        they are all parsed.  */
    6969         6022 :     --vals_to_ignore;
    6970      8885099 :   else if (val
    6971      8884973 :            && TREE_CODE (val) == INTEGER_CST
    6972      4191393 :            && TREE_TYPE (val) == integer_type_node
    6973     12527818 :            && c_parser_next_token_is (parser, CPP_COMMA))
    6974      2983582 :     if (unsigned int len = c_maybe_optimize_large_byte_initializer ())
    6975              :       {
    6976         8525 :         char buf1[64];
    6977         8525 :         unsigned int i;
    6978         8525 :         gcc_checking_assert (len >= 64);
    6979              :         location_t last_loc = UNKNOWN_LOCATION;
    6980        20115 :         for (i = 0; i < 64; ++i)
    6981              :           {
    6982        20022 :             c_token *tok = c_parser_peek_nth_token_raw (parser, 1 + 2 * i);
    6983        20022 :             if (tok->type != CPP_COMMA)
    6984              :               break;
    6985        19225 :             tok = c_parser_peek_nth_token_raw (parser, 2 + 2 * i);
    6986        19225 :             if (tok->type != CPP_NUMBER
    6987        11590 :                 || TREE_CODE (tok->value) != INTEGER_CST
    6988        11590 :                 || TREE_TYPE (tok->value) != integer_type_node
    6989        11590 :                 || wi::neg_p (wi::to_wide (tok->value))
    6990        30815 :                 || wi::to_widest (tok->value) > UCHAR_MAX)
    6991              :               break;
    6992        11590 :             buf1[i] = (char) tree_to_uhwi (tok->value);
    6993        11590 :             if (i == 0)
    6994         1108 :               loc = tok->location;
    6995        11590 :             last_loc = tok->location;
    6996              :           }
    6997         8525 :         if (i < 64)
    6998              :           {
    6999         8432 :             vals_to_ignore = i;
    7000         8438 :             return;
    7001              :           }
    7002           93 :         c_token *tok = c_parser_peek_nth_token_raw (parser, 1 + 2 * i);
    7003              :         /* If 64 CPP_COMMA CPP_NUMBER pairs are followed by CPP_CLOSE_BRACE,
    7004              :            punt if len is INT_MAX as that can mean this is a flexible array
    7005              :            member and in that case we need one CPP_NUMBER afterwards
    7006              :            (as guaranteed for CPP_EMBED).  */
    7007           93 :         if (tok->type == CPP_CLOSE_BRACE && len != INT_MAX)
    7008              :           len = i;
    7009           91 :         else if (tok->type != CPP_COMMA
    7010           91 :                  || (c_parser_peek_nth_token_raw (parser, 2 + 2 * i)->type
    7011              :                      != CPP_NUMBER))
    7012              :           {
    7013            6 :             vals_to_ignore = i;
    7014            6 :             return;
    7015              :           }
    7016              :         /* Ensure the STRING_CST fits into 128K.  */
    7017           87 :         unsigned int max_len = 131072 - offsetof (struct tree_string, str) - 1;
    7018           87 :         unsigned int orig_len = len;
    7019           87 :         unsigned int off = 0, last = 0;
    7020           87 :         if (!wi::neg_p (wi::to_wide (val)) && wi::to_widest (val) <= UCHAR_MAX)
    7021           79 :           off = 1;
    7022           87 :         len = MIN (len, max_len - off);
    7023           87 :         char *buf2 = XNEWVEC (char, len + off);
    7024           87 :         if (off)
    7025           79 :           buf2[0] = (char) tree_to_uhwi (val);
    7026           87 :         memcpy (buf2 + off, buf1, i);
    7027         5655 :         for (unsigned int j = 0; j < i; ++j)
    7028              :           {
    7029         5568 :             c_parser_peek_token (parser);
    7030         5568 :             c_parser_consume_token (parser);
    7031         5568 :             c_parser_peek_token (parser);
    7032         5568 :             c_parser_consume_token (parser);
    7033              :           }
    7034        18780 :         for (; i < len; ++i)
    7035              :           {
    7036        18743 :             if (!c_parser_next_token_is (parser, CPP_COMMA))
    7037              :               break;
    7038        18741 :             tok = c_parser_peek_2nd_token (parser);
    7039        18741 :             if (tok->type != CPP_NUMBER
    7040        18733 :                 || TREE_CODE (tok->value) != INTEGER_CST
    7041        18733 :                 || TREE_TYPE (tok->value) != integer_type_node
    7042        18733 :                 || wi::neg_p (wi::to_wide (tok->value))
    7043        37474 :                 || wi::to_widest (tok->value) > UCHAR_MAX)
    7044              :               break;
    7045        18733 :             c_token *tok2 = c_parser_peek_nth_token (parser, 3);
    7046        18733 :             if (tok2->type != CPP_COMMA && tok2->type != CPP_CLOSE_BRACE)
    7047              :               break;
    7048        18730 :             buf2[i + off] = (char) tree_to_uhwi (tok->value);
    7049              :             /* If orig_len is INT_MAX, this can be flexible array member and
    7050              :                in that case we need to ensure another element which
    7051              :                for CPP_EMBED is normally guaranteed after it.  Include
    7052              :                that byte in the RAW_DATA_OWNER though, so it can be optimized
    7053              :                later.  */
    7054        18730 :             if (orig_len == INT_MAX
    7055        18730 :                 && (tok2->type == CPP_CLOSE_BRACE
    7056        12517 :                     || (c_parser_peek_nth_token (parser, 4)->type
    7057              :                         != CPP_NUMBER)))
    7058              :               {
    7059              :                 last = 1;
    7060              :                 break;
    7061              :               }
    7062        18693 :             last_loc = tok->location;
    7063        18693 :             c_parser_consume_token (parser);
    7064        18693 :             c_parser_consume_token (parser);
    7065              :           }
    7066           87 :         val = make_node (RAW_DATA_CST);
    7067           87 :         TREE_TYPE (val) = integer_type_node;
    7068           87 :         RAW_DATA_LENGTH (val) = i;
    7069           87 :         tree owner = build_string (i + off + last, buf2);
    7070           87 :         XDELETEVEC (buf2);
    7071           87 :         TREE_TYPE (owner) = build_array_type_nelts (unsigned_char_type_node,
    7072           87 :                                                     i + off + last);
    7073           87 :         RAW_DATA_OWNER (val) = owner;
    7074           87 :         RAW_DATA_POINTER (val) = TREE_STRING_POINTER (owner) + off;
    7075           87 :         init.value = val;
    7076           87 :         set_c_expr_source_range (&init, loc, last_loc);
    7077           87 :         init.original_code = RAW_DATA_CST;
    7078           87 :         init.original_type = integer_type_node;
    7079           87 :         init.m_decimal = 0;
    7080           87 :         process_init_element (loc, init, false, braced_init_obstack);
    7081              :       }
    7082              : }
    7083              : 
    7084              : /* Parse a compound statement (possibly a function body) (C90 6.6.2,
    7085              :    C99 6.8.2, C11 6.8.2, C23 6.8.2).
    7086              : 
    7087              :    compound-statement:
    7088              :      { block-item-list[opt] }
    7089              :      { label-declarations block-item-list }
    7090              : 
    7091              :    block-item-list:
    7092              :      block-item
    7093              :      block-item-list block-item
    7094              : 
    7095              :    block-item:
    7096              :      label
    7097              :      nested-declaration
    7098              :      statement
    7099              : 
    7100              :    nested-declaration:
    7101              :      declaration
    7102              : 
    7103              :    GNU extensions:
    7104              : 
    7105              :    compound-statement:
    7106              :      { label-declarations block-item-list }
    7107              : 
    7108              :    nested-declaration:
    7109              :      __extension__ nested-declaration
    7110              :      nested-function-definition
    7111              : 
    7112              :    label-declarations:
    7113              :      label-declaration
    7114              :      label-declarations label-declaration
    7115              : 
    7116              :    label-declaration:
    7117              :      __label__ identifier-list ;
    7118              : 
    7119              :    Allowing the mixing of declarations and code is new in C99.  The
    7120              :    GNU syntax also permits (not shown above) labels at the end of
    7121              :    compound statements, which yield an error.  We don't allow labels
    7122              :    on declarations; this might seem like a natural extension, but
    7123              :    there would be a conflict between gnu-attributes on the label and
    7124              :    prefix gnu-attributes on the declaration.  ??? The syntax follows the
    7125              :    old parser in requiring something after label declarations.
    7126              :    Although they are erroneous if the labels declared aren't defined,
    7127              :    is it useful for the syntax to be this way?
    7128              : 
    7129              :    OpenACC:
    7130              : 
    7131              :    block-item:
    7132              :      openacc-directive
    7133              : 
    7134              :    openacc-directive:
    7135              :      update-directive
    7136              : 
    7137              :    OpenMP:
    7138              : 
    7139              :    block-item:
    7140              :      openmp-directive
    7141              : 
    7142              :    openmp-directive:
    7143              :      barrier-directive
    7144              :      flush-directive
    7145              :      taskwait-directive
    7146              :      taskyield-directive
    7147              :      cancel-directive
    7148              :      cancellation-point-directive  */
    7149              : 
    7150              : static tree
    7151     37155583 : c_parser_compound_statement (c_parser *parser, location_t *endlocp)
    7152              : {
    7153     37155583 :   tree stmt;
    7154     37155583 :   location_t brace_loc;
    7155     37155583 :   brace_loc = c_parser_peek_token (parser)->location;
    7156     37155583 :   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
    7157              :     {
    7158              :       /* Ensure a scope is entered and left anyway to avoid confusion
    7159              :          if we have just prepared to enter a function body.  */
    7160           16 :       stmt = c_begin_compound_stmt (true);
    7161           16 :       c_end_compound_stmt (brace_loc, stmt, true);
    7162           16 :       return error_mark_node;
    7163              :     }
    7164     37155567 :   stmt = c_begin_compound_stmt (true);
    7165     37155567 :   location_t end_loc = c_parser_compound_statement_nostart (parser);
    7166     37155566 :   if (endlocp)
    7167     36249773 :     *endlocp = end_loc;
    7168              : 
    7169     37155566 :   return c_end_compound_stmt (brace_loc, stmt, true);
    7170              : }
    7171              : 
    7172              : /* Diagnose errors related to imperfectly nested loops in an OMP
    7173              :    loop construct.  This function is called when such code is seen.
    7174              :    Only issue one such diagnostic no matter how much invalid
    7175              :    intervening code there is in the loop.
    7176              :    FIXME: maybe the location associated with the diagnostic should
    7177              :    be the current parser token instead of the location of the outer loop
    7178              :    nest.  */
    7179              : 
    7180              : static void
    7181          299 : check_omp_intervening_code (c_parser *parser)
    7182              : {
    7183          299 :   struct omp_for_parse_data *omp_for_parse_state = parser->omp_for_parse_state;
    7184          299 :   gcc_assert (omp_for_parse_state);
    7185              : 
    7186          299 :   if (!omp_for_parse_state->in_intervening_code)
    7187              :     return;
    7188          278 :   omp_for_parse_state->saw_intervening_code = true;
    7189              : 
    7190              :   /* Only diagnose errors related to perfect nesting once.  */
    7191          278 :   if (!omp_for_parse_state->perfect_nesting_fail)
    7192              :     {
    7193              : 
    7194              :       /* OpenACC does not (yet) permit intervening code, in
    7195              :          addition to situations forbidden by the OpenMP spec.  */
    7196          256 :       if (omp_for_parse_state->code == OACC_LOOP)
    7197              :         {
    7198            3 :           error_at (omp_for_parse_state->for_loc,
    7199              :                     "inner loops must be perfectly nested in "
    7200              :                     "%<#pragma acc loop%>");
    7201            3 :           omp_for_parse_state->perfect_nesting_fail = true;
    7202              :         }
    7203          253 :       else if (omp_for_parse_state->ordered)
    7204              :         {
    7205           11 :           error_at (omp_for_parse_state->for_loc,
    7206              :                     "inner loops must be perfectly nested with "
    7207              :                     "%<ordered%> clause");
    7208           11 :           omp_for_parse_state->perfect_nesting_fail = true;
    7209              :         }
    7210          242 :       else if (omp_for_parse_state->inscan)
    7211              :         {
    7212            2 :           error_at (omp_for_parse_state->for_loc,
    7213              :                     "inner loops must be perfectly nested with "
    7214              :                     "%<reduction%> %<inscan%> clause");
    7215            2 :           omp_for_parse_state->perfect_nesting_fail = true;
    7216              :         }
    7217          240 :       else if (omp_for_parse_state->code == OMP_TILE)
    7218              :         {
    7219            9 :           error_at (omp_for_parse_state->for_loc,
    7220              :                     "inner loops must be perfectly nested in "
    7221              :                      "%<pragma omp tile%>");
    7222            9 :           omp_for_parse_state->perfect_nesting_fail = true;
    7223              :         }
    7224          256 :       if (omp_for_parse_state->perfect_nesting_fail)
    7225           25 :         omp_for_parse_state->fail = true;
    7226              :     }
    7227              : }
    7228              : 
    7229              : /* Helper function for below:  wrap an OMP_STRUCTURED_BLOCK around SL
    7230              :    and add the statement to the current list.  If SL is an empty statement
    7231              :    list, do nothing.  */
    7232              : static void
    7233          294 : add_structured_block_stmt (tree sl)
    7234              : {
    7235          294 :   if (TREE_CODE (sl) != STATEMENT_LIST
    7236          294 :       || !tsi_end_p (tsi_start (sl)))
    7237          152 :     add_stmt (build1 (OMP_STRUCTURED_BLOCK, void_type_node, sl));
    7238          294 : }
    7239              : 
    7240              : struct c_omp_attribute_data
    7241              : {
    7242              :   vec<c_token, va_gc> *tokens;
    7243              :   const c_omp_directive *dir;
    7244              :   c_omp_directive_kind kind;
    7245              : };
    7246              : 
    7247              : /* Handle omp::directive and omp::sequence attributes in ATTRS
    7248              :    (if any) at the start of a statement or in attribute-declaration.  */
    7249              : 
    7250              : static bool
    7251          876 : c_parser_handle_statement_omp_attributes (c_parser *parser, tree &attrs,
    7252              :                                           bool *have_std_attrs)
    7253              : {
    7254          876 :   if (!flag_openmp && !flag_openmp_simd)
    7255              :     return false;
    7256              : 
    7257          610 :   auto_vec<c_omp_attribute_data, 16> vd;
    7258          610 :   int cnt = 0;
    7259          610 :   int tokens = 0;
    7260          610 :   bool bad = false;
    7261         1220 :   for (tree *pa = &attrs; *pa; )
    7262          610 :     if (is_attribute_namespace_p ("omp", *pa)
    7263          610 :         && is_attribute_p ("directive", get_attribute_name (*pa)))
    7264              :       {
    7265          609 :         cnt++;
    7266         1358 :         for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
    7267              :           {
    7268          749 :             tree d = TREE_VALUE (a);
    7269          749 :             gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
    7270          749 :             vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
    7271          749 :             c_token *first = toks->address ();
    7272          749 :             c_token *last = first + toks->length ();
    7273          749 :             if (parser->omp_attrs_forbidden_p)
    7274              :               {
    7275           14 :                 error_at (first->location,
    7276              :                           "mixing OpenMP directives with attribute and pragma "
    7277              :                           "syntax on the same statement");
    7278           14 :                 parser->omp_attrs_forbidden_p = false;
    7279           14 :                 bad = true;
    7280              :               }
    7281          735 :             else if (TREE_PUBLIC (d))
    7282              :               {
    7283            3 :                 error_at (first->location,
    7284              :                           "OpenMP %<omp::decl%> attribute on a statement");
    7285            3 :                 bad = true;
    7286              :               }
    7287          749 :             const char *directive[3] = {};
    7288         2208 :             for (int i = 0; i < 3; i++)
    7289              :               {
    7290         2026 :                 tree id = NULL_TREE;
    7291         2026 :                 if (first + i == last)
    7292              :                   break;
    7293         1781 :                 if (first[i].type == CPP_NAME)
    7294         1341 :                   id = first[i].value;
    7295          440 :                 else if (first[i].type == CPP_KEYWORD)
    7296          118 :                   id = ridpointers[(int) first[i].keyword];
    7297              :                 else
    7298              :                   break;
    7299         1459 :                 directive[i] = IDENTIFIER_POINTER (id);
    7300              :               }
    7301          749 :             const c_omp_directive *dir = NULL;
    7302          749 :             if (directive[0])
    7303          749 :               dir = c_omp_categorize_directive (directive[0], directive[1],
    7304              :                                                 directive[2]);
    7305          749 :             if (dir == NULL)
    7306              :               {
    7307            1 :                 error_at (first->location,
    7308              :                           "unknown OpenMP directive name in %qs attribute "
    7309              :                           "argument",
    7310            1 :                           TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
    7311            1 :                 continue;
    7312              :               }
    7313          748 :             c_omp_directive_kind kind = dir->kind;
    7314          748 :             if (dir->id == PRAGMA_OMP_ORDERED)
    7315              :               {
    7316              :                 /* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
    7317              :                    depend/doacross clause.  */
    7318            8 :                 if (directive[1]
    7319            4 :                     && (strcmp (directive[1], "depend") == 0
    7320            2 :                         || strcmp (directive[1], "doacross") == 0))
    7321              :                   kind = C_OMP_DIR_STANDALONE;
    7322            6 :                 else if (first + 2 < last
    7323            4 :                          && first[1].type == CPP_COMMA
    7324            4 :                          && first[2].type == CPP_NAME
    7325           10 :                          && (strcmp (IDENTIFIER_POINTER (first[2].value),
    7326              :                                      "depend") == 0
    7327            2 :                              || strcmp (IDENTIFIER_POINTER (first[2].value),
    7328              :                                         "doacross") == 0))
    7329              :                   kind = C_OMP_DIR_STANDALONE;
    7330              :               }
    7331          740 :             else if (dir->id == PRAGMA_OMP_ERROR)
    7332              :               {
    7333              :                 /* error with at(execution) clause is C_OMP_DIR_STANDALONE.  */
    7334              :                 int paren_depth = 0;
    7335           99 :                 for (int i = 1; first + i < last; i++)
    7336           84 :                   if (first[i].type == CPP_OPEN_PAREN)
    7337           18 :                     paren_depth++;
    7338           66 :                   else if (first[i].type == CPP_CLOSE_PAREN)
    7339           18 :                     paren_depth--;
    7340           48 :                   else if (paren_depth == 0
    7341           30 :                            && first + i + 2 < last
    7342           30 :                            && first[i].type == CPP_NAME
    7343           21 :                            && first[i + 1].type == CPP_OPEN_PAREN
    7344           21 :                            && first[i + 2].type == CPP_NAME
    7345           15 :                            && !strcmp (IDENTIFIER_POINTER (first[i].value),
    7346              :                                        "at")
    7347           57 :                            && !strcmp (IDENTIFIER_POINTER (first[i
    7348              :                                                                  + 2].value),
    7349              :                                        "execution"))
    7350              :                     {
    7351              :                       kind = C_OMP_DIR_STANDALONE;
    7352              :                       break;
    7353              :                     }
    7354              :               }
    7355          748 :             c_omp_attribute_data v = { toks, dir, kind };
    7356          748 :             vd.safe_push (v);
    7357          748 :             if (flag_openmp || dir->simd)
    7358          748 :               tokens += (last - first) + 1;
    7359              :           }
    7360          609 :         c_omp_attribute_data v = {};
    7361          609 :         vd.safe_push (v);
    7362          609 :         *pa = TREE_CHAIN (*pa);
    7363              :       }
    7364              :     else
    7365            1 :       pa = &TREE_CHAIN (*pa);
    7366              : 
    7367          610 :   if (bad)
    7368              :     {
    7369           17 :     fail:
    7370           29 :       if (have_std_attrs && attrs == NULL)
    7371           26 :         *have_std_attrs = false;
    7372           29 :       return false;
    7373              :     }
    7374              : 
    7375              :   unsigned int i;
    7376              :   c_omp_attribute_data *v;
    7377              :   c_omp_attribute_data *construct_seen = nullptr;
    7378              :   c_omp_attribute_data *standalone_seen = nullptr;
    7379              :   c_omp_attribute_data *prev_standalone_seen = nullptr;
    7380         1915 :   FOR_EACH_VEC_ELT (vd, i, v)
    7381         1322 :     if (v->tokens)
    7382              :       {
    7383          730 :         if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
    7384              :           construct_seen = v;
    7385          359 :         else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
    7386           71 :           standalone_seen = v;
    7387              :       }
    7388              :     else
    7389              :       {
    7390          592 :         if (standalone_seen && !prev_standalone_seen)
    7391              :           {
    7392         1322 :             prev_standalone_seen = standalone_seen;
    7393         1322 :             standalone_seen = nullptr;
    7394              :           }
    7395              :       }
    7396              : 
    7397          593 :   if (cnt > 1 && construct_seen)
    7398              :     {
    7399            4 :       error_at ((*construct_seen->tokens)[0].location,
    7400              :                 "OpenMP construct among %<omp::directive%> attributes"
    7401              :                 " requires all %<omp::directive%> attributes on the"
    7402              :                 " same statement to be in the same %<omp::sequence%>");
    7403            4 :       goto fail;
    7404              :     }
    7405          589 :   if (cnt > 1 && standalone_seen && prev_standalone_seen)
    7406              :     {
    7407            2 :       error_at ((*standalone_seen->tokens)[0].location,
    7408              :                 "multiple OpenMP standalone directives among"
    7409              :                 " %<omp::directive%> attributes must be all within the"
    7410              :                 " same %<omp::sequence%>");
    7411            2 :       goto fail;
    7412              :     }
    7413              : 
    7414          587 :   if (prev_standalone_seen)
    7415              :     standalone_seen = prev_standalone_seen;
    7416          520 :   if (standalone_seen
    7417          587 :       && !c_parser_next_token_is (parser, CPP_SEMICOLON))
    7418              :     {
    7419            2 :       error_at (standalone_seen->tokens->address ()->location,
    7420              :                 "standalone OpenMP directives in %<omp::directive%> attribute"
    7421              :                 " can only appear on an empty statement");
    7422            2 :       goto fail;
    7423              :     }
    7424         1162 :   if (cnt && c_parser_next_token_is (parser, CPP_PRAGMA))
    7425              :     {
    7426            4 :       c_token *token = c_parser_peek_token (parser);
    7427            4 :       enum pragma_kind kind = token->pragma_kind;
    7428            4 :       if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
    7429              :         {
    7430            4 :           error_at (token->location,
    7431              :                     "mixing OpenMP directives with attribute and pragma "
    7432              :                     "syntax on the same statement");
    7433            4 :           goto fail;
    7434              :         }
    7435              :     }
    7436              : 
    7437          581 :   if (!tokens)
    7438              :     return false;
    7439              : 
    7440          565 :   unsigned int tokens_avail = parser->tokens_avail;
    7441              : 
    7442          565 :   tokens++;
    7443          565 :   vec<c_token, va_gc> *toks = NULL;
    7444          565 :   vec_safe_reserve (toks, tokens, true);
    7445         1843 :   FOR_EACH_VEC_ELT (vd, i, v)
    7446              :     {
    7447         1278 :       if (!v->tokens)
    7448          566 :         continue;
    7449          712 :       if (!flag_openmp && !v->dir->simd)
    7450            0 :         continue;
    7451          712 :       c_token *first = v->tokens->address ();
    7452          712 :       c_token *last = first + v->tokens->length ();
    7453          712 :       c_token tok = {};
    7454          712 :       tok.type = CPP_PRAGMA;
    7455          712 :       tok.keyword = RID_MAX;
    7456          712 :       tok.pragma_kind = pragma_kind (v->dir->id);
    7457          712 :       tok.location = first->location;
    7458          712 :       toks->quick_push (tok);
    7459        17475 :       while (++first < last)
    7460        16051 :         toks->quick_push (*first);
    7461          712 :       tok = {};
    7462          712 :       tok.type = CPP_PRAGMA_EOL;
    7463          712 :       tok.keyword = RID_MAX;
    7464          712 :       tok.location = last[-1].location;
    7465          712 :       toks->quick_push (tok);
    7466              :     }
    7467              : 
    7468          565 :   c_token tok = {};
    7469          565 :   tok.type = CPP_EOF;
    7470          565 :   tok.keyword = RID_MAX;
    7471          565 :   tok.location = toks->last ().location;
    7472          565 :   toks->quick_push (tok);
    7473              : 
    7474          565 :   gcc_assert (!parser->in_omp_attribute_pragma);
    7475          565 :   parser->in_omp_attribute_pragma = ggc_alloc<omp_attribute_pragma_state> ();
    7476          565 :   parser->in_omp_attribute_pragma->token_vec = toks;
    7477          565 :   parser->in_omp_attribute_pragma->save_tokens = parser->tokens;
    7478          565 :   parser->in_omp_attribute_pragma->save_tokens_avail = tokens_avail;
    7479          565 :   parser->tokens = toks->address ();
    7480          565 :   parser->tokens_avail = tokens;
    7481          565 :   return true;
    7482          610 : }
    7483              : 
    7484              : /* Handle omp::directive and omp::sequence attributes in ATTRS
    7485              :    (if any) at the start or after declaration-id of a declaration.  */
    7486              : 
    7487              : static void
    7488     64219996 : c_parser_handle_directive_omp_attributes (tree &attrs,
    7489              :                                           vec<c_token> *&pragma_clauses,
    7490              :                                           vec<c_token> *attr_clauses)
    7491              : {
    7492     64219996 :   if (!flag_openmp && !flag_openmp_simd)
    7493              :     return;
    7494              : 
    7495      1606725 :   for (tree *pa = &attrs; *pa; )
    7496       643940 :     if (is_attribute_namespace_p ("omp", *pa)
    7497       643940 :         && is_attribute_p ("directive", get_attribute_name (*pa)))
    7498              :       {
    7499          141 :         int cnt = 0;
    7500          281 :         for (tree *pa2 = &TREE_VALUE (*pa); *pa2; )
    7501              :           {
    7502          142 :             tree a = *pa2;
    7503          142 :             tree d = TREE_VALUE (a);
    7504          142 :             gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
    7505          142 :             vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
    7506          142 :             c_token *first = toks->address ();
    7507          142 :             c_token *last = first + toks->length ();
    7508          142 :             const char *directive[3] = {};
    7509          424 :             for (int i = 0; i < 3; i++)
    7510              :               {
    7511          390 :                 tree id = NULL_TREE;
    7512          390 :                 if (first + i == last)
    7513              :                   break;
    7514          335 :                 if (first[i].type == CPP_NAME)
    7515          282 :                   id = first[i].value;
    7516           53 :                 else if (first[i].type == CPP_KEYWORD)
    7517            0 :                   id = ridpointers[(int) first[i].keyword];
    7518              :                 else
    7519              :                   break;
    7520          282 :                 directive[i] = IDENTIFIER_POINTER (id);
    7521              :               }
    7522          142 :             const c_omp_directive *dir = NULL;
    7523          142 :             if (directive[0])
    7524          142 :               dir = c_omp_categorize_directive (directive[0], directive[1],
    7525              :                                                 directive[2]);
    7526          142 :             if (dir == NULL)
    7527              :               {
    7528            9 :                 error_at (first->location,
    7529              :                           "unknown OpenMP directive name in "
    7530              :                           "%qs attribute argument",
    7531            9 :                           TREE_PUBLIC (d) ? "omp::decl" : "omp::directive");
    7532            9 :                 *pa2 = TREE_CHAIN (a);
    7533              :               }
    7534          133 :             else if (dir->id == PRAGMA_OMP_DECLARE
    7535          105 :                      && (strcmp (directive[1], "simd") == 0
    7536           22 :                          || strcmp (directive[1], "variant") == 0))
    7537              :               {
    7538           92 :                 if (pragma_clauses)
    7539              :                   {
    7540            2 :                     error_at (first->location,
    7541              :                               "mixing OpenMP directives with attribute and "
    7542              :                               "pragma syntax on the same declaration");
    7543            6 :                     for (pa = &attrs; *pa; )
    7544            2 :                       if (is_attribute_namespace_p ("omp", *pa)
    7545            4 :                           && is_attribute_p ("directive",
    7546            2 :                                              get_attribute_name (*pa)))
    7547            2 :                         *pa = TREE_CHAIN (*pa);
    7548              :                       else
    7549            0 :                         pa = &TREE_CHAIN (*pa);
    7550            2 :                     return;
    7551              :                   }
    7552           90 :                 ++cnt;
    7553          110 :                 attr_clauses->reserve (attr_clauses->length ()
    7554           90 :                                        + toks->length () + 2);
    7555          834 :                 for (++first; first < last; ++first)
    7556          744 :                   attr_clauses->quick_push (*first);
    7557           90 :                 c_token tok = {};
    7558           90 :                 tok.type = CPP_PRAGMA_EOL;
    7559           90 :                 tok.keyword = RID_MAX;
    7560           90 :                 tok.location = last[-1].location;
    7561           90 :                 attr_clauses->quick_push (tok);
    7562           90 :                 *pa2 = TREE_CHAIN (a);
    7563           90 :               }
    7564              :             else
    7565           41 :               pa2 = &TREE_CHAIN (a);
    7566              :           }
    7567          139 :         if (cnt && TREE_VALUE (*pa) == NULL_TREE)
    7568           86 :           *pa = TREE_CHAIN (*pa);
    7569              :         else
    7570           53 :           pa = &TREE_CHAIN (*pa);
    7571              :       }
    7572              :     else
    7573       643799 :       pa = &TREE_CHAIN (*pa);
    7574       962785 :   if (attr_clauses->length ())
    7575              :     {
    7576           70 :       c_token tok = {};
    7577           70 :       tok.type = CPP_EOF;
    7578           70 :       tok.keyword = RID_MAX;
    7579           70 :       tok.location = attr_clauses->last ().location;
    7580           70 :       attr_clauses->quick_push (tok);
    7581           70 :       attr_clauses->quick_push (tok);
    7582           70 :       pragma_clauses = attr_clauses;
    7583              :     }
    7584              : }
    7585              : 
    7586              : /* Check if STD_ATTR contains a musttail attribute and remove if it
    7587              :    precedes a return.  PARSER is the parser and ATTR is the output
    7588              :    attr_state.  */
    7589              : 
    7590              : static tree
    7591          973 : c_parser_handle_musttail (c_parser *parser, tree std_attrs, attr_state &attr)
    7592              : {
    7593          973 :   if (c_parser_next_token_is_keyword (parser, RID_RETURN))
    7594              :     {
    7595          224 :       if (tree a = lookup_attribute ("gnu", "musttail", std_attrs))
    7596              :         {
    7597          416 :           for (; a; a = lookup_attribute ("gnu", "musttail", TREE_CHAIN (a)))
    7598          209 :             if (TREE_VALUE (a))
    7599            2 :               error ("%qs attribute does not take any arguments",
    7600              :                      "musttail");
    7601          207 :           std_attrs = remove_attribute ("gnu", "musttail", std_attrs);
    7602          207 :           attr.musttail_p = true;
    7603              :         }
    7604          224 :       if (lookup_attribute ("clang", "musttail", std_attrs))
    7605              :         {
    7606           10 :           std_attrs = remove_attribute ("clang", "musttail", std_attrs);
    7607           10 :           attr.musttail_p = true;
    7608              :         }
    7609              :     }
    7610          973 :   return std_attrs;
    7611              : }
    7612              : 
    7613              : /* Return a statement before optional series of LABEL_EXPR/CASE_LABEL_EXPRs.
    7614              :    Instead of collecting vectors of labels before each stmt just in case
    7615              :    the statement would be iteration or switch statement for named loops,
    7616              :    we just remember last emitted statement and let the iteration/switch
    7617              :    statement search backwards in cur_stmt_list until that stmt for loop
    7618              :    names if any.  */
    7619              : 
    7620              : static tree
    7621     88705422 : get_before_labels ()
    7622              : {
    7623     88705422 :   if (!building_stmt_list_p ())
    7624            0 :     return NULL_TREE;
    7625     88705422 :   tree_stmt_iterator tsi = tsi_last (cur_stmt_list);
    7626     88705422 :   if (tsi_end_p (tsi))
    7627              :     return NULL_TREE;
    7628     49125894 :   return tsi_stmt (tsi);
    7629              : }
    7630              : 
    7631              : /* Parse a compound statement except for the opening brace.  This is
    7632              :    used for parsing both compound statements and statement expressions
    7633              :    (which follow different paths to handling the opening).  */
    7634              : 
    7635              : static location_t
    7636     37190418 : c_parser_compound_statement_nostart (c_parser *parser)
    7637              : {
    7638     37190418 :   bool last_stmt = false;
    7639     37190418 :   bool last_label = false;
    7640     37190418 :   bool save_valid_for_pragma = valid_location_for_stdc_pragma_p ();
    7641     37190418 :   location_t label_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
    7642     37190418 :   struct omp_for_parse_data *omp_for_parse_state
    7643              :     = parser->omp_for_parse_state;
    7644     74380836 :   bool in_omp_loop_block
    7645     37190418 :     = omp_for_parse_state ? omp_for_parse_state->want_nested_loop : false;
    7646     37190418 :   tree sl = NULL_TREE;
    7647     37190418 :   attr_state a = {};
    7648              : 
    7649     37190418 :   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    7650              :     {
    7651        22928 :       location_t endloc = c_parser_peek_token (parser)->location;
    7652        22928 :       add_debug_begin_stmt (endloc);
    7653        22928 :       c_parser_consume_token (parser);
    7654        22928 :       return endloc;
    7655              :     }
    7656              : 
    7657              :   /* If we're parsing a {} sequence in an OMP_FOR body, start a
    7658              :      statement list for intervening code.  */
    7659     37167490 :   if (in_omp_loop_block)
    7660          178 :     sl = push_stmt_list ();
    7661              : 
    7662     37167490 :   mark_valid_location_for_stdc_pragma (true);
    7663     37167490 :   if (c_parser_next_token_is_keyword (parser, RID_LABEL))
    7664              :     {
    7665              :       /* Read zero or more forward-declarations for labels that nested
    7666              :          functions can jump to.  */
    7667          728 :       mark_valid_location_for_stdc_pragma (false);
    7668          728 :       if (in_omp_loop_block)
    7669            5 :         check_omp_intervening_code (parser);
    7670         1578 :       while (c_parser_next_token_is_keyword (parser, RID_LABEL))
    7671              :         {
    7672          850 :           label_loc = c_parser_peek_token (parser)->location;
    7673          850 :           c_parser_consume_token (parser);
    7674              :           /* Any identifiers, including those declared as type names,
    7675              :              are OK here.  */
    7676         1534 :           while (true)
    7677              :             {
    7678         1192 :               tree label;
    7679         1192 :               if (c_parser_next_token_is_not (parser, CPP_NAME))
    7680              :                 {
    7681            0 :                   c_parser_error (parser, "expected identifier");
    7682            0 :                   break;
    7683              :                 }
    7684         1192 :               label
    7685         1192 :                 = declare_label (c_parser_peek_token (parser)->value);
    7686         1192 :               C_DECLARED_LABEL_FLAG (label) = 1;
    7687         1192 :               add_stmt (build_stmt (label_loc, DECL_EXPR, label));
    7688         1192 :               c_parser_consume_token (parser);
    7689         1192 :               if (c_parser_next_token_is (parser, CPP_COMMA))
    7690          342 :                 c_parser_consume_token (parser);
    7691              :               else
    7692              :                 break;
    7693          342 :             }
    7694          850 :           c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
    7695              :         }
    7696          728 :       pedwarn (label_loc, OPT_Wpedantic, "ISO C forbids label declarations");
    7697              :     }
    7698              :   /* We must now have at least one statement, label or declaration.  */
    7699     37167490 :   if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
    7700              :     {
    7701            0 :       mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
    7702            0 :       c_parser_error (parser, "expected declaration or statement");
    7703            0 :       location_t endloc = c_parser_peek_token (parser)->location;
    7704            0 :       c_parser_consume_token (parser);
    7705            0 :       return endloc;
    7706              :     }
    7707     37167490 :   tree before_labels = get_before_labels ();
    7708    124867484 :   while (c_parser_next_token_is_not (parser, CPP_CLOSE_BRACE))
    7709              :     {
    7710     50532563 :       location_t loc = c_parser_peek_token (parser)->location;
    7711     50532563 :       loc = expansion_point_location_if_in_system_header (loc);
    7712              : 
    7713    101065126 :       bool want_nested_loop = (omp_for_parse_state
    7714     50532563 :                                ? omp_for_parse_state->want_nested_loop
    7715              :                                : false);
    7716              : 
    7717              :       /* First take care of special cases for OpenMP "canonical loop
    7718              :          nest form", that do not allow standard attributes, labels, or
    7719              :          __extension__ before the nested statement.  */
    7720     50532563 :       if (in_omp_loop_block && !last_label)
    7721              :         {
    7722          397 :           tree_code code = omp_for_parse_state->code;
    7723          513 :           if (want_nested_loop
    7724          397 :               && c_parser_omp_next_tokens_can_be_canon_loop (parser, code,
    7725              :                                                              false))
    7726              :             {
    7727              :               /* Found the next nested loop.  If there were intervening
    7728              :                  code statements collected before now, wrap them in an
    7729              :                  OMP_STRUCTURED_BLOCK node, and start a new structured
    7730              :                  block to hold statements that may come after the FOR.  */
    7731          116 :               gcc_assert (sl);
    7732          116 :               add_structured_block_stmt (pop_stmt_list (sl));
    7733          116 :               omp_for_parse_state->depth++;
    7734          116 :               add_stmt (c_parser_omp_loop_nest (parser, NULL));
    7735          116 :               omp_for_parse_state->depth--;
    7736          116 :               sl = push_stmt_list ();
    7737          116 :               parser->error = false;
    7738          116 :               before_labels = get_before_labels ();
    7739          167 :               continue;
    7740              :             }
    7741          281 :           else if (want_nested_loop
    7742          468 :                    && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    7743              :             {
    7744              :               /* If this nested compound statement contains the nested loop,
    7745              :                  we need to separate the other statements in the current
    7746              :                  statement into separate blocks of intervening code.  If
    7747              :                  there's no nested loop, it's all part of the same
    7748              :                  chunk of intervening code.  */
    7749           44 :               tree pre_sl = pop_stmt_list (sl);
    7750           44 :               tree nested_sl = push_stmt_list ();
    7751           44 :               mark_valid_location_for_stdc_pragma (false);
    7752           44 :               c_parser_statement_after_labels (parser, NULL, NULL_TREE);
    7753           44 :               nested_sl = pop_stmt_list (nested_sl);
    7754           44 :               if (omp_for_parse_state->want_nested_loop)
    7755              :                 {
    7756              :                   /* This block didn't contain a loop-nest, so it's
    7757              :                      all part of the same chunk of intervening code.  */
    7758           13 :                   check_omp_intervening_code (parser);
    7759           13 :                   sl = push_stmt_list ();
    7760           13 :                   add_stmt (pre_sl);
    7761           13 :                   add_stmt (nested_sl);
    7762              :                 }
    7763              :               else
    7764              :                 {
    7765              :                   /* It contains the nested loop.  */
    7766           31 :                   add_structured_block_stmt (pre_sl);
    7767           31 :                   add_stmt (nested_sl);
    7768           31 :                   sl = push_stmt_list ();
    7769              :                 }
    7770           44 :               parser->error = false;
    7771           44 :               before_labels = get_before_labels ();
    7772           44 :               continue;
    7773           44 :             }
    7774          237 :           else if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    7775              :             {
    7776              :               /* Prior to implementing the OpenMP 5.1 syntax for canonical
    7777              :                  loop form, GCC used to accept an empty statements that
    7778              :                  would now be flagged as intervening code.  Continue to
    7779              :                  do that, as an extension.  */
    7780              :               /* FIXME:  Maybe issue a warning or something here?  */
    7781            4 :               c_parser_consume_token (parser);
    7782            4 :               before_labels = get_before_labels ();
    7783            4 :               continue;
    7784              :             }
    7785              :         }
    7786              : 
    7787              :       /* Standard attributes may start a label, statement or declaration.  */
    7788     50532399 :       bool have_std_attrs
    7789     50532399 :         = c_parser_nth_token_starts_std_attributes (parser, 1);
    7790     50532399 :       tree std_attrs = NULL_TREE;
    7791     50532399 :       if (have_std_attrs)
    7792              :         {
    7793          840 :           std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    7794          840 :           std_attrs = c_parser_handle_musttail (parser, std_attrs, a);
    7795              :         }
    7796     50532399 :       if (c_parser_next_token_is_keyword (parser, RID_CASE)
    7797     49536427 :           || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
    7798    100035489 :           || (c_parser_next_token_is (parser, CPP_NAME)
    7799     10070328 :               && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
    7800              :         {
    7801      1052640 :           if (c_parser_next_token_is_keyword (parser, RID_CASE))
    7802       995972 :             label_loc = c_parser_peek_2nd_token (parser)->location;
    7803              :           else
    7804        56668 :             label_loc = c_parser_peek_token (parser)->location;
    7805      1052640 :           last_label = true;
    7806      1052640 :           last_stmt = false;
    7807      1052640 :           mark_valid_location_for_stdc_pragma (false);
    7808      1052640 :           if (in_omp_loop_block)
    7809           26 :             check_omp_intervening_code (parser);
    7810      1052640 :           c_parser_label (parser, std_attrs);
    7811              :         }
    7812     49479759 :       else if (c_parser_next_tokens_start_declaration (parser)
    7813     49479759 :                || (have_std_attrs
    7814          703 :                    && !c_parser_handle_statement_omp_attributes
    7815          703 :                                 (parser, std_attrs, &have_std_attrs)
    7816          269 :                    && c_parser_next_token_is (parser, CPP_SEMICOLON)
    7817           77 :                    && (have_std_attrs = true)))
    7818              :         {
    7819      7626503 :           if (last_label)
    7820           87 :             pedwarn_c11 (c_parser_peek_token (parser)->location, OPT_Wfree_labels,
    7821              :                          "a label can only be part of a statement and "
    7822              :                          "a declaration is not a statement");
    7823              :           /* It's unlikely we'll see a nested loop in a declaration in
    7824              :              intervening code in an OMP loop, but disallow it anyway.  */
    7825      7626503 :           if (in_omp_loop_block)
    7826              :             {
    7827           19 :               check_omp_intervening_code (parser);
    7828           19 :               omp_for_parse_state->want_nested_loop = false;
    7829              :             }
    7830      7626503 :           mark_valid_location_for_stdc_pragma (false);
    7831      7626503 :           bool fallthru_attr_p = false;
    7832      7626503 :           c_parser_declaration_or_fndef (parser, true, !have_std_attrs,
    7833              :                                          true, true, true, false, NULL,
    7834              :                                          NULL, have_std_attrs, std_attrs,
    7835              :                                          NULL, &fallthru_attr_p);
    7836              : 
    7837      7626503 :           if (in_omp_loop_block)
    7838           19 :               omp_for_parse_state->want_nested_loop = want_nested_loop;
    7839      7626503 :           if (last_stmt && !fallthru_attr_p)
    7840       309104 :             pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
    7841              :                          "ISO C90 forbids mixed declarations and code");
    7842      7626503 :           last_stmt = fallthru_attr_p;
    7843      7626503 :           last_label = false;
    7844      7626503 :           before_labels = get_before_labels ();
    7845              :         }
    7846     41853256 :       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
    7847              :         {
    7848              :           /* __extension__ can start a declaration, but is also an
    7849              :              unary operator that can start an expression.  Consume all
    7850              :              but the last of a possible series of __extension__ to
    7851              :              determine which.  If standard attributes have already
    7852              :              been seen, it must start a statement, not a declaration,
    7853              :              but standard attributes starting a declaration may appear
    7854              :              after __extension__.  */
    7855         1560 :           while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
    7856          780 :                  && (c_parser_peek_2nd_token (parser)->keyword
    7857              :                      == RID_EXTENSION))
    7858            0 :             c_parser_consume_token (parser);
    7859          780 :           if (!have_std_attrs
    7860          780 :               && (c_parser_next_tokens_start_declaration (parser, 2)
    7861          709 :                   || c_parser_nth_token_starts_std_attributes (parser, 2)))
    7862              :             {
    7863           74 :               int ext;
    7864           74 :               ext = disable_extension_diagnostics ();
    7865           74 :               c_parser_consume_token (parser);
    7866           74 :               last_label = false;
    7867              :               /* It's unlikely we'll see a nested loop in a declaration in
    7868              :                  intervening code in an OMP loop, but disallow it anyway.  */
    7869           74 :               if (in_omp_loop_block)
    7870              :                 {
    7871            0 :                   check_omp_intervening_code (parser);
    7872            0 :                   omp_for_parse_state->want_nested_loop = false;
    7873              :                 }
    7874           74 :               mark_valid_location_for_stdc_pragma (false);
    7875           74 :               c_parser_declaration_or_fndef (parser, true, true, true, true,
    7876              :                                              true, false);
    7877           74 :               if (in_omp_loop_block)
    7878            0 :                 omp_for_parse_state->want_nested_loop = want_nested_loop;
    7879              :               /* Following the old parser, __extension__ does not
    7880              :                  disable this diagnostic.  */
    7881           74 :               restore_extension_diagnostics (ext);
    7882           74 :               if (last_stmt)
    7883            7 :                 pedwarn_c90 (loc, OPT_Wdeclaration_after_statement,
    7884              :                              "ISO C90 forbids mixed declarations and code");
    7885           74 :               last_stmt = false;
    7886           74 :               before_labels = get_before_labels ();
    7887              :             }
    7888              :           else
    7889          706 :             goto statement;
    7890              :         }
    7891     41852476 :       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
    7892              :         {
    7893       335328 :           if (have_std_attrs && !parser->in_omp_attribute_pragma)
    7894            0 :             c_parser_error (parser, "expected declaration or statement");
    7895       335328 :           else if (std_attrs)
    7896            0 :             c_warn_unused_attributes (std_attrs);
    7897              :           /* External pragmas, and some omp pragmas, are not associated
    7898              :              with regular c code, and so are not to be considered statements
    7899              :              syntactically.  This ensures that the user doesn't put them
    7900              :              places that would turn into syntax errors if the directive
    7901              :              were ignored.  */
    7902       335328 :           if (omp_for_parse_state)
    7903           13 :             omp_for_parse_state->want_nested_loop = false;
    7904       670574 :           if (c_parser_pragma (parser,
    7905              :                                last_label ? pragma_stmt : pragma_compound,
    7906              :                                NULL, before_labels))
    7907              :             {
    7908        23133 :               last_label = false;
    7909        23133 :               last_stmt = true;
    7910        23133 :               if (omp_for_parse_state)
    7911            5 :                 check_omp_intervening_code (parser);
    7912              :             }
    7913       312200 :           if (omp_for_parse_state)
    7914           13 :             omp_for_parse_state->want_nested_loop = want_nested_loop;
    7915       335328 :           before_labels = get_before_labels ();
    7916              :         }
    7917     41517148 :       else if (c_parser_next_token_is (parser, CPP_EOF))
    7918              :         {
    7919           56 :           mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
    7920           56 :           c_parser_error (parser, "expected declaration or statement");
    7921           58 :           return c_parser_peek_token (parser)->location;
    7922              :         }
    7923     41517092 :       else if (c_parser_next_token_is_keyword (parser, RID_ELSE))
    7924              :         {
    7925            5 :           if (parser->in_if_block)
    7926              :             {
    7927            2 :               mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
    7928            2 :               error_at (loc, "expected %<}%> before %<else%>");
    7929            2 :               return c_parser_peek_token (parser)->location;
    7930              :             }
    7931              :           else
    7932              :             {
    7933            3 :               error_at (loc, "%<else%> without a previous %<if%>");
    7934            3 :               c_parser_consume_token (parser);
    7935            3 :               before_labels = get_before_labels ();
    7936            3 :               continue;
    7937              :             }
    7938              :         }
    7939              :       else
    7940              :         {
    7941     41517087 :         statement:
    7942     41517793 :           c_warn_unused_attributes (std_attrs);
    7943     41517793 :           last_label = false;
    7944     41517793 :           last_stmt = true;
    7945     41517793 :           mark_valid_location_for_stdc_pragma (false);
    7946     41517793 :           if (!omp_for_parse_state)
    7947     41517562 :             c_parser_statement_after_labels (parser, NULL, before_labels,
    7948              :                                              NULL, a);
    7949              :           else
    7950              :             {
    7951              :               /* In canonical loop nest form, nested loops can only appear
    7952              :                  directly, or in a directly nested compound statement.  We
    7953              :                  already took care of those cases above, so now we have
    7954              :                  something else.  This statement and everything inside
    7955              :                  it must be intervening code.  */
    7956          231 :               omp_for_parse_state->want_nested_loop = false;
    7957          231 :               check_omp_intervening_code (parser);
    7958          231 :               c_parser_statement_after_labels (parser, NULL, before_labels);
    7959          231 :               omp_for_parse_state->want_nested_loop = want_nested_loop;
    7960              :             }
    7961     41517792 :           before_labels = get_before_labels ();
    7962              :         }
    7963              : 
    7964     50532337 :       parser->error = false;
    7965              :     }
    7966     37167431 :   if (last_label)
    7967           45 :     pedwarn_c11 (label_loc, OPT_Wfree_labels,
    7968              :                  "label at end of compound statement");
    7969     37167431 :   location_t endloc = c_parser_peek_token (parser)->location;
    7970     37167431 :   c_parser_consume_token (parser);
    7971              : 
    7972              :   /* Restore the value we started with.  */
    7973     37167431 :   mark_valid_location_for_stdc_pragma (save_valid_for_pragma);
    7974              : 
    7975              :   /* Package leftover intervening code, or the whole contents of the
    7976              :      compound statement if we were looking for a nested loop in an OMP_FOR
    7977              :      construct and didn't find one.  */
    7978     37167431 :   if (sl)
    7979              :     {
    7980          178 :       sl = pop_stmt_list (sl);
    7981          178 :       if (omp_for_parse_state->want_nested_loop)
    7982           31 :         add_stmt (sl);
    7983              :       else
    7984          147 :         add_structured_block_stmt (sl);
    7985              :     }
    7986              :   return endloc;
    7987              : }
    7988              : 
    7989              : /* Parse all consecutive labels, possibly preceded by standard
    7990              :    attributes.  In this context, a statement is required, not a
    7991              :    declaration, so attributes must be followed by a statement that is
    7992              :    not just a semicolon.  Returns an attr_state.  */
    7993              : 
    7994              : static attr_state
    7995      2058068 : c_parser_all_labels (c_parser *parser)
    7996              : {
    7997      2058068 :   attr_state attr = {};
    7998      2058068 :   bool have_std_attrs;
    7999      2058068 :   tree std_attrs = NULL;
    8000      2058068 :   if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1)))
    8001              :     {
    8002          109 :       std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    8003          109 :       std_attrs = c_parser_handle_musttail (parser, std_attrs, attr);
    8004              :     }
    8005              : 
    8006      2059039 :   while (c_parser_next_token_is_keyword (parser, RID_CASE)
    8007      2058546 :          || c_parser_next_token_is_keyword (parser, RID_DEFAULT)
    8008      4117574 :          || (c_parser_next_token_is (parser, CPP_NAME)
    8009       503051 :              && c_parser_peek_2nd_token (parser)->type == CPP_COLON))
    8010              :     {
    8011          971 :       c_parser_label (parser, std_attrs);
    8012          971 :       std_attrs = NULL;
    8013          971 :       if ((have_std_attrs = c_parser_nth_token_starts_std_attributes (parser,
    8014              :                                                                       1)))
    8015              :         {
    8016            3 :           std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    8017            3 :           std_attrs = c_parser_handle_musttail (parser, std_attrs, attr);
    8018              :         }
    8019              :     }
    8020      2058068 :   if (std_attrs
    8021      2058068 :       && (!c_parser_handle_statement_omp_attributes (parser, std_attrs, &have_std_attrs)
    8022           11 :           || std_attrs))
    8023              :     {
    8024           22 :       if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
    8025            0 :         c_parser_error (parser, "expected statement");
    8026           18 :       c_warn_unused_attributes (std_attrs);
    8027              :     }
    8028      2058142 :   else if (have_std_attrs && c_parser_next_token_is (parser, CPP_SEMICOLON))
    8029            1 :     c_parser_error (parser, "expected statement");
    8030      2058068 :   return attr;
    8031              : }
    8032              : 
    8033              : 
    8034              : /* Information used while parsing an OpenMP metadirective.  */
    8035              : struct omp_metadirective_parse_data {
    8036              :   /* These fields are used to unique-ify labels when reparsing the
    8037              :      code in a metadirective alternative.  */
    8038              :   vec<tree> * GTY((skip)) body_labels;
    8039              :   unsigned int region_num;
    8040              : };
    8041              : 
    8042              : /* Helper function for c_parser_label: mangle a metadirective region
    8043              :    label NAME.  */
    8044              : static tree
    8045            0 : mangle_metadirective_region_label (c_parser *parser, tree name)
    8046              : {
    8047            0 :   if (parser->omp_metadirective_state->body_labels->contains (name))
    8048              :     {
    8049            0 :       const char *old_name = IDENTIFIER_POINTER (name);
    8050            0 :       char *new_name = (char *) XALLOCAVEC (char, strlen (old_name) + 32);
    8051            0 :       sprintf (new_name, "%s_MDR%u", old_name,
    8052              :                parser->omp_metadirective_state->region_num);
    8053            0 :       return get_identifier (new_name);
    8054              :     }
    8055            0 :   return name;
    8056              : }
    8057              : 
    8058              : /* Parse a label (C90 6.6.1, C99 6.8.1, C11 6.8.1).
    8059              : 
    8060              :    label:
    8061              :      identifier : gnu-attributes[opt]
    8062              :      case constant-expression :
    8063              :      default :
    8064              : 
    8065              :    GNU extensions:
    8066              : 
    8067              :    label:
    8068              :      case constant-expression ... constant-expression :
    8069              : 
    8070              :    The use of gnu-attributes on labels is a GNU extension.  The syntax in
    8071              :    GNU C accepts any expressions without commas, non-constant
    8072              :    expressions being rejected later.  Any standard
    8073              :    attribute-specifier-sequence before the first label has been parsed
    8074              :    in the caller, to distinguish statements from declarations.  Any
    8075              :    attribute-specifier-sequence after the label is parsed in this
    8076              :    function.  */
    8077              : static void
    8078      1053611 : c_parser_label (c_parser *parser, tree std_attrs)
    8079              : {
    8080      1053611 :   location_t loc1 = c_parser_peek_token (parser)->location;
    8081      1053611 :   tree label = NULL_TREE;
    8082              : 
    8083              :   /* Remember whether this case or a user-defined label is allowed to fall
    8084              :      through to.  */
    8085      1053611 :   bool fallthrough_p = c_parser_peek_token (parser)->flags & PREV_FALLTHROUGH;
    8086              : 
    8087      1053611 :   if (c_parser_next_token_is_keyword (parser, RID_CASE))
    8088              :     {
    8089       996465 :       tree exp1, exp2;
    8090       996465 :       c_parser_consume_token (parser);
    8091       996465 :       exp1 = convert_lvalue_to_rvalue (loc1,
    8092              :                                        c_parser_expr_no_commas (parser, NULL),
    8093              :                                        true, true).value;
    8094       996465 :       if (c_parser_next_token_is (parser, CPP_COLON))
    8095              :         {
    8096       996143 :           c_parser_consume_token (parser);
    8097       996143 :           label = do_case (loc1, exp1, NULL_TREE, std_attrs);
    8098              :         }
    8099          322 :       else if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
    8100              :         {
    8101          314 :           c_parser_consume_token (parser);
    8102          314 :           exp2 = convert_lvalue_to_rvalue (loc1,
    8103              :                                            c_parser_expr_no_commas (parser,
    8104              :                                                                     NULL),
    8105              :                                            true, true).value;
    8106          314 :           if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
    8107          314 :             label = do_case (loc1, exp1, exp2, std_attrs);
    8108              :         }
    8109              :       else
    8110            8 :         c_parser_error (parser, "expected %<:%> or %<...%>");
    8111              :     }
    8112        57146 :   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
    8113              :     {
    8114        33348 :       c_parser_consume_token (parser);
    8115        33348 :       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
    8116        33348 :         label = do_case (loc1, NULL_TREE, NULL_TREE, std_attrs);
    8117              :     }
    8118              :   else
    8119              :     {
    8120        23798 :       tree name = c_parser_peek_token (parser)->value;
    8121        23798 :       tree tlab;
    8122        23798 :       tree attrs;
    8123        23798 :       location_t loc2 = c_parser_peek_token (parser)->location;
    8124        23798 :       gcc_assert (c_parser_next_token_is (parser, CPP_NAME));
    8125        23798 :       c_parser_consume_token (parser);
    8126        23798 :       gcc_assert (c_parser_next_token_is (parser, CPP_COLON));
    8127        23798 :       c_parser_consume_token (parser);
    8128        23798 :       attrs = c_parser_gnu_attributes (parser);
    8129        23798 :       if (parser->omp_metadirective_state)
    8130            0 :         name = mangle_metadirective_region_label (parser, name);
    8131        23798 :       tlab = define_label (loc2, name);
    8132        23798 :       if (tlab)
    8133              :         {
    8134        23770 :           decl_attributes (&tlab, attrs, 0);
    8135        23770 :           decl_attributes (&tlab, std_attrs, 0);
    8136        23770 :           label = add_stmt (build_stmt (loc1, LABEL_EXPR, tlab));
    8137              :         }
    8138        23798 :       if (attrs
    8139        23798 :           && c_parser_next_tokens_start_declaration (parser))
    8140            1 :           warning_at (loc2, OPT_Wattributes, "GNU-style attribute between"
    8141              :                       " label and declaration appertains to the label");
    8142              :     }
    8143      1053611 :   if (label)
    8144              :     {
    8145      1053431 :       if (TREE_CODE (label) == LABEL_EXPR)
    8146        23770 :         FALLTHROUGH_LABEL_P (LABEL_EXPR_LABEL (label)) = fallthrough_p;
    8147              :       else
    8148      1029661 :         FALLTHROUGH_LABEL_P (CASE_LABEL (label)) = fallthrough_p;
    8149              :     }
    8150      1053611 : }
    8151              : 
    8152              : /* Parse a statement (C90 6.6, C99 6.8, C11 6.8).
    8153              : 
    8154              :    statement:
    8155              :      labeled-statement
    8156              :      attribute-specifier-sequence[opt] compound-statement
    8157              :      expression-statement
    8158              :      attribute-specifier-sequence[opt] selection-statement
    8159              :      attribute-specifier-sequence[opt] iteration-statement
    8160              :      attribute-specifier-sequence[opt] jump-statement
    8161              : 
    8162              :    labeled-statement:
    8163              :      attribute-specifier-sequence[opt] label statement
    8164              : 
    8165              :    expression-statement:
    8166              :      expression[opt] ;
    8167              :      attribute-specifier-sequence expression ;
    8168              : 
    8169              :    selection-statement:
    8170              :      if-statement
    8171              :      switch-statement
    8172              : 
    8173              :    iteration-statement:
    8174              :      while-statement
    8175              :      do-statement
    8176              :      for-statement
    8177              : 
    8178              :    jump-statement:
    8179              :      goto identifier ;
    8180              :      continue ;
    8181              :      break ;
    8182              :      return expression[opt] ;
    8183              : 
    8184              :    GNU extensions:
    8185              : 
    8186              :    statement:
    8187              :      attribute-specifier-sequence[opt] asm-statement
    8188              : 
    8189              :    jump-statement:
    8190              :      goto * expression ;
    8191              : 
    8192              :    expression-statement:
    8193              :      gnu-attributes ;
    8194              : 
    8195              :    Objective-C:
    8196              : 
    8197              :    statement:
    8198              :      attribute-specifier-sequence[opt] objc-throw-statement
    8199              :      attribute-specifier-sequence[opt] objc-try-catch-statement
    8200              :      attribute-specifier-sequence[opt] objc-synchronized-statement
    8201              : 
    8202              :    objc-throw-statement:
    8203              :      @throw expression ;
    8204              :      @throw ;
    8205              : 
    8206              :    OpenACC:
    8207              : 
    8208              :    statement:
    8209              :      attribute-specifier-sequence[opt] openacc-construct
    8210              : 
    8211              :    openacc-construct:
    8212              :      parallel-construct
    8213              :      kernels-construct
    8214              :      data-construct
    8215              :      loop-construct
    8216              : 
    8217              :    parallel-construct:
    8218              :      parallel-directive structured-block
    8219              : 
    8220              :    kernels-construct:
    8221              :      kernels-directive structured-block
    8222              : 
    8223              :    data-construct:
    8224              :      data-directive structured-block
    8225              : 
    8226              :    loop-construct:
    8227              :      loop-directive structured-block
    8228              : 
    8229              :    OpenMP:
    8230              : 
    8231              :    statement:
    8232              :      attribute-specifier-sequence[opt] openmp-construct
    8233              : 
    8234              :    openmp-construct:
    8235              :      parallel-construct
    8236              :      for-construct
    8237              :      simd-construct
    8238              :      for-simd-construct
    8239              :      sections-construct
    8240              :      single-construct
    8241              :      parallel-for-construct
    8242              :      parallel-for-simd-construct
    8243              :      parallel-sections-construct
    8244              :      master-construct
    8245              :      critical-construct
    8246              :      atomic-construct
    8247              :      ordered-construct
    8248              : 
    8249              :    parallel-construct:
    8250              :      parallel-directive structured-block
    8251              : 
    8252              :    for-construct:
    8253              :      for-directive iteration-statement
    8254              : 
    8255              :    simd-construct:
    8256              :      simd-directive iteration-statements
    8257              : 
    8258              :    for-simd-construct:
    8259              :      for-simd-directive iteration-statements
    8260              : 
    8261              :    sections-construct:
    8262              :      sections-directive section-scope
    8263              : 
    8264              :    single-construct:
    8265              :      single-directive structured-block
    8266              : 
    8267              :    parallel-for-construct:
    8268              :      parallel-for-directive iteration-statement
    8269              : 
    8270              :    parallel-for-simd-construct:
    8271              :      parallel-for-simd-directive iteration-statement
    8272              : 
    8273              :    parallel-sections-construct:
    8274              :      parallel-sections-directive section-scope
    8275              : 
    8276              :    master-construct:
    8277              :      master-directive structured-block
    8278              : 
    8279              :    critical-construct:
    8280              :      critical-directive structured-block
    8281              : 
    8282              :    atomic-construct:
    8283              :      atomic-directive expression-statement
    8284              : 
    8285              :    ordered-construct:
    8286              :      ordered-directive structured-block
    8287              : 
    8288              :    Transactional Memory:
    8289              : 
    8290              :    statement:
    8291              :      attribute-specifier-sequence[opt] transaction-statement
    8292              :      attribute-specifier-sequence[opt] transaction-cancel-statement
    8293              : 
    8294              :    IF_P is used to track whether there's a (possibly labeled) if statement
    8295              :    which is not enclosed in braces and has an else clause.  This is used to
    8296              :    implement -Wparentheses.  */
    8297              : 
    8298              : static void
    8299       532091 : c_parser_statement (c_parser *parser, bool *if_p, location_t *loc_after_labels)
    8300              : {
    8301       532091 :   tree before_labels = get_before_labels ();
    8302       532091 :   attr_state a = c_parser_all_labels (parser);
    8303       532091 :   if (loc_after_labels)
    8304       366471 :     *loc_after_labels = c_parser_peek_token (parser)->location;
    8305       532091 :   parser->omp_attrs_forbidden_p = false;
    8306       532091 :   c_parser_statement_after_labels (parser, if_p, before_labels, NULL, a);
    8307       532091 : }
    8308              : 
    8309              : /* Parse and handle optional identifier after break or continue keywords.  */
    8310              : 
    8311              : static tree
    8312       187071 : c_parser_bc_name (c_parser *parser, bool is_break)
    8313              : {
    8314       187071 :   if (!c_parser_next_token_is (parser, CPP_NAME))
    8315              :     return NULL_TREE;
    8316              : 
    8317          316 :   c_token *tok = c_parser_peek_token (parser);
    8318          316 :   tree label = c_finish_bc_name (tok->location, tok->value, is_break);
    8319          316 :   c_parser_consume_token (parser);
    8320          316 :   return label;
    8321              : }
    8322              : 
    8323              : /* Parse a statement, other than a labeled statement.  CHAIN is a vector
    8324              :    of if-else-if conditions.  All labels and standard attributes have
    8325              :    been parsed in the caller.
    8326              : 
    8327              :    IF_P is used to track whether there's a (possibly labeled) if statement
    8328              :    which is not enclosed in braces and has an else clause.  This is used to
    8329              :    implement -Wparentheses.  ASTATE is an earlier parsed attribute state.
    8330              : 
    8331              :    BEFORE_LABELS is last statement before possible labels, see
    8332              :    get_before_labels description for details.  */
    8333              : 
    8334              : static void
    8335     43115965 : c_parser_statement_after_labels (c_parser *parser, bool *if_p,
    8336              :                                  tree before_labels,
    8337              :                                  vec<tree> *chain, attr_state astate)
    8338              : {
    8339     43115965 :   location_t loc = c_parser_peek_token (parser)->location;
    8340     43115965 :   tree stmt = NULL_TREE;
    8341     43115965 :   bool in_if_block = parser->in_if_block;
    8342     43115965 :   parser->in_if_block = false;
    8343     43115965 :   if (if_p != NULL)
    8344       811937 :     *if_p = false;
    8345              : 
    8346     43115965 :   if (c_parser_peek_token (parser)->type != CPP_OPEN_BRACE)
    8347     42663628 :     add_debug_begin_stmt (loc);
    8348              : 
    8349       452337 :  restart:
    8350     43116001 :   switch (c_parser_peek_token (parser)->type)
    8351              :     {
    8352       452341 :     case CPP_OPEN_BRACE:
    8353       452341 :       add_stmt (c_parser_compound_statement (parser));
    8354       452341 :       break;
    8355     36806047 :     case CPP_KEYWORD:
    8356     36806047 :       switch (c_parser_peek_token (parser)->keyword)
    8357              :         {
    8358      1268763 :         case RID_IF:
    8359      1268763 :           c_parser_if_statement (parser, if_p, chain);
    8360      1268763 :           break;
    8361        37243 :         case RID_SWITCH:
    8362        37243 :           c_parser_switch_statement (parser, if_p, before_labels);
    8363        37243 :           break;
    8364        44415 :         case RID_WHILE:
    8365        44415 :           c_parser_while_statement (parser, false, 0, false, if_p, before_labels);
    8366        44415 :           break;
    8367       145261 :         case RID_DO:
    8368       145261 :           c_parser_do_statement (parser, false, 0, false, before_labels);
    8369       145261 :           break;
    8370       281561 :         case RID_FOR:
    8371       281561 :           c_parser_for_statement (parser, false, 0, false, if_p, before_labels);
    8372       281561 :           break;
    8373        83627 :         case RID_GOTO:
    8374        83627 :           c_parser_consume_token (parser);
    8375        83627 :           if (c_parser_next_token_is (parser, CPP_NAME))
    8376              :             {
    8377        82687 :               tree name = c_parser_peek_token (parser)->value;
    8378        82687 :               if (parser->omp_metadirective_state)
    8379            0 :                 name = mangle_metadirective_region_label (parser, name);
    8380        82687 :               stmt = c_finish_goto_label (loc, name);
    8381        82687 :               c_parser_consume_token (parser);
    8382              :             }
    8383          940 :           else if (c_parser_next_token_is (parser, CPP_MULT))
    8384              :             {
    8385          940 :               struct c_expr val;
    8386              : 
    8387          940 :               c_parser_consume_token (parser);
    8388          940 :               val = c_parser_expression (parser);
    8389          940 :               val = convert_lvalue_to_rvalue (loc, val, false, true);
    8390          940 :               stmt = c_finish_goto_ptr (loc, val);
    8391              :             }
    8392              :           else
    8393            0 :             c_parser_error (parser, "expected identifier or %<*%>");
    8394        83627 :           goto expect_semicolon;
    8395        13160 :         case RID_CONTINUE:
    8396        13160 :           c_parser_consume_token (parser);
    8397        13160 :           stmt = c_finish_bc_stmt (loc, objc_foreach_continue_label, false,
    8398              :                                    c_parser_bc_name (parser, false));
    8399        13160 :           goto expect_semicolon;
    8400       173911 :         case RID_BREAK:
    8401       173911 :           c_parser_consume_token (parser);
    8402       173911 :           stmt = c_finish_bc_stmt (loc, objc_foreach_break_label, true,
    8403              :                                    c_parser_bc_name (parser, true));
    8404       173911 :           goto expect_semicolon;
    8405     34534675 :         case RID_RETURN:
    8406     34534675 :           c_parser_consume_token (parser);
    8407     34534675 :           if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8408              :             {
    8409        42440 :               stmt = c_finish_return (loc, NULL_TREE, NULL_TREE,
    8410        21220 :                                       astate.musttail_p);
    8411        21220 :               c_parser_consume_token (parser);
    8412              :             }
    8413              :           else
    8414              :             {
    8415     34513455 :               location_t xloc = c_parser_peek_token (parser)->location;
    8416     34513455 :               struct c_expr expr = c_parser_expression_conv (parser);
    8417     34513455 :               mark_exp_read (expr.value);
    8418     35291846 :               stmt = c_finish_return (EXPR_LOC_OR_LOC (expr.value, xloc),
    8419              :                                       expr.value, expr.original_type,
    8420     34513455 :                                       astate.musttail_p);
    8421     34513455 :               goto expect_semicolon;
    8422              :             }
    8423        21220 :           break;
    8424       204806 :         case RID_ASM:
    8425       204806 :           stmt = c_parser_asm_statement (parser);
    8426       204806 :           break;
    8427          137 :         case RID_TRANSACTION_ATOMIC:
    8428          137 :         case RID_TRANSACTION_RELAXED:
    8429          274 :           stmt = c_parser_transaction (parser,
    8430          137 :               c_parser_peek_token (parser)->keyword);
    8431          137 :           break;
    8432           28 :         case RID_TRANSACTION_CANCEL:
    8433           28 :           stmt = c_parser_transaction_cancel (parser);
    8434           28 :           goto expect_semicolon;
    8435            0 :         case RID_AT_THROW:
    8436            0 :           gcc_assert (c_dialect_objc ());
    8437            0 :           c_parser_consume_token (parser);
    8438            0 :           if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8439              :             {
    8440            0 :               stmt = objc_build_throw_stmt (loc, NULL_TREE);
    8441            0 :               c_parser_consume_token (parser);
    8442              :             }
    8443              :           else
    8444              :             {
    8445            0 :               struct c_expr expr = c_parser_expression (parser);
    8446            0 :               expr = convert_lvalue_to_rvalue (loc, expr, false, false);
    8447            0 :               expr.value = c_fully_fold (expr.value, false, NULL);
    8448            0 :               stmt = objc_build_throw_stmt (loc, expr.value);
    8449            0 :               goto expect_semicolon;
    8450              :             }
    8451            0 :           break;
    8452            0 :         case RID_AT_TRY:
    8453            0 :           gcc_assert (c_dialect_objc ());
    8454            0 :           c_parser_objc_try_catch_finally_statement (parser);
    8455            0 :           break;
    8456            0 :         case RID_AT_SYNCHRONIZED:
    8457            0 :           gcc_assert (c_dialect_objc ());
    8458            0 :           c_parser_objc_synchronized_statement (parser);
    8459            0 :           break;
    8460            9 :         case RID_ATTRIBUTE:
    8461            9 :           {
    8462              :             /* Allow '__attribute__((fallthrough));' or
    8463              :                '__attribute__((assume(cond)));' or
    8464              :                '__attribute__((musttail))) return'.  */
    8465            9 :             tree attrs = c_parser_gnu_attributes (parser);
    8466            9 :             bool has_assume = lookup_attribute ("assume", attrs);
    8467            9 :             if (has_assume)
    8468              :               {
    8469            0 :                 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8470            0 :                   attrs = handle_assume_attribute (loc, attrs, true);
    8471              :                 else
    8472              :                   {
    8473            0 :                     auto_urlify_attributes sentinel;
    8474            0 :                     warning_at (loc, OPT_Wattributes,
    8475              :                                 "%<assume%> attribute not followed by %<;%>");
    8476            0 :                     has_assume = false;
    8477            0 :                   }
    8478              :               }
    8479            9 :             gcc_assert (!astate.musttail_p);
    8480            9 :             attrs = c_parser_handle_musttail (parser, attrs, astate);
    8481            9 :             if (astate.musttail_p)
    8482              :               {
    8483            4 :                 if (attrs)
    8484              :                   {
    8485            1 :                     auto_urlify_attributes sentinel;
    8486            1 :                     warning_at (c_parser_peek_token (parser)->location,
    8487            1 :                                 OPT_Wattributes,
    8488              :                                 "attribute %<musttail%> mixed with other "
    8489              :                                 "attributes on %<return%> statement");
    8490            1 :                   }
    8491            4 :                 goto restart;
    8492              :               }
    8493            5 :             if (attribute_fallthrough_p (attrs))
    8494              :               {
    8495            5 :                 if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8496              :                   {
    8497            5 :                     tree fn = build_call_expr_internal_loc (loc,
    8498              :                                                             IFN_FALLTHROUGH,
    8499              :                                                             void_type_node, 0);
    8500            5 :                     add_stmt (fn);
    8501              :                     /* Eat the ';'.  */
    8502            5 :                     c_parser_consume_token (parser);
    8503              :                   }
    8504              :                 else
    8505              :                   {
    8506            0 :                     auto_urlify_attributes sentinel;
    8507            0 :                     warning_at (loc, OPT_Wattributes,
    8508              :                                 "%<fallthrough%> attribute not followed "
    8509              :                                 "by %<;%>");
    8510            0 :                   }
    8511              :               }
    8512            0 :             else if (has_assume)
    8513              :               /* Eat the ';'.  */
    8514            0 :               c_parser_consume_token (parser);
    8515            0 :             else if (attrs != NULL_TREE)
    8516              :               {
    8517            0 :                 auto_urlify_attributes sentinel;
    8518            0 :                 warning_at (loc, OPT_Wattributes,
    8519              :                             "only attribute %<fallthrough%> or %<assume%> can "
    8520              :                             "be applied to a null statement");
    8521            0 :               }
    8522              :             break;
    8523              :           }
    8524        18451 :         default:
    8525        18451 :           goto expr_stmt;
    8526              :         }
    8527              :       break;
    8528       207297 :     case CPP_SEMICOLON:
    8529       207297 :       c_parser_consume_token (parser);
    8530       207297 :       break;
    8531            5 :     case CPP_CLOSE_PAREN:
    8532            5 :     case CPP_CLOSE_SQUARE:
    8533              :       /* Avoid infinite loop in error recovery:
    8534              :          c_parser_skip_until_found stops at a closing nesting
    8535              :          delimiter without consuming it, but here we need to consume
    8536              :          it to proceed further.  */
    8537            5 :       c_parser_error (parser, "expected statement");
    8538            5 :       c_parser_consume_token (parser);
    8539            5 :       break;
    8540         2703 :     case CPP_PRAGMA:
    8541         2703 :       if (!c_parser_pragma (parser, pragma_stmt, if_p, before_labels))
    8542           32 :         goto restart;
    8543              :       break;
    8544      5666059 :     default:
    8545      5666059 :     expr_stmt:
    8546      5666059 :       stmt = c_finish_expr_stmt (loc, c_parser_expression_conv (parser).value);
    8547     40450239 :     expect_semicolon:
    8548     40450239 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
    8549     40450239 :       break;
    8550              :     }
    8551              :   /* Two cases cannot and do not have line numbers associated: If stmt
    8552              :      is degenerate, such as "2;", then stmt is an INTEGER_CST, which
    8553              :      cannot hold line numbers.  But that's OK because the statement
    8554              :      will either be changed to a MODIFY_EXPR during gimplification of
    8555              :      the statement expr, or discarded.  If stmt was compound, but
    8556              :      without new variables, we will have skipped the creation of a
    8557              :      BIND and will have a bare STATEMENT_LIST.  But that's OK because
    8558              :      (recursively) all of the component statements should already have
    8559              :      line numbers assigned.  ??? Can we discard no-op statements
    8560              :      earlier?  */
    8561     43115964 :   if (EXPR_LOCATION (stmt) == UNKNOWN_LOCATION)
    8562      2442896 :     protected_set_expr_location (stmt, loc);
    8563              : 
    8564     43115964 :   parser->in_if_block = in_if_block;
    8565     43115964 : }
    8566              : 
    8567              : /* Parse the condition from an if, do, while or for statements.  */
    8568              : 
    8569              : static tree
    8570       471410 : c_parser_condition (c_parser *parser)
    8571              : {
    8572       471410 :   location_t loc = c_parser_peek_token (parser)->location;
    8573       471410 :   tree cond;
    8574       471410 :   cond = c_parser_expression_conv (parser).value;
    8575       471410 :   cond = c_objc_common_truthvalue_conversion (loc, cond);
    8576       471410 :   cond = c_fully_fold (cond, false, NULL);
    8577       471410 :   if (warn_sequence_point)
    8578        82077 :     verify_sequence_points (cond);
    8579       471410 :   return cond;
    8580              : }
    8581              : 
    8582              : /* Parse a parenthesized condition from a do or while statement.
    8583              : 
    8584              :    condition:
    8585              :      ( expression )
    8586              : */
    8587              : 
    8588              : static tree
    8589       189750 : c_parser_paren_condition (c_parser *parser)
    8590              : {
    8591       189750 :   tree cond;
    8592       189750 :   matching_parens parens;
    8593       189750 :   if (!parens.require_open (parser))
    8594            0 :     return error_mark_node;
    8595       189750 :   cond = c_parser_condition (parser);
    8596       189750 :   parens.skip_until_found_close (parser);
    8597       189750 :   return cond;
    8598              : }
    8599              : 
    8600              : /* Parse a selection-header:
    8601              : 
    8602              :    selection-header:
    8603              :      expression
    8604              :      declaration expression
    8605              :      simple-declaration
    8606              : 
    8607              :    simple-declaration:
    8608              :      attribute-specifier-sequence[opt] declaration-specifiers declarator
    8609              :        = initializer
    8610              : 
    8611              :   SWITCH_P is true if we are called from c_parser_switch_statement; in
    8612              :   that case, don't perform the truthvalue conversion.  */
    8613              : 
    8614              : static c_expr
    8615      1305998 : c_parser_selection_header (c_parser *parser, bool switch_p)
    8616              : {
    8617      1305998 :   location_t loc = c_parser_peek_token (parser)->location;
    8618      1305998 :   c_expr expr;
    8619      1305998 :   bool parse_expr = true;
    8620      1305998 :   tree std_attrs;
    8621      1305998 :   bool have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
    8622      1305998 :   if (have_std_attrs)
    8623           20 :     std_attrs = c_parser_std_attribute_specifier_sequence (parser);
    8624              :   else
    8625              :     std_attrs = NULL_TREE;
    8626      1305998 :   if (c_parser_next_tokens_start_declaration (parser))
    8627              :     {
    8628          239 :       pedwarn_c23 (loc, OPT_Wpedantic,
    8629              :                    "ISO C does not support if declarations before C2Y");
    8630          239 :       expr.value
    8631          239 :         = c_parser_declaration_or_fndef (parser,
    8632              :                                          /*fndef_ok=*/false,
    8633              :                                          /*static_assert_ok=*/false,
    8634              :                                          /*empty_ok=*/false,
    8635              :                                          /*nested=*/true,
    8636              :                                          /*start_attr_ok=*/true,
    8637              :                                          /*simple_ok=*/true,
    8638              :                                          /*objc_foreach_object_decl=*/nullptr,
    8639              :                                          /*omp_declare_simd_clauses=*/nullptr,
    8640              :                                          have_std_attrs,
    8641              :                                          std_attrs);
    8642          239 :       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8643           99 :         c_parser_consume_token (parser);
    8644              :       else
    8645              :         {
    8646              :           /* A simple-declaration is a declaration that can appear in
    8647              :              place of the controlling expression of a selection statement.
    8648              :              In that case, there shall be an initializer.  */
    8649          140 :           if (!expr.value)
    8650              :             {
    8651           48 :               error_at (loc, "declaration in the controlling expression must "
    8652              :                         "have an initializer");
    8653           48 :               expr.original_type = error_mark_node;
    8654           48 :               expr.set_error ();
    8655           48 :               return expr;
    8656              :             }
    8657              :           parse_expr = false;
    8658              :         }
    8659          191 :       if (expr.value)
    8660              :         {
    8661          175 :           expr.original_type = TREE_TYPE (expr.value);
    8662          175 :           expr = convert_lvalue_to_rvalue (loc, expr, /*convert_p=*/true,
    8663              :                                            /*read_p=*/true);
    8664              :         }
    8665              :     }
    8666      1305759 :   else if (have_std_attrs)
    8667              :     {
    8668            8 :       c_parser_error (parser, "expected declaration");
    8669            8 :       expr.original_type = error_mark_node;
    8670            8 :       expr.set_error ();
    8671            8 :       return expr;
    8672              :     }
    8673              : 
    8674          191 :   if (parse_expr)
    8675      1305850 :     expr = c_parser_expression_conv (parser);
    8676      1305942 :   if (!switch_p)
    8677              :     {
    8678      1268734 :       expr.value = c_objc_common_truthvalue_conversion (loc, expr.value);
    8679      1268734 :       expr.value = c_fully_fold (expr.value, false, NULL);
    8680      1268734 :       if (warn_sequence_point)
    8681       245621 :         verify_sequence_points (expr.value);
    8682              :     }
    8683              :   return expr;
    8684              : }
    8685              : 
    8686              : /* Parse a selection-header enclosed in parentheses:
    8687              : 
    8688              :    ( selection-header )
    8689              : */
    8690              : 
    8691              : static tree
    8692      1268763 : c_parser_paren_selection_header (c_parser *parser)
    8693              : {
    8694      1268763 :   matching_parens parens;
    8695      1268763 :   if (!parens.require_open (parser))
    8696            1 :     return error_mark_node;
    8697      1268762 :   tree cond = c_parser_selection_header (parser, /*switch_p=*/false).value;
    8698      1268762 :   parens.skip_until_found_close (parser);
    8699      1268762 :   return cond;
    8700              : }
    8701              : 
    8702              : /* Parse a statement which is a block in C99.
    8703              : 
    8704              :    IF_P is used to track whether there's a (possibly labeled) if statement
    8705              :    which is not enclosed in braces and has an else clause.  This is used to
    8706              :    implement -Wparentheses.  */
    8707              : 
    8708              : static tree
    8709       522475 : c_parser_c99_block_statement (c_parser *parser, bool *if_p,
    8710              :                               location_t *loc_after_labels)
    8711              : {
    8712       522475 :   tree block = c_begin_compound_stmt (flag_isoc99);
    8713       522475 :   location_t loc = c_parser_peek_token (parser)->location;
    8714       522475 :   c_parser_statement (parser, if_p, loc_after_labels);
    8715       522475 :   return c_end_compound_stmt (loc, block, flag_isoc99);
    8716              : }
    8717              : 
    8718              : /* Parse the body of an if statement.  This is just parsing a
    8719              :    statement but (a) it is a block in C99, (b) we track whether the
    8720              :    body is an if statement for the sake of -Wparentheses warnings, (c)
    8721              :    we handle an empty body specially for the sake of -Wempty-body
    8722              :    warnings, and (d) we call parser_compound_statement directly
    8723              :    because c_parser_statement_after_labels resets
    8724              :    parser->in_if_block.
    8725              : 
    8726              :    IF_P is used to track whether there's a (possibly labeled) if statement
    8727              :    which is not enclosed in braces and has an else clause.  This is used to
    8728              :    implement -Wparentheses.  */
    8729              : 
    8730              : static tree
    8731      1268763 : c_parser_if_body (c_parser *parser, bool *if_p,
    8732              :                   const token_indent_info &if_tinfo)
    8733              : {
    8734      1268763 :   tree block = c_begin_compound_stmt (flag_isoc99);
    8735      1268763 :   location_t body_loc = c_parser_peek_token (parser)->location;
    8736      1268763 :   location_t body_loc_after_labels = UNKNOWN_LOCATION;
    8737      1268763 :   token_indent_info body_tinfo
    8738      1268763 :     = get_token_indent_info (c_parser_peek_token (parser));
    8739      1268763 :   tree before_labels = get_before_labels ();
    8740      1268763 :   attr_state a = c_parser_all_labels (parser);
    8741              : 
    8742      1268763 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8743              :     {
    8744         6735 :       location_t loc = c_parser_peek_token (parser)->location;
    8745         6735 :       add_stmt (build_empty_stmt (loc));
    8746         6735 :       c_parser_consume_token (parser);
    8747         6735 :       if (!c_parser_next_token_is_keyword (parser, RID_ELSE))
    8748          466 :         warning_at (loc, OPT_Wempty_body,
    8749              :                     "suggest braces around empty body in an %<if%> statement");
    8750              :     }
    8751      1262028 :   else if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    8752       453188 :     add_stmt (c_parser_compound_statement (parser));
    8753              :   else
    8754              :     {
    8755       808840 :       body_loc_after_labels = c_parser_peek_token (parser)->location;
    8756       808840 :       c_parser_statement_after_labels (parser, if_p, before_labels, NULL, a);
    8757              :     }
    8758              : 
    8759      1268763 :   token_indent_info next_tinfo
    8760      1268763 :     = get_token_indent_info (c_parser_peek_token (parser));
    8761      1268763 :   warn_for_misleading_indentation (if_tinfo, body_tinfo, next_tinfo);
    8762      1268763 :   if (body_loc_after_labels != UNKNOWN_LOCATION
    8763       808840 :       && next_tinfo.type != CPP_SEMICOLON)
    8764       803959 :     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
    8765       803959 :                                     if_tinfo.location, RID_IF);
    8766              : 
    8767      1268763 :   return c_end_compound_stmt (body_loc, block, flag_isoc99);
    8768              : }
    8769              : 
    8770              : /* Parse the else body of an if statement.  This is just parsing a
    8771              :    statement but (a) it is a block in C99, (b) we handle an empty body
    8772              :    specially for the sake of -Wempty-body warnings.  CHAIN is a vector
    8773              :    of if-else-if conditions.  */
    8774              : 
    8775              : static tree
    8776       257214 : c_parser_else_body (c_parser *parser, const token_indent_info &else_tinfo,
    8777              :                     vec<tree> *chain)
    8778              : {
    8779       257214 :   location_t body_loc = c_parser_peek_token (parser)->location;
    8780       257214 :   tree block = c_begin_compound_stmt (flag_isoc99);
    8781       257214 :   token_indent_info body_tinfo
    8782       257214 :     = get_token_indent_info (c_parser_peek_token (parser));
    8783       257214 :   location_t body_loc_after_labels = UNKNOWN_LOCATION;
    8784       257214 :   tree before_labels = get_before_labels ();
    8785       257214 :   attr_state a = c_parser_all_labels (parser);
    8786              : 
    8787       257214 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    8788              :     {
    8789           29 :       location_t loc = c_parser_peek_token (parser)->location;
    8790           29 :       warning_at (loc,
    8791           29 :                   OPT_Wempty_body,
    8792              :                  "suggest braces around empty body in an %<else%> statement");
    8793           29 :       add_stmt (build_empty_stmt (loc));
    8794           29 :       c_parser_consume_token (parser);
    8795              :     }
    8796              :   else
    8797              :     {
    8798       257185 :       if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
    8799       220298 :         body_loc_after_labels = c_parser_peek_token (parser)->location;
    8800       257185 :       c_parser_statement_after_labels (parser, NULL, before_labels, chain, a);
    8801              :     }
    8802              : 
    8803       257214 :   token_indent_info next_tinfo
    8804       257214 :     = get_token_indent_info (c_parser_peek_token (parser));
    8805       257214 :   warn_for_misleading_indentation (else_tinfo, body_tinfo, next_tinfo);
    8806       257214 :   if (body_loc_after_labels != UNKNOWN_LOCATION
    8807       220298 :       && next_tinfo.type != CPP_SEMICOLON)
    8808       220280 :     warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
    8809       220280 :                                     else_tinfo.location, RID_ELSE);
    8810              : 
    8811       257214 :   return c_end_compound_stmt (body_loc, block, flag_isoc99);
    8812              : }
    8813              : 
    8814              : /* Parse an if statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
    8815              : 
    8816              :    if-statement:
    8817              :      if ( selection-header ) statement
    8818              :      if ( selection-header ) statement else statement
    8819              : 
    8820              :    CHAIN is a vector of if-else-if conditions.
    8821              :    IF_P is used to track whether there's a (possibly labeled) if statement
    8822              :    which is not enclosed in braces and has an else clause.  This is used to
    8823              :    implement -Wparentheses.  */
    8824              : 
    8825              : static void
    8826      1268763 : c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
    8827              : {
    8828      1268763 :   tree block;
    8829      1268763 :   location_t loc;
    8830      1268763 :   tree cond;
    8831      1268763 :   bool nested_if = false;
    8832      1268763 :   tree first_body, second_body;
    8833      1268763 :   bool in_if_block;
    8834              : 
    8835      1268763 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_IF));
    8836      1268763 :   token_indent_info if_tinfo
    8837      1268763 :     = get_token_indent_info (c_parser_peek_token (parser));
    8838      1268763 :   c_parser_consume_token (parser);
    8839      1268763 :   block = c_begin_compound_stmt (flag_isoc99);
    8840      1268763 :   loc = c_parser_peek_token (parser)->location;
    8841      1268763 :   cond = c_parser_paren_selection_header (parser);
    8842      1268763 :   in_if_block = parser->in_if_block;
    8843      1268763 :   parser->in_if_block = true;
    8844      1268763 :   first_body = c_parser_if_body (parser, &nested_if, if_tinfo);
    8845      1268763 :   parser->in_if_block = in_if_block;
    8846              : 
    8847      1268763 :   if (warn_duplicated_cond)
    8848           62 :     warn_duplicated_cond_add_or_warn (EXPR_LOCATION (cond), cond, &chain);
    8849              : 
    8850      1268763 :   if (c_parser_next_token_is_keyword (parser, RID_ELSE))
    8851              :     {
    8852       257214 :       token_indent_info else_tinfo
    8853       257214 :         = get_token_indent_info (c_parser_peek_token (parser));
    8854       257214 :       c_parser_consume_token (parser);
    8855       257214 :       if (warn_duplicated_cond)
    8856              :         {
    8857           43 :           if (c_parser_next_token_is_keyword (parser, RID_IF)
    8858           43 :               && chain == NULL)
    8859              :             {
    8860              :               /* We've got "if (COND) else if (COND2)".  Start the
    8861              :                  condition chain and add COND as the first element.  */
    8862           18 :               chain = new vec<tree> ();
    8863           18 :               if (!CONSTANT_CLASS_P (cond) && !TREE_SIDE_EFFECTS (cond))
    8864           12 :                 chain->safe_push (cond);
    8865              :             }
    8866           25 :           else if (!c_parser_next_token_is_keyword (parser, RID_IF))
    8867              :             /* This is if-else without subsequent if.  Zap the condition
    8868              :                chain; we would have already warned at this point.  */
    8869            4 :             vec_free (chain);
    8870              :         }
    8871       257214 :       second_body = c_parser_else_body (parser, else_tinfo, chain);
    8872              :       /* Set IF_P to true to indicate that this if statement has an
    8873              :          else clause.  This may trigger the Wparentheses warning
    8874              :          below when we get back up to the parent if statement.  */
    8875       257214 :       if (if_p != NULL)
    8876          289 :         *if_p = true;
    8877              :     }
    8878              :   else
    8879              :     {
    8880      1011549 :       second_body = NULL_TREE;
    8881              : 
    8882              :       /* Diagnose an ambiguous else if if-then-else is nested inside
    8883              :          if-then.  */
    8884      1011549 :       if (nested_if)
    8885          215 :         warning_at (loc, OPT_Wdangling_else,
    8886              :                     "suggest explicit braces to avoid ambiguous %<else%>");
    8887              : 
    8888      1011549 :       if (warn_duplicated_cond)
    8889              :         /* This if statement does not have an else clause.  We don't
    8890              :            need the condition chain anymore.  */
    8891           19 :         vec_free (chain);
    8892              :     }
    8893      1268763 :   c_finish_if_stmt (loc, cond, first_body, second_body);
    8894      1268763 :   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
    8895              : 
    8896      1268763 :   c_parser_maybe_reclassify_token (parser);
    8897      1268763 : }
    8898              : 
    8899              : /* Parse a switch statement (C90 6.6.4, C99 6.8.4, C11 6.8.4).
    8900              : 
    8901              :    switch-statement:
    8902              :      switch (expression) statement
    8903              : 
    8904              :    BEFORE_LABELS is last statement before possible labels, see
    8905              :    get_before_labels description for details.  */
    8906              : 
    8907              : static void
    8908        37243 : c_parser_switch_statement (c_parser *parser, bool *if_p, tree before_labels)
    8909              : {
    8910        37243 :   struct c_expr ce;
    8911        37243 :   tree block, expr, body;
    8912        37243 :   unsigned char save_in_statement;
    8913        37243 :   location_t switch_loc = c_parser_peek_token (parser)->location;
    8914        37243 :   location_t switch_cond_loc;
    8915        37243 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_SWITCH));
    8916        37243 :   c_parser_consume_token (parser);
    8917        37243 :   tree switch_name;
    8918        37243 :   int num_names = c_get_loop_names (before_labels, true, &switch_name);
    8919        37243 :   block = c_begin_compound_stmt (flag_isoc99);
    8920        37243 :   bool explicit_cast_p = false;
    8921        37243 :   matching_parens parens;
    8922        37243 :   if (parens.require_open (parser))
    8923              :     {
    8924        37236 :       switch_cond_loc = c_parser_peek_token (parser)->location;
    8925        37236 :       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
    8926        37236 :           && c_token_starts_typename (c_parser_peek_2nd_token (parser)))
    8927              :         explicit_cast_p = true;
    8928        37236 :       ce = c_parser_selection_header (parser, /*switch_p=*/true);
    8929              :       /* The call above already performed convert_lvalue_to_rvalue, but
    8930              :          if it parsed an expression, read_p was false.  Make sure we mark
    8931              :          the expression as read.  */
    8932        37236 :       ce = convert_lvalue_to_rvalue (switch_cond_loc, ce, true, true);
    8933        37236 :       expr = ce.value;
    8934              :       /* ??? expr has no valid location?  */
    8935        37236 :       parens.skip_until_found_close (parser);
    8936              :     }
    8937              :   else
    8938              :     {
    8939            7 :       switch_cond_loc = UNKNOWN_LOCATION;
    8940            7 :       expr = error_mark_node;
    8941            7 :       ce.original_type = error_mark_node;
    8942              :     }
    8943        37243 :   tree stmt
    8944        37243 :     = c_start_switch (switch_loc, switch_cond_loc, expr, explicit_cast_p,
    8945              :                       switch_name);
    8946        37243 :   save_in_statement = in_statement;
    8947        37243 :   in_statement |= IN_SWITCH_STMT;
    8948        37243 :   if (switch_name)
    8949              :     {
    8950          122 :       C_DECL_LOOP_SWITCH_NAME_VALID (switch_name) = 1;
    8951          122 :       in_statement |= IN_NAMED_STMT;
    8952              :     }
    8953              :   else
    8954        37121 :     in_statement &= ~IN_NAMED_STMT;
    8955        37243 :   location_t loc_after_labels;
    8956        37243 :   bool open_brace_p = c_parser_peek_token (parser)->type == CPP_OPEN_BRACE;
    8957        37243 :   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
    8958        37243 :   location_t next_loc = c_parser_peek_token (parser)->location;
    8959        37243 :   if (!open_brace_p && c_parser_peek_token (parser)->type != CPP_SEMICOLON)
    8960          385 :     warn_for_multistatement_macros (loc_after_labels, next_loc, switch_loc,
    8961              :                                     RID_SWITCH);
    8962        37243 :   c_finish_switch (body, ce.original_type);
    8963        37243 :   in_statement = save_in_statement;
    8964        37243 :   if (num_names)
    8965              :     {
    8966          122 :       if (!C_DECL_LOOP_SWITCH_NAME_USED (switch_name))
    8967          110 :         SWITCH_STMT_NAME (stmt) = NULL_TREE;
    8968              :       else
    8969           12 :         SWITCH_STMT_NO_BREAK_P (stmt) = 0;
    8970          122 :       c_release_loop_names (num_names);
    8971              :     }
    8972        37243 :   add_stmt (c_end_compound_stmt (switch_loc, block, flag_isoc99));
    8973        37243 :   c_parser_maybe_reclassify_token (parser);
    8974        37243 : }
    8975              : 
    8976              : /* Parse a while statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
    8977              : 
    8978              :    while-statement:
    8979              :       while (expression) statement
    8980              : 
    8981              :    IF_P is used to track whether there's a (possibly labeled) if statement
    8982              :    which is not enclosed in braces and has an else clause.  This is used to
    8983              :    implement -Wparentheses.
    8984              : 
    8985              :    BEFORE_LABELS is last statement before possible labels, see
    8986              :    get_before_labels description for details.  */
    8987              : 
    8988              : static void
    8989        44430 : c_parser_while_statement (c_parser *parser, bool ivdep, unsigned short unroll,
    8990              :                           bool novector, bool *if_p, tree before_labels)
    8991              : {
    8992        44430 :   tree block, cond, body;
    8993        44430 :   unsigned char save_in_statement;
    8994        44430 :   location_t loc;
    8995        44430 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_WHILE));
    8996        44430 :   token_indent_info while_tinfo
    8997        44430 :     = get_token_indent_info (c_parser_peek_token (parser));
    8998        44430 :   tree loop_name;
    8999        44430 :   int num_names = c_get_loop_names (before_labels, false, &loop_name);
    9000              : 
    9001        44430 :   if (parser->omp_for_parse_state)
    9002              :     {
    9003            1 :       error_at (c_parser_peek_token (parser)->location,
    9004              :                 "loop not permitted in intervening code in OpenMP loop body");
    9005            1 :       parser->omp_for_parse_state->fail = true;
    9006              :     }
    9007              : 
    9008        44430 :   c_parser_consume_token (parser);
    9009        44430 :   block = c_begin_compound_stmt (flag_isoc99);
    9010        44430 :   loc = c_parser_peek_token (parser)->location;
    9011        44430 :   cond = c_parser_paren_condition (parser);
    9012        44430 :   if (ivdep && cond != error_mark_node)
    9013            3 :     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9014              :                    build_int_cst (integer_type_node,
    9015              :                                   annot_expr_ivdep_kind),
    9016              :                    integer_zero_node);
    9017        44430 :   if (unroll && cond != error_mark_node)
    9018            6 :     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9019              :                    build_int_cst (integer_type_node,
    9020              :                                   annot_expr_unroll_kind),
    9021            6 :                    build_int_cst (integer_type_node, unroll));
    9022        44430 :   if (novector && cond != error_mark_node)
    9023            6 :     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9024              :                    build_int_cst (integer_type_node,
    9025              :                                   annot_expr_no_vector_kind),
    9026              :                    integer_zero_node);
    9027        44430 :   save_in_statement = in_statement;
    9028        44430 :   in_statement = IN_ITERATION_STMT;
    9029        44430 :   if (loop_name)
    9030              :     {
    9031          135 :       C_DECL_LOOP_SWITCH_NAME_VALID (loop_name) = 1;
    9032          135 :       in_statement |= IN_NAMED_STMT;
    9033              :     }
    9034              : 
    9035        44430 :   token_indent_info body_tinfo
    9036        44430 :     = get_token_indent_info (c_parser_peek_token (parser));
    9037              : 
    9038        44430 :   location_t loc_after_labels;
    9039        44430 :   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
    9040        44430 :   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
    9041        44430 :   if (loop_name && !C_DECL_LOOP_SWITCH_NAME_USED (loop_name))
    9042          133 :     loop_name = NULL_TREE;
    9043        44430 :   add_stmt (build_stmt (loc, WHILE_STMT, cond, body, loop_name, NULL_TREE,
    9044              :                         NULL_TREE));
    9045        44430 :   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
    9046        44430 :   c_parser_maybe_reclassify_token (parser);
    9047        44430 :   if (num_names)
    9048          135 :     c_release_loop_names (num_names);
    9049              : 
    9050        44430 :   token_indent_info next_tinfo
    9051        44430 :     = get_token_indent_info (c_parser_peek_token (parser));
    9052        44430 :   warn_for_misleading_indentation (while_tinfo, body_tinfo, next_tinfo);
    9053              : 
    9054        44430 :   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
    9055        10638 :     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
    9056              :                                     while_tinfo.location, RID_WHILE);
    9057              : 
    9058        44430 :   in_statement = save_in_statement;
    9059        44430 : }
    9060              : 
    9061              : /* Parse a do statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
    9062              : 
    9063              :    do-statement:
    9064              :      do statement while ( expression ) ;
    9065              : 
    9066              :    BEFORE_LABELS is last statement before possible labels, see
    9067              :    get_before_labels description for details.  */
    9068              : 
    9069              : static void
    9070       145320 : c_parser_do_statement (c_parser *parser, bool ivdep, unsigned short unroll,
    9071              :                        bool novector, tree before_labels)
    9072              : {
    9073       145320 :   tree block, cond, body;
    9074       145320 :   unsigned char save_in_statement;
    9075       145320 :   location_t loc;
    9076       145320 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_DO));
    9077       145320 :   tree loop_name;
    9078       145320 :   int num_names = c_get_loop_names (before_labels, false, &loop_name);
    9079              : 
    9080       145320 :   if (parser->omp_for_parse_state)
    9081              :     {
    9082            1 :       error_at (c_parser_peek_token (parser)->location,
    9083              :                 "loop not permitted in intervening code in OpenMP loop body");
    9084            1 :       parser->omp_for_parse_state->fail = true;
    9085              :     }
    9086              : 
    9087       145320 :   c_parser_consume_token (parser);
    9088       145320 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    9089           50 :     warning_at (c_parser_peek_token (parser)->location,
    9090           50 :                 OPT_Wempty_body,
    9091              :                 "suggest braces around empty body in %<do%> statement");
    9092       145320 :   block = c_begin_compound_stmt (flag_isoc99);
    9093       145320 :   loc = c_parser_peek_token (parser)->location;
    9094       145320 :   save_in_statement = in_statement;
    9095       145320 :   in_statement = IN_ITERATION_STMT;
    9096       145320 :   if (loop_name)
    9097              :     {
    9098          176 :       C_DECL_LOOP_SWITCH_NAME_VALID (loop_name) = 1;
    9099          176 :       in_statement |= IN_NAMED_STMT;
    9100              :     }
    9101       145320 :   body = c_parser_c99_block_statement (parser, NULL);
    9102       145320 :   c_parser_require_keyword (parser, RID_WHILE, "expected %<while%>");
    9103       145320 :   in_statement = save_in_statement;
    9104       145320 :   if (num_names)
    9105              :     {
    9106          176 :       if (!C_DECL_LOOP_SWITCH_NAME_USED (loop_name))
    9107          174 :         loop_name = NULL_TREE;
    9108          176 :       c_release_loop_names (num_names);
    9109              :     }
    9110       145320 :   cond = c_parser_paren_condition (parser);
    9111       145320 :   if (ivdep && cond != error_mark_node)
    9112            2 :     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9113              :                    build_int_cst (integer_type_node,
    9114              :                                   annot_expr_ivdep_kind),
    9115              :                    integer_zero_node);
    9116       145320 :   if (unroll && cond != error_mark_node)
    9117            3 :     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9118              :                    build_int_cst (integer_type_node,
    9119              :                                   annot_expr_unroll_kind),
    9120            3 :                    build_int_cst (integer_type_node, unroll));
    9121       145320 :   if (novector && cond != error_mark_node)
    9122           54 :     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9123              :                    build_int_cst (integer_type_node,
    9124              :                                   annot_expr_no_vector_kind),
    9125              :                    integer_zero_node);
    9126       145320 :   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
    9127            0 :     c_parser_skip_to_end_of_block_or_statement (parser);
    9128              : 
    9129       145320 :   add_stmt (build_stmt (loc, DO_STMT, cond, body, loop_name));
    9130       145320 :   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
    9131       145320 : }
    9132              : 
    9133              : /* Parse a for statement (C90 6.6.5, C99 6.8.5, C11 6.8.5).
    9134              : 
    9135              :    for-statement:
    9136              :      for ( expression[opt] ; expression[opt] ; expression[opt] ) statement
    9137              :      for ( nested-declaration expression[opt] ; expression[opt] ) statement
    9138              : 
    9139              :    The form with a declaration is new in C99.
    9140              : 
    9141              :    ??? In accordance with the old parser, the declaration may be a
    9142              :    nested function, which is then rejected in check_for_loop_decls,
    9143              :    but does it make any sense for this to be included in the grammar?
    9144              :    Note in particular that the nested function does not include a
    9145              :    trailing ';', whereas the "declaration" production includes one.
    9146              :    Also, can we reject bad declarations earlier and cheaper than
    9147              :    check_for_loop_decls?
    9148              : 
    9149              :    In Objective-C, there are two additional variants:
    9150              : 
    9151              :    foreach-statement:
    9152              :      for ( expression in expresssion ) statement
    9153              :      for ( declaration in expression ) statement
    9154              : 
    9155              :    This is inconsistent with C, because the second variant is allowed
    9156              :    even if c99 is not enabled.
    9157              : 
    9158              :    The rest of the comment documents these Objective-C foreach-statement.
    9159              : 
    9160              :    Here is the canonical example of the first variant:
    9161              :     for (object in array)    { do something with object }
    9162              :    we call the first expression ("object") the "object_expression" and
    9163              :    the second expression ("array") the "collection_expression".
    9164              :    object_expression must be an lvalue of type "id" (a generic Objective-C
    9165              :    object) because the loop works by assigning to object_expression the
    9166              :    various objects from the collection_expression.  collection_expression
    9167              :    must evaluate to something of type "id" which responds to the method
    9168              :    countByEnumeratingWithState:objects:count:.
    9169              : 
    9170              :    The canonical example of the second variant is:
    9171              :     for (id object in array)    { do something with object }
    9172              :    which is completely equivalent to
    9173              :     {
    9174              :       id object;
    9175              :       for (object in array) { do something with object }
    9176              :     }
    9177              :    Note that initizializing 'object' in some way (eg, "for ((object =
    9178              :    xxx) in array) { do something with object }") is possibly
    9179              :    technically valid, but completely pointless as 'object' will be
    9180              :    assigned to something else as soon as the loop starts.  We should
    9181              :    most likely reject it (TODO).
    9182              : 
    9183              :    The beginning of the Objective-C foreach-statement looks exactly
    9184              :    like the beginning of the for-statement, and we can tell it is a
    9185              :    foreach-statement only because the initial declaration or
    9186              :    expression is terminated by 'in' instead of ';'.
    9187              : 
    9188              :    IF_P is used to track whether there's a (possibly labeled) if statement
    9189              :    which is not enclosed in braces and has an else clause.  This is used to
    9190              :    implement -Wparentheses.
    9191              : 
    9192              :    BEFORE_LABELS is last statement before possible labels, see
    9193              :    get_before_labels description for details.  */
    9194              : 
    9195              : static void
    9196       284798 : c_parser_for_statement (c_parser *parser, bool ivdep, unsigned short unroll,
    9197              :                         bool novector, bool *if_p, tree before_labels)
    9198              : {
    9199       284798 :   tree block, cond, incr, body;
    9200       284798 :   unsigned char save_in_statement;
    9201       284798 :   tree save_objc_foreach_break_label, save_objc_foreach_continue_label;
    9202              :   /* The following are only used when parsing an ObjC foreach statement.  */
    9203       284798 :   tree object_expression;
    9204              :   /* Silence the bogus uninitialized warning.  */
    9205       284798 :   tree collection_expression = NULL;
    9206       284798 :   location_t loc = c_parser_peek_token (parser)->location;
    9207       284798 :   location_t for_loc = loc;
    9208       284798 :   bool is_foreach_statement = false;
    9209       284798 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
    9210       284798 :   token_indent_info for_tinfo
    9211       284798 :     = get_token_indent_info (c_parser_peek_token (parser));
    9212       284798 :   tree loop_name;
    9213       284798 :   int num_names = c_get_loop_names (before_labels, false, &loop_name);
    9214              : 
    9215       284798 :   if (parser->omp_for_parse_state)
    9216              :     {
    9217           13 :       error_at (for_loc,
    9218              :                 "loop not permitted in intervening code in OpenMP loop body");
    9219           13 :       parser->omp_for_parse_state->fail = true;
    9220              :     }
    9221              : 
    9222       284798 :   c_parser_consume_token (parser);
    9223              :   /* Open a compound statement in Objective-C as well, just in case this is
    9224              :      as foreach expression.  */
    9225       568709 :   block = c_begin_compound_stmt (flag_isoc99 || c_dialect_objc ());
    9226       284798 :   cond = error_mark_node;
    9227       284798 :   incr = error_mark_node;
    9228       284798 :   matching_parens parens;
    9229       284798 :   if (parens.require_open (parser))
    9230              :     {
    9231              :       /* Parse the initialization declaration or expression.  */
    9232       284797 :       object_expression = error_mark_node;
    9233       284797 :       parser->objc_could_be_foreach_context = c_dialect_objc ();
    9234       284797 :       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    9235              :         {
    9236        12484 :           parser->objc_could_be_foreach_context = false;
    9237        12484 :           c_parser_consume_token (parser);
    9238        12484 :           c_finish_expr_stmt (loc, NULL_TREE);
    9239              :         }
    9240       272313 :       else if (c_parser_next_tokens_start_declaration (parser)
    9241       272313 :                || c_parser_nth_token_starts_std_attributes (parser, 1))
    9242              :         {
    9243        20995 :           c_parser_declaration_or_fndef (parser, true, true, true, true, true,
    9244              :                                          false, &object_expression);
    9245        20995 :           parser->objc_could_be_foreach_context = false;
    9246              : 
    9247        20995 :           if (c_parser_next_token_is_keyword (parser, RID_IN))
    9248              :             {
    9249            0 :               c_parser_consume_token (parser);
    9250            0 :               is_foreach_statement = true;
    9251            0 :               if (check_for_loop_decls (for_loc, true) == NULL_TREE)
    9252            0 :                 c_parser_error (parser, "multiple iterating variables in "
    9253              :                                         "fast enumeration");
    9254              :             }
    9255              :           else
    9256        20995 :             check_for_loop_decls (for_loc, flag_isoc99);
    9257              :         }
    9258       251318 :       else if (c_parser_next_token_is_keyword (parser, RID_EXTENSION))
    9259              :         {
    9260              :           /* __extension__ can start a declaration, but is also an
    9261              :              unary operator that can start an expression.  Consume all
    9262              :              but the last of a possible series of __extension__ to
    9263              :              determine which.  */
    9264            0 :           while (c_parser_peek_2nd_token (parser)->type == CPP_KEYWORD
    9265            0 :                  && (c_parser_peek_2nd_token (parser)->keyword
    9266              :                      == RID_EXTENSION))
    9267            0 :             c_parser_consume_token (parser);
    9268            0 :           if (c_parser_next_tokens_start_declaration (parser, 2)
    9269            0 :               || c_parser_nth_token_starts_std_attributes (parser, 2))
    9270              :             {
    9271            0 :               int ext;
    9272            0 :               ext = disable_extension_diagnostics ();
    9273            0 :               c_parser_consume_token (parser);
    9274            0 :               c_parser_declaration_or_fndef (parser, true, true, true, true,
    9275              :                                              true, false, &object_expression);
    9276            0 :               parser->objc_could_be_foreach_context = false;
    9277              : 
    9278            0 :               restore_extension_diagnostics (ext);
    9279            0 :               if (c_parser_next_token_is_keyword (parser, RID_IN))
    9280              :                 {
    9281            0 :                   c_parser_consume_token (parser);
    9282            0 :                   is_foreach_statement = true;
    9283            0 :                   if (check_for_loop_decls (for_loc, true) == NULL_TREE)
    9284            0 :                     c_parser_error (parser, "multiple iterating variables in "
    9285              :                                             "fast enumeration");
    9286              :                 }
    9287              :               else
    9288            0 :                 check_for_loop_decls (for_loc, flag_isoc99);
    9289              :             }
    9290              :           else
    9291            0 :             goto init_expr;
    9292              :         }
    9293              :       else
    9294              :         {
    9295       251318 :         init_expr:
    9296       251318 :           {
    9297       251318 :             struct c_expr ce;
    9298       251318 :             tree init_expression;
    9299       251318 :             ce = c_parser_expression (parser);
    9300       251318 :             init_expression = ce.value;
    9301       251318 :             parser->objc_could_be_foreach_context = false;
    9302       251318 :             if (c_parser_next_token_is_keyword (parser, RID_IN))
    9303              :               {
    9304            0 :                 c_parser_consume_token (parser);
    9305            0 :                 is_foreach_statement = true;
    9306            0 :                 if (! lvalue_p (init_expression))
    9307            0 :                   c_parser_error (parser, "invalid iterating variable in "
    9308              :                                           "fast enumeration");
    9309            0 :                 object_expression
    9310            0 :                   = c_fully_fold (init_expression, false, NULL);
    9311              :               }
    9312              :             else
    9313              :               {
    9314       251318 :                 ce = convert_lvalue_to_rvalue (loc, ce, true, false);
    9315       251318 :                 init_expression = ce.value;
    9316       251318 :                 c_finish_expr_stmt (loc, init_expression);
    9317       251318 :                 c_parser_skip_until_found (parser, CPP_SEMICOLON,
    9318              :                                            "expected %<;%>");
    9319              :               }
    9320              :           }
    9321              :         }
    9322              :       /* Parse the loop condition.  In the case of a foreach
    9323              :          statement, there is no loop condition.  */
    9324       284797 :       gcc_assert (!parser->objc_could_be_foreach_context);
    9325       284797 :       if (!is_foreach_statement)
    9326              :         {
    9327       284797 :           if (c_parser_next_token_is (parser, CPP_SEMICOLON))
    9328              :             {
    9329         3137 :               if (ivdep)
    9330              :                 {
    9331            1 :                   c_parser_error (parser, "missing loop condition in loop "
    9332              :                                           "with %<GCC ivdep%> pragma");
    9333            1 :                   cond = error_mark_node;
    9334              :                 }
    9335         3136 :               else if (unroll)
    9336              :                 {
    9337            0 :                   c_parser_error (parser, "missing loop condition in loop "
    9338              :                                           "with %<GCC unroll%> pragma");
    9339            0 :                   cond = error_mark_node;
    9340              :                 }
    9341              :               else
    9342              :                 {
    9343         3136 :                   c_parser_consume_token (parser);
    9344         3136 :                   cond = NULL_TREE;
    9345              :                 }
    9346              :             }
    9347              :           else
    9348              :             {
    9349       281660 :               cond = c_parser_condition (parser);
    9350       281660 :               c_parser_skip_until_found (parser, CPP_SEMICOLON,
    9351              :                                          "expected %<;%>");
    9352              :             }
    9353       284797 :           if (ivdep && cond != error_mark_node)
    9354          122 :             cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9355              :                            build_int_cst (integer_type_node,
    9356              :                                           annot_expr_ivdep_kind),
    9357              :                            integer_zero_node);
    9358       284797 :           if (unroll && cond != error_mark_node)
    9359          275 :             cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9360              :                            build_int_cst (integer_type_node,
    9361              :                                           annot_expr_unroll_kind),
    9362          275 :                            build_int_cst (integer_type_node, unroll));
    9363       284797 :           if (novector && cond && cond != error_mark_node)
    9364         2850 :             cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
    9365              :                            build_int_cst (integer_type_node,
    9366              :                                           annot_expr_no_vector_kind),
    9367              :                            integer_zero_node);
    9368              :         }
    9369              :       /* Parse the increment expression (the third expression in a
    9370              :          for-statement).  In the case of a foreach-statement, this is
    9371              :          the expression that follows the 'in'.  */
    9372       284797 :       loc = c_parser_peek_token (parser)->location;
    9373       284797 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    9374              :         {
    9375         4323 :           if (is_foreach_statement)
    9376              :             {
    9377            0 :               c_parser_error (parser,
    9378              :                               "missing collection in fast enumeration");
    9379            0 :               collection_expression = error_mark_node;
    9380              :             }
    9381              :           else
    9382         4323 :             incr = c_process_expr_stmt (loc, NULL_TREE);
    9383              :         }
    9384              :       else
    9385              :         {
    9386       280474 :           if (is_foreach_statement)
    9387            0 :             collection_expression
    9388            0 :               = c_fully_fold (c_parser_expression (parser).value, false, NULL);
    9389              :           else
    9390              :             {
    9391       280474 :               struct c_expr ce = c_parser_expression (parser);
    9392       280474 :               ce = convert_lvalue_to_rvalue (loc, ce, true, false);
    9393       280474 :               incr = c_process_expr_stmt (loc, ce.value);
    9394              :             }
    9395              :         }
    9396       284797 :       parens.skip_until_found_close (parser);
    9397              :     }
    9398       284798 :   save_in_statement = in_statement;
    9399       284798 :   if (is_foreach_statement)
    9400              :     {
    9401            0 :       in_statement = IN_OBJC_FOREACH;
    9402            0 :       save_objc_foreach_break_label = objc_foreach_break_label;
    9403            0 :       save_objc_foreach_continue_label = objc_foreach_continue_label;
    9404            0 :       objc_foreach_break_label = create_artificial_label (loc);
    9405            0 :       objc_foreach_continue_label = create_artificial_label (loc);
    9406            0 :       if (loop_name)
    9407              :         {
    9408            0 :           gcc_checking_assert (!DECL_CHAIN (loop_name)
    9409              :                                && !DECL_CHAIN (objc_foreach_break_label));
    9410            0 :           C_DECL_SWITCH_NAME (loop_name) = 1;
    9411            0 :           DECL_CHAIN (loop_name) = objc_foreach_break_label;
    9412            0 :           DECL_CHAIN (objc_foreach_break_label) = objc_foreach_continue_label;
    9413              :         }
    9414              :     }
    9415              :   else
    9416       284798 :     in_statement = IN_ITERATION_STMT;
    9417       284798 :   if (loop_name)
    9418              :     {
    9419          460 :       C_DECL_LOOP_SWITCH_NAME_VALID (loop_name) = 1;
    9420          460 :       in_statement |= IN_NAMED_STMT;
    9421              :     }
    9422              : 
    9423       284798 :   token_indent_info body_tinfo
    9424       284798 :     = get_token_indent_info (c_parser_peek_token (parser));
    9425              : 
    9426       284798 :   location_t loc_after_labels;
    9427       284798 :   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
    9428       284798 :   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
    9429              : 
    9430       284798 :   if (loop_name && is_foreach_statement)
    9431              :     {
    9432            0 :       gcc_checking_assert (DECL_CHAIN (loop_name) == objc_foreach_break_label
    9433              :                            && (DECL_CHAIN (objc_foreach_break_label)
    9434              :                                == objc_foreach_continue_label));
    9435            0 :       C_DECL_SWITCH_NAME (loop_name) = 0;
    9436            0 :       DECL_CHAIN (loop_name) = NULL_TREE;
    9437            0 :       DECL_CHAIN (objc_foreach_break_label) = NULL_TREE;
    9438              :     }
    9439              : 
    9440       284338 :   if (is_foreach_statement)
    9441            0 :     objc_finish_foreach_loop (for_loc, object_expression,
    9442              :                               collection_expression, body,
    9443              :                               objc_foreach_break_label,
    9444              :                               objc_foreach_continue_label);
    9445              :   else
    9446       569596 :     add_stmt (build_stmt (for_loc, FOR_STMT, NULL_TREE, cond, incr,
    9447              :                           body, NULL_TREE,
    9448          460 :                           loop_name && C_DECL_LOOP_SWITCH_NAME_USED (loop_name)
    9449              :                           ? loop_name : NULL_TREE, NULL_TREE, NULL_TREE));
    9450       284798 :   add_stmt (c_end_compound_stmt (for_loc, block,
    9451       284798 :                                  flag_isoc99 || c_dialect_objc ()));
    9452       284798 :   c_parser_maybe_reclassify_token (parser);
    9453              : 
    9454       284798 :   token_indent_info next_tinfo
    9455       284798 :     = get_token_indent_info (c_parser_peek_token (parser));
    9456       284798 :   warn_for_misleading_indentation (for_tinfo, body_tinfo, next_tinfo);
    9457              : 
    9458       284798 :   if (next_tinfo.type != CPP_SEMICOLON && !open_brace)
    9459       167782 :     warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
    9460              :                                     for_tinfo.location, RID_FOR);
    9461              : 
    9462       284798 :   in_statement = save_in_statement;
    9463       284798 :   if (num_names)
    9464          460 :     c_release_loop_names (num_names);
    9465       284798 :   if (is_foreach_statement)
    9466              :     {
    9467            0 :       objc_foreach_break_label = save_objc_foreach_break_label;
    9468            0 :       objc_foreach_continue_label = save_objc_foreach_continue_label;
    9469              :     }
    9470       284798 : }
    9471              : 
    9472              : /* Parse an asm statement, a GNU extension.  This is a full-blown asm
    9473              :    statement with inputs, outputs, clobbers, and volatile, inline, and goto
    9474              :    tags allowed.
    9475              : 
    9476              :    asm-qualifier:
    9477              :      volatile
    9478              :      inline
    9479              :      goto
    9480              : 
    9481              :    asm-qualifier-list:
    9482              :      asm-qualifier-list asm-qualifier
    9483              :      asm-qualifier
    9484              : 
    9485              :    asm-statement:
    9486              :      asm asm-qualifier-list[opt] ( asm-argument ) ;
    9487              : 
    9488              :    asm-argument:
    9489              :      asm-string-literal
    9490              :      asm-string-literal : asm-operands[opt]
    9491              :      asm-string-literal : asm-operands[opt] : asm-operands[opt]
    9492              :      asm-string-literal : asm-operands[opt] : asm-operands[opt] \
    9493              :        : asm-clobbers[opt]
    9494              :      asm-string-literal : : asm-operands[opt] : asm-clobbers[opt] \
    9495              :        : asm-goto-operands
    9496              : 
    9497              :    The form with asm-goto-operands is valid if and only if the
    9498              :    asm-qualifier-list contains goto, and is the only allowed form in that case.
    9499              :    Duplicate asm-qualifiers are not allowed.
    9500              : 
    9501              :    The :: token is considered equivalent to two consecutive : tokens.  */
    9502              : 
    9503              : static tree
    9504       204806 : c_parser_asm_statement (c_parser *parser)
    9505              : {
    9506       204806 :   tree str, outputs, inputs, clobbers, labels, ret;
    9507       204806 :   bool simple;
    9508       204806 :   location_t asm_loc = c_parser_peek_token (parser)->location;
    9509       204806 :   int section, nsections;
    9510              : 
    9511       204806 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
    9512       204806 :   c_parser_consume_token (parser);
    9513              : 
    9514              :   /* Handle the asm-qualifier-list.  */
    9515       204806 :   location_t volatile_loc = UNKNOWN_LOCATION;
    9516       204806 :   location_t inline_loc = UNKNOWN_LOCATION;
    9517       204806 :   location_t goto_loc = UNKNOWN_LOCATION;
    9518       370321 :   for (;;)
    9519              :     {
    9520       370321 :       c_token *token = c_parser_peek_token (parser);
    9521       370321 :       location_t loc = token->location;
    9522       370321 :       switch (token->keyword)
    9523              :         {
    9524       164991 :         case RID_VOLATILE:
    9525       164991 :           if (volatile_loc)
    9526              :             {
    9527            6 :               error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
    9528            6 :               inform (volatile_loc, "first seen here");
    9529              :             }
    9530              :           else
    9531              :             volatile_loc = loc;
    9532       164991 :           c_parser_consume_token (parser);
    9533       164991 :           continue;
    9534              : 
    9535           38 :         case RID_INLINE:
    9536           38 :           if (inline_loc)
    9537              :             {
    9538            6 :               error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
    9539            6 :               inform (inline_loc, "first seen here");
    9540              :             }
    9541              :           else
    9542              :             inline_loc = loc;
    9543           38 :           c_parser_consume_token (parser);
    9544           38 :           continue;
    9545              : 
    9546          484 :         case RID_GOTO:
    9547          484 :           if (goto_loc)
    9548              :             {
    9549            6 :               error_at (loc, "duplicate %<asm%> qualifier %qE", token->value);
    9550            6 :               inform (goto_loc, "first seen here");
    9551              :             }
    9552              :           else
    9553              :             goto_loc = loc;
    9554          484 :           c_parser_consume_token (parser);
    9555          484 :           continue;
    9556              : 
    9557            2 :         case RID_CONST:
    9558            2 :         case RID_RESTRICT:
    9559            2 :           error_at (loc, "%qE is not a valid %<asm%> qualifier", token->value);
    9560            2 :           c_parser_consume_token (parser);
    9561            2 :           continue;
    9562              : 
    9563       204806 :         default:
    9564       204806 :           break;
    9565              :         }
    9566       204806 :       break;
    9567              :     }
    9568              : 
    9569       204806 :   bool is_volatile = (volatile_loc != UNKNOWN_LOCATION);
    9570       204806 :   bool is_inline = (inline_loc != UNKNOWN_LOCATION);
    9571       204806 :   bool is_goto = (goto_loc != UNKNOWN_LOCATION);
    9572              : 
    9573       204806 :   ret = NULL;
    9574              : 
    9575       204806 :   matching_parens parens;
    9576       204806 :   if (!parens.require_open (parser))
    9577            0 :     goto error;
    9578              : 
    9579       204806 :   str = c_parser_asm_string_literal (parser);
    9580       204806 :   if (str == NULL_TREE)
    9581           12 :     goto error_close_paren;
    9582              : 
    9583       204794 :   simple = true;
    9584       204794 :   outputs = NULL_TREE;
    9585       204794 :   inputs = NULL_TREE;
    9586       204794 :   clobbers = NULL_TREE;
    9587       204794 :   labels = NULL_TREE;
    9588              : 
    9589       204794 :   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
    9590         1861 :     goto done_asm;
    9591              : 
    9592              :   /* Parse each colon-delimited section of operands.  */
    9593       202933 :   nsections = 3 + is_goto;
    9594       518188 :   for (section = 0; section < nsections; ++section)
    9595              :     {
    9596       517720 :       if (c_parser_next_token_is (parser, CPP_SCOPE))
    9597              :         {
    9598        35612 :           ++section;
    9599        35612 :           if (section == nsections)
    9600              :             {
    9601            5 :               c_parser_error (parser, "expected %<)%>");
    9602            5 :               goto error_close_paren;
    9603              :             }
    9604        35607 :           c_parser_consume_token (parser);
    9605              :         }
    9606       962612 :       else if (!c_parser_require (parser, CPP_COLON,
    9607              :                                   is_goto
    9608              :                                   ? G_("expected %<:%>")
    9609              :                                   : G_("expected %<:%> or %<)%>"),
    9610              :                                   UNKNOWN_LOCATION, is_goto))
    9611            7 :         goto error_close_paren;
    9612              : 
    9613              :       /* Once past any colon, we're no longer a simple asm.  */
    9614       517708 :       simple = false;
    9615              : 
    9616       517708 :       if ((!c_parser_next_token_is (parser, CPP_COLON)
    9617       421286 :            && !c_parser_next_token_is (parser, CPP_SCOPE)
    9618       421216 :            && !c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
    9619       522646 :           || section == 3)
    9620       416349 :         switch (section)
    9621              :           {
    9622       132392 :           case 0:
    9623       132392 :             outputs = c_parser_asm_operands (parser);
    9624       132392 :             break;
    9625       131837 :           case 1:
    9626       131837 :             inputs = c_parser_asm_operands (parser);
    9627       131837 :             break;
    9628       151652 :           case 2:
    9629       151652 :             clobbers = c_parser_asm_clobbers (parser);
    9630       151652 :             break;
    9631          468 :           case 3:
    9632          468 :             labels = c_parser_asm_goto_operands (parser);
    9633          468 :             break;
    9634            0 :           default:
    9635            0 :             gcc_unreachable ();
    9636              :           }
    9637              : 
    9638       517708 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN) && !is_goto)
    9639       202453 :         goto done_asm;
    9640              :     }
    9641              : 
    9642          468 :  done_asm:
    9643       204782 :   if (!parens.require_close (parser))
    9644              :     {
    9645            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    9646            0 :       goto error;
    9647              :     }
    9648              : 
    9649       204782 :   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
    9650            0 :     c_parser_skip_to_end_of_block_or_statement (parser);
    9651              : 
    9652       204782 :   ret = build_asm_stmt (is_volatile,
    9653              :                         build_asm_expr (asm_loc, str, outputs, inputs,
    9654              :                                         clobbers, labels, simple, is_inline));
    9655              : 
    9656       204806 :  error:
    9657       204806 :   return ret;
    9658              : 
    9659           24 :  error_close_paren:
    9660           24 :   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    9661           24 :   goto error;
    9662              : }
    9663              : 
    9664              : /* Parse asm operands, a GNU extension.
    9665              : 
    9666              :    asm-operands:
    9667              :      asm-operand
    9668              :      asm-operands , asm-operand
    9669              : 
    9670              :    asm-operand:
    9671              :      asm-string-literal ( expression )
    9672              :      [ identifier ] asm-string-literal ( expression )
    9673              : */
    9674              : 
    9675              : static tree
    9676       264285 : c_parser_asm_operands (c_parser *parser)
    9677              : {
    9678       264285 :   tree list = NULL_TREE;
    9679      1161387 :   while (true)
    9680              :     {
    9681       712836 :       tree name, str;
    9682       712836 :       struct c_expr expr;
    9683       712836 :       if (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
    9684              :         {
    9685          730 :           c_parser_consume_token (parser);
    9686          730 :           if (c_parser_next_token_is (parser, CPP_NAME))
    9687              :             {
    9688          730 :               tree id = c_parser_peek_token (parser)->value;
    9689          730 :               c_parser_consume_token (parser);
    9690          730 :               name = build_string (IDENTIFIER_LENGTH (id),
    9691          730 :                                    IDENTIFIER_POINTER (id));
    9692              :             }
    9693              :           else
    9694              :             {
    9695            0 :               c_parser_error (parser, "expected identifier");
    9696            0 :               c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE, NULL);
    9697            0 :               return NULL_TREE;
    9698              :             }
    9699          730 :           c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
    9700              :                                      "expected %<]%>");
    9701              :         }
    9702              :       else
    9703              :         name = NULL_TREE;
    9704       712836 :       str = c_parser_asm_string_literal (parser);
    9705       712836 :       if (str == NULL_TREE)
    9706              :         return NULL_TREE;
    9707       712836 :       matching_parens parens;
    9708       712836 :       if (!parens.require_open (parser))
    9709              :         return NULL_TREE;
    9710       712836 :       expr = c_parser_expression (parser);
    9711       712836 :       mark_exp_read (expr.value);
    9712       712836 :       if (!parens.require_close (parser))
    9713              :         {
    9714            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
    9715            0 :           return NULL_TREE;
    9716              :         }
    9717       712836 :       list = chainon (list, build_tree_list (build_tree_list (name, str),
    9718              :                                              expr.value));
    9719       712836 :       if (c_parser_next_token_is (parser, CPP_COMMA))
    9720       448551 :         c_parser_consume_token (parser);
    9721              :       else
    9722              :         break;
    9723       448551 :     }
    9724       264285 :   return list;
    9725              : }
    9726              : 
    9727              : /* Parse asm clobbers, a GNU extension.
    9728              : 
    9729              :    asm-clobbers:
    9730              :      asm-string-literal
    9731              :      asm-clobbers , asm-string-literal
    9732              : */
    9733              : 
    9734              : static tree
    9735       151652 : c_parser_asm_clobbers (c_parser *parser)
    9736              : {
    9737       151652 :   tree list = NULL_TREE;
    9738       205678 :   while (true)
    9739              :     {
    9740       178665 :       tree str = c_parser_asm_string_literal (parser);
    9741       178665 :       if (str)
    9742       178665 :         list = tree_cons (NULL_TREE, str, list);
    9743              :       else
    9744              :         return NULL_TREE;
    9745       178665 :       if (c_parser_next_token_is (parser, CPP_COMMA))
    9746        27013 :         c_parser_consume_token (parser);
    9747              :       else
    9748              :         break;
    9749        27013 :     }
    9750              :   return list;
    9751              : }
    9752              : 
    9753              : /* Parse asm goto labels, a GNU extension.
    9754              : 
    9755              :    asm-goto-operands:
    9756              :      identifier
    9757              :      asm-goto-operands , identifier
    9758              : */
    9759              : 
    9760              : static tree
    9761          468 : c_parser_asm_goto_operands (c_parser *parser)
    9762              : {
    9763          468 :   tree list = NULL_TREE;
    9764         1104 :   while (true)
    9765              :     {
    9766          786 :       tree name, label;
    9767              : 
    9768          786 :       if (c_parser_next_token_is (parser, CPP_NAME))
    9769              :         {
    9770          785 :           c_token *tok = c_parser_peek_token (parser);
    9771          785 :           name = tok->value;
    9772          785 :           label = lookup_label_for_goto (tok->location, name);
    9773          785 :           c_parser_consume_token (parser);
    9774          785 :           TREE_USED (label) = 1;
    9775              :         }
    9776              :       else
    9777              :         {
    9778            1 :           c_parser_error (parser, "expected identifier");
    9779            1 :           return NULL_TREE;
    9780              :         }
    9781              : 
    9782          785 :       name = build_string (IDENTIFIER_LENGTH (name),
    9783          785 :                            IDENTIFIER_POINTER (name));
    9784          785 :       list = tree_cons (name, label, list);
    9785          785 :       if (c_parser_next_token_is (parser, CPP_COMMA))
    9786          318 :         c_parser_consume_token (parser);
    9787              :       else
    9788          467 :         return nreverse (list);
    9789          318 :     }
    9790              : }
    9791              : 
    9792              : /* Parse a possibly concatenated sequence of string literals.
    9793              :    TRANSLATE says whether to translate them to the execution character
    9794              :    set; WIDE_OK says whether any kind of prefixed string literal is
    9795              :    permitted in this context.  This code is based on that in
    9796              :    lex_string.  */
    9797              : 
    9798              : struct c_expr
    9799      3769007 : c_parser_string_literal (c_parser *parser, bool translate, bool wide_ok)
    9800              : {
    9801      3769007 :   struct c_expr ret;
    9802      3769007 :   size_t count;
    9803      3769007 :   struct obstack str_ob;
    9804      3769007 :   struct obstack loc_ob;
    9805      3769007 :   cpp_string str, istr, *strs;
    9806      3769007 :   c_token *tok;
    9807      3769007 :   location_t loc, last_tok_loc;
    9808      3769007 :   enum cpp_ttype type;
    9809      3769007 :   tree value, string_tree;
    9810              : 
    9811      3769007 :   tok = c_parser_peek_token (parser);
    9812      3769007 :   loc = tok->location;
    9813      3769007 :   last_tok_loc = linemap_resolve_location (line_table, loc,
    9814              :                                            LRK_MACRO_DEFINITION_LOCATION,
    9815              :                                            NULL);
    9816      3769007 :   type = tok->type;
    9817      3769007 :   switch (type)
    9818              :     {
    9819      3768990 :     case CPP_STRING:
    9820      3768990 :     case CPP_WSTRING:
    9821      3768990 :     case CPP_STRING16:
    9822      3768990 :     case CPP_STRING32:
    9823      3768990 :     case CPP_UTF8STRING:
    9824      3768990 :       string_tree = tok->value;
    9825      3768990 :       break;
    9826              : 
    9827           17 :     default:
    9828           17 :       c_parser_error (parser, "expected string literal");
    9829           17 :       ret.set_error ();
    9830           17 :       ret.value = NULL_TREE;
    9831           17 :       ret.original_code = ERROR_MARK;
    9832           17 :       ret.original_type = NULL_TREE;
    9833           17 :       return ret;
    9834              :     }
    9835              : 
    9836              :   /* Try to avoid the overhead of creating and destroying an obstack
    9837              :      for the common case of just one string.  */
    9838      3768990 :   switch (c_parser_peek_2nd_token (parser)->type)
    9839              :     {
    9840      2888088 :     default:
    9841      2888088 :       c_parser_consume_token (parser);
    9842      2888088 :       str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
    9843      2888088 :       str.len = TREE_STRING_LENGTH (string_tree);
    9844      2888088 :       count = 1;
    9845      2888088 :       strs = &str;
    9846      2888088 :       break;
    9847              : 
    9848       880902 :     case CPP_STRING:
    9849       880902 :     case CPP_WSTRING:
    9850       880902 :     case CPP_STRING16:
    9851       880902 :     case CPP_STRING32:
    9852       880902 :     case CPP_UTF8STRING:
    9853       880902 :       gcc_obstack_init (&str_ob);
    9854       880902 :       gcc_obstack_init (&loc_ob);
    9855       880902 :       count = 0;
    9856     27871769 :       do
    9857              :         {
    9858     27871769 :           c_parser_consume_token (parser);
    9859     27871769 :           count++;
    9860     27871769 :           str.text = (const unsigned char *) TREE_STRING_POINTER (string_tree);
    9861     27871769 :           str.len = TREE_STRING_LENGTH (string_tree);
    9862     27871769 :           if (type != tok->type)
    9863              :             {
    9864          669 :               if (type == CPP_STRING)
    9865           29 :                 type = tok->type;
    9866          640 :               else if (tok->type != CPP_STRING)
    9867           66 :                 error ("unsupported non-standard concatenation "
    9868              :                        "of string literals");
    9869              :             }
    9870     27871769 :           obstack_grow (&str_ob, &str, sizeof (cpp_string));
    9871     27871769 :           obstack_grow (&loc_ob, &last_tok_loc, sizeof (location_t));
    9872     27871769 :           tok = c_parser_peek_token (parser);
    9873     27871769 :           string_tree = tok->value;
    9874     27871769 :           last_tok_loc
    9875     27871769 :             = linemap_resolve_location (line_table, tok->location,
    9876              :                                         LRK_MACRO_DEFINITION_LOCATION, NULL);
    9877              :         }
    9878     27871769 :       while (tok->type == CPP_STRING
    9879              :              || tok->type == CPP_WSTRING
    9880              :              || tok->type == CPP_STRING16
    9881              :              || tok->type == CPP_STRING32
    9882     27871769 :              || tok->type == CPP_UTF8STRING);
    9883       880902 :       strs = (cpp_string *) obstack_finish (&str_ob);
    9884              :     }
    9885              : 
    9886      3768990 :   if (count > 1 && !in_system_header_at (input_location))
    9887       658717 :     warning (OPT_Wtraditional,
    9888              :              "traditional C rejects string constant concatenation");
    9889              : 
    9890      3768990 :   if ((type == CPP_STRING || wide_ok)
    9891      7537970 :       && ((translate
    9892      3768980 :           ? cpp_interpret_string : cpp_interpret_string_notranslate)
    9893      3768980 :           (parse_in, strs, count, &istr, type)))
    9894              :     {
    9895      3768980 :       value = build_string (istr.len, (const char *) istr.text);
    9896      3768980 :       free (const_cast<unsigned char *> (istr.text));
    9897      3768980 :       if (count > 1)
    9898              :         {
    9899       880902 :           location_t *locs = (location_t *) obstack_finish (&loc_ob);
    9900       880902 :           gcc_assert (g_string_concat_db);
    9901       880902 :           g_string_concat_db->record_string_concatenation (count, locs);
    9902              :         }
    9903              :     }
    9904              :   else
    9905              :     {
    9906           10 :       if (type != CPP_STRING && !wide_ok)
    9907              :         {
    9908           10 :           error_at (loc, "a wide string is invalid in this context");
    9909           10 :           type = CPP_STRING;
    9910              :         }
    9911              :       /* Callers cannot generally handle error_mark_node in this
    9912              :          context, so return the empty string instead.  An error has
    9913              :          been issued, either above or from cpp_interpret_string.  */
    9914           10 :       switch (type)
    9915              :         {
    9916           10 :         default:
    9917           10 :         case CPP_STRING:
    9918           10 :         case CPP_UTF8STRING:
    9919           10 :           if (type == CPP_UTF8STRING && flag_char8_t)
    9920              :             {
    9921            0 :               value = build_string (TYPE_PRECISION (char8_type_node)
    9922            0 :                                     / TYPE_PRECISION (char_type_node),
    9923              :                                     "");  /* char8_t is 8 bits */
    9924              :             }
    9925              :           else
    9926           10 :             value = build_string (1, "");
    9927              :           break;
    9928            0 :         case CPP_STRING16:
    9929            0 :           value = build_string (TYPE_PRECISION (char16_type_node)
    9930            0 :                                 / TYPE_PRECISION (char_type_node),
    9931              :                                 "\0");  /* char16_t is 16 bits */
    9932            0 :           break;
    9933            0 :         case CPP_STRING32:
    9934            0 :           value = build_string (TYPE_PRECISION (char32_type_node)
    9935            0 :                                 / TYPE_PRECISION (char_type_node),
    9936              :                                 "\0\0\0");  /* char32_t is 32 bits */
    9937            0 :           break;
    9938            0 :         case CPP_WSTRING:
    9939            0 :           value = build_string (TYPE_PRECISION (wchar_type_node)
    9940            0 :                                 / TYPE_PRECISION (char_type_node),
    9941              :                                 "\0\0\0");  /* widest supported wchar_t
    9942              :                                                is 32 bits */
    9943            0 :           break;
    9944              :         }
    9945              :     }
    9946              : 
    9947      3768990 :   switch (type)
    9948              :     {
    9949      3765680 :     default:
    9950      3765680 :     case CPP_STRING:
    9951      3765680 :       TREE_TYPE (value) = char_array_type_node;
    9952      3765680 :       break;
    9953          264 :     case CPP_UTF8STRING:
    9954          264 :       if (flag_char8_t)
    9955           82 :         TREE_TYPE (value) = char8_array_type_node;
    9956              :       else
    9957          182 :         TREE_TYPE (value) = char_array_type_node;
    9958              :       break;
    9959          229 :     case CPP_STRING16:
    9960          229 :       TREE_TYPE (value) = char16_array_type_node;
    9961          229 :       break;
    9962         2292 :     case CPP_STRING32:
    9963         2292 :       TREE_TYPE (value) = char32_array_type_node;
    9964         2292 :       break;
    9965          525 :     case CPP_WSTRING:
    9966          525 :       TREE_TYPE (value) = wchar_array_type_node;
    9967              :     }
    9968      3768990 :   value = fix_string_type (value);
    9969              : 
    9970      3768990 :   if (count > 1)
    9971              :     {
    9972       880902 :       obstack_free (&str_ob, 0);
    9973       880902 :       obstack_free (&loc_ob, 0);
    9974              :     }
    9975              : 
    9976      3768990 :   ret.value = value;
    9977      3768990 :   ret.original_code = STRING_CST;
    9978      3768990 :   ret.original_type = NULL_TREE;
    9979      3768990 :   set_c_expr_source_range (&ret, get_range_from_loc (line_table, loc));
    9980      3768990 :   ret.m_decimal = 0;
    9981      3768990 :   parser->seen_string_literal = true;
    9982      3768990 :   return ret;
    9983              : }
    9984              : 
    9985              : /* Parse an expression other than a compound expression; that is, an
    9986              :    assignment expression (C90 6.3.16, C99 6.5.16, C11 6.5.16).  If
    9987              :    AFTER is not NULL then it is an Objective-C message expression which
    9988              :    is the primary-expression starting the expression as an initializer.
    9989              : 
    9990              :    assignment-expression:
    9991              :      conditional-expression
    9992              :      unary-expression assignment-operator assignment-expression
    9993              : 
    9994              :    assignment-operator: one of
    9995              :      = *= /= %= += -= <<= >>= &= ^= |=
    9996              : 
    9997              :    In GNU C we accept any conditional expression on the LHS and
    9998              :    diagnose the invalid lvalue rather than producing a syntax
    9999              :    error.  */
   10000              : 
   10001              : static struct c_expr
   10002    227428794 : c_parser_expr_no_commas (c_parser *parser, struct c_expr *after,
   10003              :                          tree omp_atomic_lhs)
   10004              : {
   10005    227428794 :   struct c_expr lhs, rhs, ret;
   10006    227428794 :   enum tree_code code;
   10007    227428794 :   location_t op_location, exp_location;
   10008    227428794 :   bool save_in_omp_for = c_in_omp_for;
   10009    227428794 :   c_in_omp_for = false;
   10010    227428794 :   gcc_assert (!after || c_dialect_objc ());
   10011    227428794 :   lhs = c_parser_conditional_expression (parser, after, omp_atomic_lhs);
   10012    227428792 :   op_location = c_parser_peek_token (parser)->location;
   10013    227428792 :   switch (c_parser_peek_token (parser)->type)
   10014              :     {
   10015              :     case CPP_EQ:
   10016              :       code = NOP_EXPR;
   10017              :       break;
   10018        12298 :     case CPP_MULT_EQ:
   10019        12298 :       code = MULT_EXPR;
   10020        12298 :       break;
   10021         8763 :     case CPP_DIV_EQ:
   10022         8763 :       code = TRUNC_DIV_EXPR;
   10023         8763 :       break;
   10024         2245 :     case CPP_MOD_EQ:
   10025         2245 :       code = TRUNC_MOD_EXPR;
   10026         2245 :       break;
   10027        90402 :     case CPP_PLUS_EQ:
   10028        90402 :       code = PLUS_EXPR;
   10029        90402 :       break;
   10030        29223 :     case CPP_MINUS_EQ:
   10031        29223 :       code = MINUS_EXPR;
   10032        29223 :       break;
   10033         4126 :     case CPP_LSHIFT_EQ:
   10034         4126 :       code = LSHIFT_EXPR;
   10035         4126 :       break;
   10036        16868 :     case CPP_RSHIFT_EQ:
   10037        16868 :       code = RSHIFT_EXPR;
   10038        16868 :       break;
   10039        25372 :     case CPP_AND_EQ:
   10040        25372 :       code = BIT_AND_EXPR;
   10041        25372 :       break;
   10042         3200 :     case CPP_XOR_EQ:
   10043         3200 :       code = BIT_XOR_EXPR;
   10044         3200 :       break;
   10045        21366 :     case CPP_OR_EQ:
   10046        21366 :       code = BIT_IOR_EXPR;
   10047        21366 :       break;
   10048    224549981 :     default:
   10049    224549981 :       c_in_omp_for = save_in_omp_for;
   10050    224549981 :       return lhs;
   10051              :     }
   10052      2878811 :   c_parser_consume_token (parser);
   10053      2878811 :   exp_location = c_parser_peek_token (parser)->location;
   10054      2878811 :   rhs = c_parser_expr_no_commas (parser, NULL);
   10055      2878811 :   rhs = convert_lvalue_to_rvalue (exp_location, rhs, true, true);
   10056              : 
   10057      2878811 :   ret.value = build_modify_expr (op_location, lhs.value, lhs.original_type,
   10058              :                                  code, exp_location, rhs.value,
   10059              :                                  rhs.original_type);
   10060      2878811 :   ret.m_decimal = 0;
   10061      2878811 :   set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
   10062      2878811 :   if (code == NOP_EXPR)
   10063      2664948 :     ret.original_code = MODIFY_EXPR;
   10064              :   else
   10065              :     {
   10066       213863 :       suppress_warning (ret.value, OPT_Wparentheses);
   10067       213863 :       ret.original_code = ERROR_MARK;
   10068              :     }
   10069      2878811 :   ret.original_type = NULL;
   10070      2878811 :   c_in_omp_for = save_in_omp_for;
   10071      2878811 :   return ret;
   10072              : }
   10073              : 
   10074              : /* Parse a conditional expression (C90 6.3.15, C99 6.5.15, C11 6.5.15).  If
   10075              :    AFTER is not NULL then it is an Objective-C message expression which is
   10076              :    the primary-expression starting the expression as an initializer.
   10077              : 
   10078              :    conditional-expression:
   10079              :      logical-OR-expression
   10080              :      logical-OR-expression ? expression : conditional-expression
   10081              : 
   10082              :    GNU extensions:
   10083              : 
   10084              :    conditional-expression:
   10085              :      logical-OR-expression ? : conditional-expression
   10086              : */
   10087              : 
   10088              : static struct c_expr
   10089    227837645 : c_parser_conditional_expression (c_parser *parser, struct c_expr *after,
   10090              :                                  tree omp_atomic_lhs)
   10091              : {
   10092    227837645 :   struct c_expr cond, exp1, exp2, ret;
   10093    227837645 :   location_t start, cond_loc, colon_loc;
   10094    227837645 :   bool save_c_omp_array_section_p = c_omp_array_section_p;
   10095              : 
   10096    227837645 :   gcc_assert (!after || c_dialect_objc ());
   10097              : 
   10098    227837645 :   cond = c_parser_binary_expression (parser, after, omp_atomic_lhs);
   10099              : 
   10100    227837643 :   if (c_parser_next_token_is_not (parser, CPP_QUERY))
   10101    227428983 :     return cond;
   10102       408660 :   c_omp_array_section_p = false;
   10103       408660 :   if (cond.value != error_mark_node)
   10104       408649 :     start = cond.get_start ();
   10105              :   else
   10106              :     start = UNKNOWN_LOCATION;
   10107       408660 :   cond_loc = c_parser_peek_token (parser)->location;
   10108       408660 :   cond = convert_lvalue_to_rvalue (cond_loc, cond, true, true);
   10109       408660 :   c_parser_consume_token (parser);
   10110       408660 :   if (c_parser_next_token_is (parser, CPP_COLON))
   10111              :     {
   10112          770 :       tree eptype = NULL_TREE;
   10113              : 
   10114          770 :       location_t middle_loc = c_parser_peek_token (parser)->location;
   10115          770 :       pedwarn (middle_loc, OPT_Wpedantic,
   10116              :                "ISO C forbids omitting the middle term of a %<?:%> expression");
   10117          770 :       if (TREE_CODE (cond.value) == EXCESS_PRECISION_EXPR)
   10118              :         {
   10119            1 :           eptype = TREE_TYPE (cond.value);
   10120            1 :           cond.value = TREE_OPERAND (cond.value, 0);
   10121              :         }
   10122          770 :       tree e = cond.value;
   10123          773 :       while (TREE_CODE (e) == COMPOUND_EXPR)
   10124            3 :         e = TREE_OPERAND (e, 1);
   10125          770 :       warn_for_omitted_condop (middle_loc, e);
   10126              :       /* Make sure first operand is calculated only once.  */
   10127          770 :       exp1.value = save_expr (default_conversion (cond.value));
   10128          770 :       if (eptype)
   10129            1 :         exp1.value = build1 (EXCESS_PRECISION_EXPR, eptype, exp1.value);
   10130          770 :       exp1.original_type = NULL;
   10131          770 :       exp1.src_range = cond.src_range;
   10132          770 :       cond.value = c_objc_common_truthvalue_conversion (cond_loc, exp1.value);
   10133          770 :       c_inhibit_evaluation_warnings += cond.value == truthvalue_true_node;
   10134              :     }
   10135              :   else
   10136              :     {
   10137       407890 :       cond.value
   10138       407890 :         = c_objc_common_truthvalue_conversion
   10139       407890 :         (cond_loc, default_conversion (cond.value));
   10140       407890 :       c_inhibit_evaluation_warnings += cond.value == truthvalue_false_node;
   10141       407890 :       exp1 = c_parser_expression_conv (parser);
   10142       407890 :       mark_exp_read (exp1.value);
   10143       407890 :       c_inhibit_evaluation_warnings +=
   10144       407890 :         ((cond.value == truthvalue_true_node)
   10145       407890 :          - (cond.value == truthvalue_false_node));
   10146              :     }
   10147              : 
   10148       408660 :   colon_loc = c_parser_peek_token (parser)->location;
   10149       408660 :   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   10150              :     {
   10151            9 :       c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
   10152            9 :       ret.set_error ();
   10153            9 :       ret.original_code = ERROR_MARK;
   10154            9 :       ret.original_type = NULL;
   10155            9 :       c_omp_array_section_p = save_c_omp_array_section_p;
   10156            9 :       return ret;
   10157              :     }
   10158       408651 :   {
   10159       408651 :     location_t exp2_loc = c_parser_peek_token (parser)->location;
   10160       408651 :     exp2 = c_parser_conditional_expression (parser, NULL, NULL_TREE);
   10161       408651 :     exp2 = convert_lvalue_to_rvalue (exp2_loc, exp2, true, true);
   10162              :   }
   10163       408651 :   c_inhibit_evaluation_warnings -= cond.value == truthvalue_true_node;
   10164       408651 :   location_t loc1 = make_location (exp1.get_start (), exp1.src_range);
   10165       408651 :   location_t loc2 = make_location (exp2.get_start (), exp2.src_range);
   10166       408651 :   if (UNLIKELY (omp_atomic_lhs != NULL)
   10167           69 :       && (TREE_CODE (cond.value) == GT_EXPR
   10168              :           || TREE_CODE (cond.value) == LT_EXPR
   10169              :           || TREE_CODE (cond.value) == EQ_EXPR)
   10170           63 :       && c_tree_equal (exp2.value, omp_atomic_lhs)
   10171       408709 :       && (c_tree_equal (TREE_OPERAND (cond.value, 0), omp_atomic_lhs)
   10172           19 :           || c_tree_equal (TREE_OPERAND (cond.value, 1), omp_atomic_lhs)))
   10173           55 :     ret.value = build3_loc (colon_loc, COND_EXPR, TREE_TYPE (omp_atomic_lhs),
   10174              :                             cond.value, exp1.value, exp2.value);
   10175              :   else
   10176       408596 :     ret.value
   10177       408596 :       = build_conditional_expr (colon_loc, cond.value,
   10178       408596 :                                 cond.original_code == C_MAYBE_CONST_EXPR,
   10179              :                                 exp1.value, exp1.original_type, loc1,
   10180              :                                 exp2.value, exp2.original_type, loc2);
   10181       408651 :   ret.original_code = ERROR_MARK;
   10182       408651 :   if (exp1.value == error_mark_node || exp2.value == error_mark_node)
   10183           15 :     ret.original_type = NULL;
   10184              :   else
   10185              :     {
   10186       408636 :       tree t1, t2;
   10187              : 
   10188              :       /* If both sides are enum type, the default conversion will have
   10189              :          made the type of the result be an integer type.  We want to
   10190              :          remember the enum types we started with.  */
   10191       408636 :       t1 = exp1.original_type ? exp1.original_type : TREE_TYPE (exp1.value);
   10192       408636 :       t2 = exp2.original_type ? exp2.original_type : TREE_TYPE (exp2.value);
   10193       408636 :       ret.original_type = ((t1 != error_mark_node
   10194       408636 :                             && t2 != error_mark_node
   10195       408636 :                             && (TYPE_MAIN_VARIANT (t1)
   10196       408636 :                                 == TYPE_MAIN_VARIANT (t2)))
   10197       408636 :                            ? t1
   10198              :                            : NULL);
   10199              :     }
   10200       408651 :   set_c_expr_source_range (&ret, start, exp2.get_finish ());
   10201       408651 :   ret.m_decimal = 0;
   10202       408651 :   c_omp_array_section_p = save_c_omp_array_section_p;
   10203       408651 :   return ret;
   10204              : }
   10205              : 
   10206              : /* Parse a binary expression; that is, a logical-OR-expression (C90
   10207              :    6.3.5-6.3.14, C99 6.5.5-6.5.14, C11 6.5.5-6.5.14).  If AFTER is not
   10208              :    NULL then it is an Objective-C message expression which is the
   10209              :    primary-expression starting the expression as an initializer.
   10210              : 
   10211              :    OMP_ATOMIC_LHS is NULL, unless parsing OpenMP #pragma omp atomic,
   10212              :    when it should be the unfolded lhs.  In a valid OpenMP source,
   10213              :    one of the operands of the toplevel binary expression must be equal
   10214              :    to it.  In that case, just return a build2 created binary operation
   10215              :    rather than result of parser_build_binary_op.
   10216              : 
   10217              :    multiplicative-expression:
   10218              :      cast-expression
   10219              :      multiplicative-expression * cast-expression
   10220              :      multiplicative-expression / cast-expression
   10221              :      multiplicative-expression % cast-expression
   10222              : 
   10223              :    additive-expression:
   10224              :      multiplicative-expression
   10225              :      additive-expression + multiplicative-expression
   10226              :      additive-expression - multiplicative-expression
   10227              : 
   10228              :    shift-expression:
   10229              :      additive-expression
   10230              :      shift-expression << additive-expression
   10231              :      shift-expression >> additive-expression
   10232              : 
   10233              :    relational-expression:
   10234              :      shift-expression
   10235              :      relational-expression < shift-expression
   10236              :      relational-expression > shift-expression
   10237              :      relational-expression <= shift-expression
   10238              :      relational-expression >= shift-expression
   10239              : 
   10240              :    equality-expression:
   10241              :      relational-expression
   10242              :      equality-expression == relational-expression
   10243              :      equality-expression != relational-expression
   10244              : 
   10245              :    AND-expression:
   10246              :      equality-expression
   10247              :      AND-expression & equality-expression
   10248              : 
   10249              :    exclusive-OR-expression:
   10250              :      AND-expression
   10251              :      exclusive-OR-expression ^ AND-expression
   10252              : 
   10253              :    inclusive-OR-expression:
   10254              :      exclusive-OR-expression
   10255              :      inclusive-OR-expression | exclusive-OR-expression
   10256              : 
   10257              :    logical-AND-expression:
   10258              :      inclusive-OR-expression
   10259              :      logical-AND-expression && inclusive-OR-expression
   10260              : 
   10261              :    logical-OR-expression:
   10262              :      logical-AND-expression
   10263              :      logical-OR-expression || logical-AND-expression
   10264              : */
   10265              : 
   10266              : static struct c_expr
   10267    227854110 : c_parser_binary_expression (c_parser *parser, struct c_expr *after,
   10268              :                             tree omp_atomic_lhs)
   10269              : {
   10270              :   /* A binary expression is parsed using operator-precedence parsing,
   10271              :      with the operands being cast expressions.  All the binary
   10272              :      operators are left-associative.  Thus a binary expression is of
   10273              :      form:
   10274              : 
   10275              :      E0 op1 E1 op2 E2 ...
   10276              : 
   10277              :      which we represent on a stack.  On the stack, the precedence
   10278              :      levels are strictly increasing.  When a new operator is
   10279              :      encountered of higher precedence than that at the top of the
   10280              :      stack, it is pushed; its LHS is the top expression, and its RHS
   10281              :      is everything parsed until it is popped.  When a new operator is
   10282              :      encountered with precedence less than or equal to that at the top
   10283              :      of the stack, triples E[i-1] op[i] E[i] are popped and replaced
   10284              :      by the result of the operation until the operator at the top of
   10285              :      the stack has lower precedence than the new operator or there is
   10286              :      only one element on the stack; then the top expression is the LHS
   10287              :      of the new operator.  In the case of logical AND and OR
   10288              :      expressions, we also need to adjust c_inhibit_evaluation_warnings
   10289              :      as appropriate when the operators are pushed and popped.  */
   10290              : 
   10291    227854110 :   struct {
   10292              :     /* The expression at this stack level.  */
   10293              :     struct c_expr expr;
   10294              :     /* The precedence of the operator on its left, PREC_NONE at the
   10295              :        bottom of the stack.  */
   10296              :     enum c_parser_prec prec;
   10297              :     /* The operation on its left.  */
   10298              :     enum tree_code op;
   10299              :     /* The source location of this operation.  */
   10300              :     location_t loc;
   10301              :     /* The sizeof argument if expr.original_code == {PAREN_,}SIZEOF_EXPR.  */
   10302              :     tree sizeof_arg;
   10303              :   } stack[NUM_PRECS];
   10304    227854110 :   int sp;
   10305              :   /* Location of the binary operator.  */
   10306    227854110 :   location_t binary_loc = UNKNOWN_LOCATION;  /* Quiet warning.  */
   10307              : #define POP                                                                   \
   10308              :   do {                                                                        \
   10309              :     switch (stack[sp].op)                                                     \
   10310              :       {                                                                       \
   10311              :       case TRUTH_ANDIF_EXPR:                                                  \
   10312              :         c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value            \
   10313              :                                           == truthvalue_false_node);          \
   10314              :         break;                                                                \
   10315              :       case TRUTH_ORIF_EXPR:                                                   \
   10316              :         c_inhibit_evaluation_warnings -= (stack[sp - 1].expr.value            \
   10317              :                                           == truthvalue_true_node);           \
   10318              :         break;                                                                \
   10319              :       case TRUNC_DIV_EXPR:                                                    \
   10320              :         if ((stack[sp - 1].expr.original_code == SIZEOF_EXPR                  \
   10321              :              || stack[sp - 1].expr.original_code == PAREN_SIZEOF_EXPR)        \
   10322              :             && (stack[sp].expr.original_code == SIZEOF_EXPR                   \
   10323              :                 || stack[sp].expr.original_code == PAREN_SIZEOF_EXPR))        \
   10324              :           {                                                                   \
   10325              :             tree type0 = stack[sp - 1].sizeof_arg;                            \
   10326              :             tree type1 = stack[sp].sizeof_arg;                                \
   10327              :             tree first_arg = type0;                                           \
   10328              :             if (!TYPE_P (type0))                                              \
   10329              :               type0 = TREE_TYPE (type0);                                      \
   10330              :             if (!TYPE_P (type1))                                              \
   10331              :               type1 = TREE_TYPE (type1);                                      \
   10332              :             if (POINTER_TYPE_P (type0)                                        \
   10333              :                 && comptypes (TREE_TYPE (type0), type1)                       \
   10334              :                 && !(TREE_CODE (first_arg) == PARM_DECL                       \
   10335              :                      && C_ARRAY_PARAMETER (first_arg)                         \
   10336              :                      && warn_sizeof_array_argument))                          \
   10337              :               {                                                               \
   10338              :                 auto_diagnostic_group d;                                      \
   10339              :                 if (warning_at (stack[sp].loc, OPT_Wsizeof_pointer_div,       \
   10340              :                                   "division %<sizeof (%T) / sizeof (%T)%> "   \
   10341              :                                   "does not compute the number of array "     \
   10342              :                                   "elements",                               \
   10343              :                                   type0, type1))                              \
   10344              :                   if (DECL_P (first_arg))                                     \
   10345              :                     inform (DECL_SOURCE_LOCATION (first_arg),                 \
   10346              :                               "first %<sizeof%> operand was declared here");  \
   10347              :               }                                                               \
   10348              :             else if (TREE_CODE (type0) == ARRAY_TYPE                          \
   10349              :                      && !char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type0)))  \
   10350              :                      && stack[sp].expr.original_code != PAREN_SIZEOF_EXPR)    \
   10351              :               maybe_warn_sizeof_array_div (stack[sp].loc, first_arg, type0,   \
   10352              :                                            stack[sp].sizeof_arg, type1);      \
   10353              :           }                                                                   \
   10354              :         break;                                                                \
   10355              :       default:                                                                \
   10356              :         break;                                                                \
   10357              :       }                                                                       \
   10358              :     stack[sp - 1].expr                                                        \
   10359              :       = convert_lvalue_to_rvalue (stack[sp - 1].loc,                          \
   10360              :                                   stack[sp - 1].expr, true, true);            \
   10361              :     stack[sp].expr                                                            \
   10362              :       = convert_lvalue_to_rvalue (stack[sp].loc,                              \
   10363              :                                   stack[sp].expr, true, true);                \
   10364              :     if (UNLIKELY (omp_atomic_lhs != NULL_TREE) && sp == 1                     \
   10365              :         && ((c_parser_next_token_is (parser, CPP_SEMICOLON)                   \
   10366              :              && ((1 << stack[sp].prec)                                          \
   10367              :                  & ((1 << PREC_BITOR) | (1 << PREC_BITXOR)                    \
   10368              :                      | (1 << PREC_BITAND) | (1 << PREC_SHIFT)                     \
   10369              :                      | (1 << PREC_ADD) | (1 << PREC_MULT)                 \
   10370              :                      | (1 << PREC_EQ))))                                \
   10371              :             || ((c_parser_next_token_is (parser, CPP_QUERY)                   \
   10372              :                  || (omp_atomic_lhs == void_list_node                         \
   10373              :                      && c_parser_next_token_is (parser, CPP_CLOSE_PAREN)))    \
   10374              :                 && (stack[sp].prec == PREC_REL || stack[sp].prec == PREC_EQ)))\
   10375              :         && stack[sp].op != TRUNC_MOD_EXPR                                     \
   10376              :         && stack[sp].op != GE_EXPR                                            \
   10377              :         && stack[sp].op != LE_EXPR                                            \
   10378              :         && stack[sp].op != NE_EXPR                                            \
   10379              :         && stack[0].expr.value != error_mark_node                             \
   10380              :         && stack[1].expr.value != error_mark_node                             \
   10381              :         && (omp_atomic_lhs == void_list_node                                  \
   10382              :             || c_tree_equal (stack[0].expr.value, omp_atomic_lhs)             \
   10383              :             || c_tree_equal (stack[1].expr.value, omp_atomic_lhs)             \
   10384              :             || (stack[sp].op == EQ_EXPR                                       \
   10385              :                 && c_parser_peek_2nd_token (parser)->keyword == RID_IF)))     \
   10386              :       {                                                                       \
   10387              :         tree t = make_node (stack[1].op);                                     \
   10388              :         TREE_TYPE (t) = TREE_TYPE (stack[0].expr.value);                      \
   10389              :         TREE_OPERAND (t, 0) = stack[0].expr.value;                            \
   10390              :         TREE_OPERAND (t, 1) = stack[1].expr.value;                            \
   10391              :         stack[0].expr.value = t;                                              \
   10392              :         stack[0].expr.m_decimal = 0;                                          \
   10393              :       }                                                                       \
   10394              :     else                                                                      \
   10395              :       stack[sp - 1].expr = parser_build_binary_op (stack[sp].loc,             \
   10396              :                                                    stack[sp].op,              \
   10397              :                                                    stack[sp - 1].expr,        \
   10398              :                                                    stack[sp].expr);           \
   10399              :     sp--;                                                                     \
   10400              :   } while (0)
   10401    227854110 :   gcc_assert (!after || c_dialect_objc ());
   10402    227854110 :   stack[0].loc = c_parser_peek_token (parser)->location;
   10403    227854110 :   stack[0].expr = c_parser_cast_expression (parser, after);
   10404    227854110 :   stack[0].prec = PREC_NONE;
   10405    227854110 :   stack[0].sizeof_arg = c_last_sizeof_arg;
   10406    227854110 :   sp = 0;
   10407    246480852 :   while (true)
   10408              :     {
   10409    237167481 :       enum c_parser_prec oprec;
   10410    237167481 :       enum tree_code ocode;
   10411    237167481 :       source_range src_range;
   10412    237167481 :       if (parser->error)
   10413         1076 :         goto out;
   10414    237166405 :       switch (c_parser_peek_token (parser)->type)
   10415              :         {
   10416              :         case CPP_MULT:
   10417              :           oprec = PREC_MULT;
   10418              :           ocode = MULT_EXPR;
   10419              :           break;
   10420       264593 :         case CPP_DIV:
   10421       264593 :           oprec = PREC_MULT;
   10422       264593 :           ocode = TRUNC_DIV_EXPR;
   10423       264593 :           break;
   10424        56185 :         case CPP_MOD:
   10425        56185 :           oprec = PREC_MULT;
   10426        56185 :           ocode = TRUNC_MOD_EXPR;
   10427        56185 :           break;
   10428      1827535 :         case CPP_PLUS:
   10429      1827535 :           oprec = PREC_ADD;
   10430      1827535 :           ocode = PLUS_EXPR;
   10431      1827535 :           break;
   10432       749100 :         case CPP_MINUS:
   10433       749100 :           oprec = PREC_ADD;
   10434       749100 :           ocode = MINUS_EXPR;
   10435       749100 :           break;
   10436       798151 :         case CPP_LSHIFT:
   10437       798151 :           oprec = PREC_SHIFT;
   10438       798151 :           ocode = LSHIFT_EXPR;
   10439       798151 :           break;
   10440       214042 :         case CPP_RSHIFT:
   10441       214042 :           oprec = PREC_SHIFT;
   10442       214042 :           ocode = RSHIFT_EXPR;
   10443       214042 :           break;
   10444       470245 :         case CPP_LESS:
   10445       470245 :           oprec = PREC_REL;
   10446       470245 :           ocode = LT_EXPR;
   10447       470245 :           break;
   10448       195238 :         case CPP_GREATER:
   10449       195238 :           oprec = PREC_REL;
   10450       195238 :           ocode = GT_EXPR;
   10451       195238 :           break;
   10452       163153 :         case CPP_LESS_EQ:
   10453       163153 :           oprec = PREC_REL;
   10454       163153 :           ocode = LE_EXPR;
   10455       163153 :           break;
   10456       167400 :         case CPP_GREATER_EQ:
   10457       167400 :           oprec = PREC_REL;
   10458       167400 :           ocode = GE_EXPR;
   10459       167400 :           break;
   10460       394776 :         case CPP_EQ_EQ:
   10461       394776 :           oprec = PREC_EQ;
   10462       394776 :           ocode = EQ_EXPR;
   10463       394776 :           break;
   10464       770457 :         case CPP_NOT_EQ:
   10465       770457 :           oprec = PREC_EQ;
   10466       770457 :           ocode = NE_EXPR;
   10467       770457 :           break;
   10468       593280 :         case CPP_AND:
   10469       593280 :           oprec = PREC_BITAND;
   10470       593280 :           ocode = BIT_AND_EXPR;
   10471       593280 :           break;
   10472        76969 :         case CPP_XOR:
   10473        76969 :           oprec = PREC_BITXOR;
   10474        76969 :           ocode = BIT_XOR_EXPR;
   10475        76969 :           break;
   10476       864393 :         case CPP_OR:
   10477       864393 :           oprec = PREC_BITOR;
   10478       864393 :           ocode = BIT_IOR_EXPR;
   10479       864393 :           break;
   10480       184789 :         case CPP_AND_AND:
   10481       184789 :           oprec = PREC_LOGAND;
   10482       184789 :           ocode = TRUTH_ANDIF_EXPR;
   10483       184789 :           break;
   10484       323422 :         case CPP_OR_OR:
   10485       323422 :           oprec = PREC_LOGOR;
   10486       323422 :           ocode = TRUTH_ORIF_EXPR;
   10487       323422 :           break;
   10488    227853034 :         default:
   10489              :           /* Not a binary operator, so end of the binary
   10490              :              expression.  */
   10491    227853034 :           goto out;
   10492              :         }
   10493      9313371 :       binary_loc = c_parser_peek_token (parser)->location;
   10494      9313371 :       while (oprec <= stack[sp].prec)
   10495     10756537 :         POP;
   10496      9313371 :       c_parser_consume_token (parser);
   10497      9313371 :       switch (ocode)
   10498              :         {
   10499       184789 :         case TRUTH_ANDIF_EXPR:
   10500       184789 :           src_range = stack[sp].expr.src_range;
   10501       184789 :           stack[sp].expr
   10502       184789 :             = convert_lvalue_to_rvalue (stack[sp].loc,
   10503              :                                         stack[sp].expr, true, true);
   10504       369578 :           stack[sp].expr.value = c_objc_common_truthvalue_conversion
   10505       184789 :             (stack[sp].loc, default_conversion (stack[sp].expr.value));
   10506       184789 :           c_inhibit_evaluation_warnings += (stack[sp].expr.value
   10507       184789 :                                             == truthvalue_false_node);
   10508       184789 :           set_c_expr_source_range (&stack[sp].expr, src_range);
   10509       184789 :           break;
   10510       323422 :         case TRUTH_ORIF_EXPR:
   10511       323422 :           src_range = stack[sp].expr.src_range;
   10512       323422 :           stack[sp].expr
   10513       323422 :             = convert_lvalue_to_rvalue (stack[sp].loc,
   10514              :                                         stack[sp].expr, true, true);
   10515       646844 :           stack[sp].expr.value = c_objc_common_truthvalue_conversion
   10516       323422 :             (stack[sp].loc, default_conversion (stack[sp].expr.value));
   10517       323422 :           c_inhibit_evaluation_warnings += (stack[sp].expr.value
   10518       323422 :                                             == truthvalue_true_node);
   10519       323422 :           set_c_expr_source_range (&stack[sp].expr, src_range);
   10520       323422 :           break;
   10521              :         default:
   10522              :           break;
   10523              :         }
   10524      9313371 :       sp++;
   10525      9313371 :       stack[sp].loc = binary_loc;
   10526      9313371 :       stack[sp].expr = c_parser_cast_expression (parser, NULL);
   10527      9313371 :       stack[sp].prec = oprec;
   10528      9313371 :       stack[sp].op = ocode;
   10529      9313371 :       stack[sp].sizeof_arg = c_last_sizeof_arg;
   10530      9313371 :     }
   10531    227854110 :  out:
   10532    227854110 :   while (sp > 0)
   10533    235725036 :     POP;
   10534    227854108 :   return stack[0].expr;
   10535              : #undef POP
   10536              : }
   10537              : 
   10538              : /* Parse any storage class specifiers after an open parenthesis in a
   10539              :    context where a compound literal is permitted.  */
   10540              : 
   10541              : static struct c_declspecs *
   10542    121284805 : c_parser_compound_literal_scspecs (c_parser *parser)
   10543              : {
   10544    121284805 :   bool seen_scspec = false;
   10545    121284805 :   struct c_declspecs *specs = build_null_declspecs ();
   10546    242569953 :   while (c_parser_next_token_is (parser, CPP_KEYWORD))
   10547              :     {
   10548      4195448 :       switch (c_parser_peek_token (parser)->keyword)
   10549              :         {
   10550          343 :         case RID_CONSTEXPR:
   10551          343 :         case RID_REGISTER:
   10552          343 :         case RID_STATIC:
   10553          343 :         case RID_THREAD:
   10554          343 :           seen_scspec = true;
   10555          343 :           declspecs_add_scspec (c_parser_peek_token (parser)->location,
   10556          343 :                                 specs, c_parser_peek_token (parser)->value);
   10557          343 :           c_parser_consume_token (parser);
   10558          343 :           break;
   10559      4195105 :         default:
   10560      4195105 :           goto out;
   10561              :         }
   10562              :     }
   10563    117089700 :  out:
   10564    121284805 :   return seen_scspec ? specs : NULL;
   10565              : }
   10566              : 
   10567              : /* Parse a cast expression (C90 6.3.4, C99 6.5.4, C11 6.5.4).  If AFTER
   10568              :    is not NULL then it is an Objective-C message expression which is the
   10569              :    primary-expression starting the expression as an initializer.
   10570              : 
   10571              :    cast-expression:
   10572              :      unary-expression
   10573              :      ( type-name ) unary-expression
   10574              : */
   10575              : 
   10576              : static struct c_expr
   10577    366990256 : c_parser_cast_expression (c_parser *parser, struct c_expr *after)
   10578              : {
   10579    366990256 :   location_t cast_loc = c_parser_peek_token (parser)->location;
   10580    366990256 :   gcc_assert (!after || c_dialect_objc ());
   10581            0 :   if (after)
   10582            0 :     return c_parser_postfix_expression_after_primary (parser,
   10583            0 :                                                       cast_loc, *after);
   10584              :   /* If the expression begins with a parenthesized type name, it may
   10585              :      be either a cast or a compound literal; we need to see whether
   10586              :      the next character is '{' to tell the difference.  If not, it is
   10587              :      an unary expression.  Full detection of unknown typenames here
   10588              :      would require a 3-token lookahead.  */
   10589    366990256 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
   10590    366990256 :       && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
   10591              :     {
   10592    120921860 :       struct c_declspecs *scspecs;
   10593    120921860 :       struct c_type_name *type_name;
   10594    120921860 :       struct c_expr ret;
   10595    120921860 :       struct c_expr expr;
   10596    120921860 :       matching_parens parens;
   10597    120921860 :       parens.consume_open (parser);
   10598    120921860 :       scspecs = c_parser_compound_literal_scspecs (parser);
   10599    120921860 :       type_name = c_parser_type_name (parser, true);
   10600    120921860 :       parens.skip_until_found_close (parser);
   10601    120921860 :       if (type_name == NULL)
   10602              :         {
   10603            1 :           ret.set_error ();
   10604            1 :           ret.original_code = ERROR_MARK;
   10605            1 :           ret.original_type = NULL;
   10606            1 :           return ret;
   10607              :         }
   10608              : 
   10609              :       /* Save casted types in the function's used types hash table.  */
   10610    120921859 :       used_types_insert (type_name->specs->type);
   10611              : 
   10612    120921859 :       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   10613       917693 :         return c_parser_postfix_expression_after_paren_type (parser, scspecs,
   10614              :                                                              type_name,
   10615       917693 :                                                              cast_loc);
   10616    120004166 :       if (scspecs)
   10617            1 :         error_at (cast_loc, "storage class specifier in cast");
   10618    120004166 :       if (type_name->specs->alignas_p)
   10619            1 :         error_at (type_name->specs->locations[cdw_alignas],
   10620              :                   "alignment specified for type name in cast");
   10621    120004166 :       {
   10622    120004166 :         location_t expr_loc = c_parser_peek_token (parser)->location;
   10623    120004166 :         expr = c_parser_cast_expression (parser, NULL);
   10624    120004166 :         expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
   10625              :       }
   10626    120004166 :       ret.value = c_cast_expr (cast_loc, type_name, expr.value);
   10627    120004166 :       if (ret.value && expr.value)
   10628    120004166 :         set_c_expr_source_range (&ret, cast_loc, expr.get_finish ());
   10629    120004166 :       ret.original_code = ERROR_MARK;
   10630    120004166 :       ret.original_type = NULL;
   10631    120004166 :       ret.m_decimal = 0;
   10632    120004166 :       return ret;
   10633              :     }
   10634              :   else
   10635    246068396 :     return c_parser_unary_expression (parser);
   10636              : }
   10637              : 
   10638              : /* Parse an unary expression (C90 6.3.3, C99 6.5.3, C11 6.5.3).
   10639              : 
   10640              :    unary-expression:
   10641              :      postfix-expression
   10642              :      ++ unary-expression
   10643              :      -- unary-expression
   10644              :      unary-operator cast-expression
   10645              :      _Countof unary-expression
   10646              :      _Countof ( type-name )
   10647              :      sizeof unary-expression
   10648              :      sizeof ( type-name )
   10649              :      static-assert-declaration-no-semi
   10650              : 
   10651              :    (_Countof and the use of static assertions in expressions are new in C2y.)
   10652              : 
   10653              :    unary-operator: one of
   10654              :      & * + - ~ !
   10655              : 
   10656              :    GNU extensions:
   10657              : 
   10658              :    unary-expression:
   10659              :      __alignof__ unary-expression
   10660              :      __alignof__ ( type-name )
   10661              :      _Maxof ( type-name )
   10662              :      _Minof ( type-name )
   10663              :      && identifier
   10664              : 
   10665              :    (C11 permits _Alignof with type names only.)
   10666              : 
   10667              :    unary-operator: one of
   10668              :      __extension__ __real__ __imag__
   10669              : 
   10670              :    Transactional Memory:
   10671              : 
   10672              :    unary-expression:
   10673              :      transaction-expression
   10674              : 
   10675              :    In addition, the GNU syntax treats ++ and -- as unary operators, so
   10676              :    they may be applied to cast expressions with errors for non-lvalues
   10677              :    given later.  */
   10678              : 
   10679              : static struct c_expr
   10680    246421985 : c_parser_unary_expression (c_parser *parser)
   10681              : {
   10682    246421985 :   int ext;
   10683    246421985 :   struct c_expr ret, op;
   10684    246421985 :   location_t op_loc = c_parser_peek_token (parser)->location;
   10685    246421985 :   location_t exp_loc;
   10686    246421985 :   location_t finish;
   10687    246421985 :   ret.original_code = ERROR_MARK;
   10688    246421985 :   ret.original_type = NULL;
   10689    246421985 :   switch (c_parser_peek_token (parser)->type)
   10690              :     {
   10691       220509 :     case CPP_PLUS_PLUS:
   10692       220509 :       c_parser_consume_token (parser);
   10693       220509 :       exp_loc = c_parser_peek_token (parser)->location;
   10694       220509 :       op = c_parser_cast_expression (parser, NULL);
   10695         4095 :       if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL)
   10696       217548 :           && !DECL_READ_P (op.value)
   10697       226741 :           && (VAR_P (op.value) ? warn_unused_but_set_variable
   10698              :                                : warn_unused_but_set_parameter) > 1)
   10699              :         {
   10700          399 :           op = default_function_array_read_conversion (exp_loc, op);
   10701          399 :           DECL_READ_P (op.value) = 0;
   10702              :         }
   10703              :       else
   10704       220110 :         op = default_function_array_read_conversion (exp_loc, op);
   10705       220509 :       return parser_build_unary_op (op_loc, PREINCREMENT_EXPR, op);
   10706        20024 :     case CPP_MINUS_MINUS:
   10707        20024 :       c_parser_consume_token (parser);
   10708        20024 :       exp_loc = c_parser_peek_token (parser)->location;
   10709        20024 :       op = c_parser_cast_expression (parser, NULL);
   10710        14785 :       if ((VAR_P (op.value) || TREE_CODE (op.value) == PARM_DECL)
   10711        19387 :           && !DECL_READ_P (op.value)
   10712        21982 :           && (VAR_P (op.value) ? warn_unused_but_set_variable
   10713              :                                : warn_unused_but_set_parameter) > 1)
   10714              :         {
   10715          202 :           op = default_function_array_read_conversion (exp_loc, op);
   10716          202 :           DECL_READ_P (op.value) = 0;
   10717              :         }
   10718              :       else
   10719        19822 :         op = default_function_array_read_conversion (exp_loc, op);
   10720        20024 :       return parser_build_unary_op (op_loc, PREDECREMENT_EXPR, op);
   10721       445213 :     case CPP_AND:
   10722       445213 :       c_parser_consume_token (parser);
   10723       445213 :       op = c_parser_cast_expression (parser, NULL);
   10724       445213 :       mark_exp_read (op.value);
   10725       445213 :       return parser_build_unary_op (op_loc, ADDR_EXPR, op);
   10726      1209706 :     case CPP_MULT:
   10727      1209706 :       {
   10728      1209706 :         c_parser_consume_token (parser);
   10729      1209706 :         exp_loc = c_parser_peek_token (parser)->location;
   10730      1209706 :         op = c_parser_cast_expression (parser, NULL);
   10731      1209706 :         finish = op.get_finish ();
   10732      1209706 :         op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
   10733      1209706 :         location_t combined_loc = make_location (op_loc, op_loc, finish);
   10734      1209706 :         ret.value = build_indirect_ref (combined_loc, op.value, RO_UNARY_STAR);
   10735      1209706 :         ret.src_range.m_start = op_loc;
   10736      1209706 :         ret.src_range.m_finish = finish;
   10737      1209706 :         ret.m_decimal = 0;
   10738      1209706 :         return ret;
   10739              :       }
   10740        28760 :     case CPP_PLUS:
   10741        28760 :       if (!c_dialect_objc () && !in_system_header_at (input_location))
   10742        28758 :         warning_at (op_loc,
   10743        28758 :                     OPT_Wtraditional,
   10744              :                     "traditional C rejects the unary plus operator");
   10745        28760 :       c_parser_consume_token (parser);
   10746        28760 :       exp_loc = c_parser_peek_token (parser)->location;
   10747        28760 :       op = c_parser_cast_expression (parser, NULL);
   10748        28760 :       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
   10749        28760 :       return parser_build_unary_op (op_loc, CONVERT_EXPR, op);
   10750      6683547 :     case CPP_MINUS:
   10751      6683547 :       c_parser_consume_token (parser);
   10752      6683547 :       exp_loc = c_parser_peek_token (parser)->location;
   10753      6683547 :       op = c_parser_cast_expression (parser, NULL);
   10754      6683547 :       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
   10755      6683547 :       return parser_build_unary_op (op_loc, NEGATE_EXPR, op);
   10756       294688 :     case CPP_COMPL:
   10757       294688 :       c_parser_consume_token (parser);
   10758       294688 :       exp_loc = c_parser_peek_token (parser)->location;
   10759       294688 :       op = c_parser_cast_expression (parser, NULL);
   10760       294688 :       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
   10761       294688 :       return parser_build_unary_op (op_loc, BIT_NOT_EXPR, op);
   10762       375766 :     case CPP_NOT:
   10763       375766 :       c_parser_consume_token (parser);
   10764       375766 :       exp_loc = c_parser_peek_token (parser)->location;
   10765       375766 :       op = c_parser_cast_expression (parser, NULL);
   10766       375766 :       op = convert_lvalue_to_rvalue (exp_loc, op, true, true);
   10767       375766 :       return parser_build_unary_op (op_loc, TRUTH_NOT_EXPR, op);
   10768         1839 :     case CPP_AND_AND:
   10769              :       /* Refer to the address of a label as a pointer.  */
   10770         1839 :       c_parser_consume_token (parser);
   10771         1839 :       if (c_parser_next_token_is (parser, CPP_NAME))
   10772              :         {
   10773         3664 :           ret.value = finish_label_address_expr
   10774         1832 :             (c_parser_peek_token (parser)->value, op_loc);
   10775         1832 :           set_c_expr_source_range (&ret, op_loc,
   10776              :                                    c_parser_peek_token (parser)->get_finish ());
   10777         1832 :           c_parser_consume_token (parser);
   10778              :         }
   10779              :       else
   10780              :         {
   10781            7 :           c_parser_error (parser, "expected identifier");
   10782            7 :           ret.set_error ();
   10783              :         }
   10784         1839 :       return ret;
   10785      2891083 :     case CPP_KEYWORD:
   10786      2891083 :       {
   10787      2891083 :         enum rid rid = c_parser_peek_token (parser)->keyword;
   10788      2891083 :         switch (rid)
   10789              :           {
   10790       643848 :           case RID_COUNTOF:
   10791       643848 :           case RID_SIZEOF:
   10792       643848 :             return c_parser_sizeof_or_countof_expression (parser, rid);
   10793        72686 :           case RID_ALIGNOF:
   10794        72686 :             return c_parser_alignof_expression (parser);
   10795          102 :           case RID_MAXOF:
   10796          102 :           case RID_MINOF:
   10797          102 :             return c_parser_maxof_or_minof_expression (parser, rid);
   10798          764 :           case RID_BUILTIN_HAS_ATTRIBUTE:
   10799          764 :             return c_parser_has_attribute_expression (parser);
   10800       461093 :           case RID_EXTENSION:
   10801       461093 :             c_parser_consume_token (parser);
   10802       461093 :             ext = disable_extension_diagnostics ();
   10803       461093 :             ret = c_parser_cast_expression (parser, NULL);
   10804       461093 :             restore_extension_diagnostics (ext);
   10805       461093 :             return ret;
   10806        38400 :           case RID_REALPART:
   10807        38400 :             c_parser_consume_token (parser);
   10808        38400 :             exp_loc = c_parser_peek_token (parser)->location;
   10809        38400 :             op = c_parser_cast_expression (parser, NULL);
   10810        38400 :             op = default_function_array_conversion (exp_loc, op);
   10811        38400 :             return parser_build_unary_op (op_loc, REALPART_EXPR, op);
   10812        38322 :           case RID_IMAGPART:
   10813        38322 :             c_parser_consume_token (parser);
   10814        38322 :             exp_loc = c_parser_peek_token (parser)->location;
   10815        38322 :             op = c_parser_cast_expression (parser, NULL);
   10816        38322 :             op = default_function_array_conversion (exp_loc, op);
   10817        38322 :             return parser_build_unary_op (op_loc, IMAGPART_EXPR, op);
   10818            7 :           case RID_TRANSACTION_ATOMIC:
   10819            7 :           case RID_TRANSACTION_RELAXED:
   10820            7 :             return c_parser_transaction_expression (parser, rid);
   10821          168 :           case RID_STATIC_ASSERT:
   10822          168 :             c_parser_static_assert_declaration_no_semi (parser);
   10823          168 :             pedwarn_c23 (op_loc, OPT_Wpedantic,
   10824              :                          "ISO C does not support static assertions in "
   10825              :                          "expressions before C2Y");
   10826          168 :             ret.value = void_node;
   10827          168 :             set_c_expr_source_range (&ret, op_loc, op_loc);
   10828          168 :             ret.m_decimal = 0;
   10829          168 :             return ret;
   10830      1635693 :           default:
   10831      1635693 :             return c_parser_postfix_expression (parser);
   10832              :           }
   10833              :       }
   10834    234250850 :     default:
   10835    234250850 :       return c_parser_postfix_expression (parser);
   10836              :     }
   10837              : }
   10838              : 
   10839              : /* Parse a sizeof or _Countof expression.  */
   10840              : 
   10841              : static struct c_expr
   10842       643848 : c_parser_sizeof_or_countof_expression (c_parser *parser, enum rid rid)
   10843              : {
   10844       643848 :   const char *op_name = (rid == RID_COUNTOF) ? "_Countof" : "sizeof";
   10845       643848 :   struct c_expr expr;
   10846       643848 :   struct c_expr result;
   10847       643848 :   location_t expr_loc;
   10848       643848 :   gcc_assert (c_parser_next_token_is_keyword (parser, rid));
   10849              : 
   10850       643848 :   location_t start;
   10851       643848 :   location_t finish = UNKNOWN_LOCATION;
   10852              : 
   10853       643848 :   start = c_parser_peek_token (parser)->location;
   10854              : 
   10855       643848 :   if (rid == RID_COUNTOF)
   10856           72 :     pedwarn_c23 (start, OPT_Wpedantic,
   10857              :                  "ISO C does not support %qs before C2Y", op_name);
   10858              : 
   10859       643848 :   c_parser_consume_token (parser);
   10860       643848 :   c_inhibit_evaluation_warnings++;
   10861       643848 :   if (rid == RID_COUNTOF)
   10862           72 :     in_countof++;
   10863              :   else
   10864       643776 :     in_sizeof++;
   10865       643848 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
   10866       643848 :       && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
   10867              :     {
   10868              :       /* Either sizeof ( type-name ) or sizeof unary-expression
   10869              :          starting with a compound literal.  */
   10870       331058 :       struct c_declspecs *scspecs;
   10871       331058 :       struct c_type_name *type_name;
   10872       331058 :       matching_parens parens;
   10873       331058 :       parens.consume_open (parser);
   10874       331058 :       expr_loc = c_parser_peek_token (parser)->location;
   10875       331058 :       scspecs = c_parser_compound_literal_scspecs (parser);
   10876       331058 :       type_name = c_parser_type_name (parser, true);
   10877       331058 :       parens.skip_until_found_close (parser);
   10878       331058 :       finish = parser->tokens_buf[0].location;
   10879       331058 :       if (type_name == NULL)
   10880              :         {
   10881              :           /* Let c_expr_sizeof_expr call pop_maybe_used and fill in c_expr
   10882              :              for parsing error; the parsing of the expression could have
   10883              :              called record_maybe_used_decl.  */
   10884            1 :           expr.set_error ();
   10885           27 :           goto Xof_expr;
   10886              :         }
   10887       331057 :       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   10888              :         {
   10889           26 :           expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
   10890              :                                                                type_name,
   10891              :                                                                expr_loc);
   10892           26 :           finish = expr.get_finish ();
   10893           26 :           goto Xof_expr;
   10894              :         }
   10895              :       /* sizeof ( type-name ).  */
   10896       331031 :       if (scspecs)
   10897            1 :         error_at (expr_loc, "storage class specifier in %qs", op_name);
   10898       331031 :       if (type_name->specs->alignas_p)
   10899            2 :         error_at (type_name->specs->locations[cdw_alignas],
   10900              :                   "alignment specified for type name in %qs", op_name);
   10901       331031 :       c_inhibit_evaluation_warnings--;
   10902       331031 :       if (rid == RID_COUNTOF)
   10903              :         {
   10904           18 :           in_countof--;
   10905           18 :           result = c_expr_countof_type (expr_loc, type_name);
   10906              :         }
   10907              :       else
   10908              :         {
   10909       331013 :           in_sizeof--;
   10910       331013 :           result = c_expr_sizeof_type (expr_loc, type_name);
   10911              :         }
   10912              :     }
   10913              :   else
   10914              :     {
   10915       312790 :       expr_loc = c_parser_peek_token (parser)->location;
   10916       312790 :       expr = c_parser_unary_expression (parser);
   10917       312790 :       finish = expr.get_finish ();
   10918       312817 :     Xof_expr:
   10919       312817 :       c_inhibit_evaluation_warnings--;
   10920       312817 :       if (rid == RID_COUNTOF)
   10921           54 :         in_countof--;
   10922              :       else
   10923       312763 :         in_sizeof--;
   10924       312817 :       mark_exp_read (expr.value);
   10925       312817 :       if (TREE_CODE (expr.value) == COMPONENT_REF
   10926       312817 :           && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
   10927            1 :         error_at (expr_loc, "%qs applied to a bit-field", op_name);
   10928       312817 :       if (rid == RID_COUNTOF)
   10929           54 :         result = c_expr_countof_expr (expr_loc, expr);
   10930              :       else
   10931       312763 :         result = c_expr_sizeof_expr (expr_loc, expr);
   10932              :     }
   10933       643848 :   if (finish == UNKNOWN_LOCATION)
   10934            1 :     finish = start;
   10935       643848 :   set_c_expr_source_range (&result, start, finish);
   10936       643848 :   return result;
   10937              : }
   10938              : 
   10939              : /* Parse an alignof expression.  */
   10940              : 
   10941              : static struct c_expr
   10942        72686 : c_parser_alignof_expression (c_parser *parser)
   10943              : {
   10944        72686 :   struct c_expr expr;
   10945        72686 :   location_t start_loc = c_parser_peek_token (parser)->location;
   10946        72686 :   location_t end_loc;
   10947        72686 :   tree alignof_spelling = c_parser_peek_token (parser)->value;
   10948        72686 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_ALIGNOF));
   10949        72686 :   bool is_c11_alignof = (strcmp (IDENTIFIER_POINTER (alignof_spelling),
   10950              :                                 "_Alignof") == 0
   10951        72686 :                          || strcmp (IDENTIFIER_POINTER (alignof_spelling),
   10952        72916 :                                     "alignof") == 0);
   10953              :   /* A diagnostic is not required for the use of this identifier in
   10954              :      the implementation namespace; only diagnose it for the C11 or C23
   10955              :      spelling because of existing code using the other spellings.  */
   10956          230 :   if (is_c11_alignof)
   10957              :     {
   10958          230 :       if (flag_isoc99)
   10959          226 :         pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C99 does not support %qE",
   10960              :                      alignof_spelling);
   10961              :       else
   10962            4 :         pedwarn_c99 (start_loc, OPT_Wpedantic, "ISO C90 does not support %qE",
   10963              :                      alignof_spelling);
   10964              :     }
   10965        72686 :   c_parser_consume_token (parser);
   10966        72686 :   c_inhibit_evaluation_warnings++;
   10967        72686 :   in_alignof++;
   10968        72686 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
   10969        72686 :       && c_token_starts_compound_literal (c_parser_peek_2nd_token (parser)))
   10970              :     {
   10971              :       /* Either __alignof__ ( type-name ) or __alignof__
   10972              :          unary-expression starting with a compound literal.  */
   10973        31887 :       location_t loc;
   10974        31887 :       struct c_declspecs *scspecs;
   10975        31887 :       struct c_type_name *type_name;
   10976        31887 :       struct c_expr ret;
   10977        31887 :       matching_parens parens;
   10978        31887 :       parens.consume_open (parser);
   10979        31887 :       loc = c_parser_peek_token (parser)->location;
   10980        31887 :       scspecs = c_parser_compound_literal_scspecs (parser);
   10981        31887 :       type_name = c_parser_type_name (parser, true);
   10982        31887 :       end_loc = c_parser_peek_token (parser)->location;
   10983        31887 :       parens.skip_until_found_close (parser);
   10984        31887 :       if (type_name == NULL)
   10985              :         {
   10986            0 :           struct c_expr ret;
   10987            0 :           c_inhibit_evaluation_warnings--;
   10988            0 :           in_alignof--;
   10989            0 :           ret.set_error ();
   10990            0 :           ret.original_code = ERROR_MARK;
   10991            0 :           ret.original_type = NULL;
   10992        31885 :           return ret;
   10993              :         }
   10994        31887 :       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   10995              :         {
   10996            2 :           expr = c_parser_postfix_expression_after_paren_type (parser, scspecs,
   10997              :                                                                type_name,
   10998              :                                                                loc);
   10999            2 :           goto alignof_expr;
   11000              :         }
   11001              :       /* alignof ( type-name ).  */
   11002        31885 :       if (scspecs)
   11003            1 :         error_at (loc, "storage class specifier in %qE", alignof_spelling);
   11004        31885 :       if (type_name->specs->alignas_p)
   11005            1 :         error_at (type_name->specs->locations[cdw_alignas],
   11006              :                   "alignment specified for type name in %qE",
   11007              :                   alignof_spelling);
   11008        31885 :       c_inhibit_evaluation_warnings--;
   11009        31885 :       in_alignof--;
   11010        31885 :       ret.value = c_sizeof_or_alignof_type (loc, groktypename (type_name,
   11011              :                                                                NULL, NULL),
   11012              :                                             false, is_c11_alignof, 1);
   11013        31885 :       ret.original_code = ERROR_MARK;
   11014        31885 :       ret.original_type = NULL;
   11015        31885 :       set_c_expr_source_range (&ret, start_loc, end_loc);
   11016        31885 :       ret.m_decimal = 0;
   11017        31885 :       return ret;
   11018              :     }
   11019              :   else
   11020              :     {
   11021        40799 :       struct c_expr ret;
   11022        40799 :       expr = c_parser_unary_expression (parser);
   11023        40799 :       end_loc = expr.src_range.m_finish;
   11024        40801 :     alignof_expr:
   11025        40801 :       mark_exp_read (expr.value);
   11026        40801 :       c_inhibit_evaluation_warnings--;
   11027        40801 :       in_alignof--;
   11028        40801 :       if (is_c11_alignof)
   11029           36 :         pedwarn (start_loc,
   11030           36 :                  OPT_Wpedantic, "ISO C does not allow %<%E (expression)%>",
   11031              :                  alignof_spelling);
   11032        40801 :       ret.value = c_alignof_expr (start_loc, expr.value);
   11033        40801 :       ret.original_code = ERROR_MARK;
   11034        40801 :       ret.original_type = NULL;
   11035        40801 :       set_c_expr_source_range (&ret, start_loc, end_loc);
   11036        40801 :       ret.m_decimal = 0;
   11037        40801 :       return ret;
   11038              :     }
   11039              : }
   11040              : 
   11041              : /* Parse a _Maxof or _Minof expression.  */
   11042              : 
   11043              : static struct c_expr
   11044          102 : c_parser_maxof_or_minof_expression (c_parser *parser, enum rid rid)
   11045              : {
   11046          102 :   const char *op_name = (rid == RID_MAXOF) ? "_Maxof" : "_Minof";
   11047          102 :   struct c_expr result;
   11048          102 :   location_t expr_loc;
   11049          102 :   struct c_type_name *type_name;
   11050          102 :   matching_parens parens;
   11051          102 :   gcc_assert (c_parser_next_token_is_keyword (parser, rid));
   11052              : 
   11053          102 :   location_t start;
   11054          102 :   location_t finish = UNKNOWN_LOCATION;
   11055              : 
   11056          102 :   start = c_parser_peek_token (parser)->location;
   11057              : 
   11058          102 :   pedwarn (start, OPT_Wpedantic, "ISO C does not support %qs", op_name);
   11059              : 
   11060          102 :   c_parser_consume_token (parser);
   11061          102 :   c_inhibit_evaluation_warnings++;
   11062          102 :   if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   11063              :     {
   11064            2 :       c_parser_error (parser, "expected %<(%>");
   11065            2 :       goto fail;
   11066              :     }
   11067          100 :   parens.consume_open (parser);
   11068          100 :   expr_loc = c_parser_peek_token (parser)->location;
   11069          100 :   if (!c_token_starts_typename (c_parser_peek_token (parser)))
   11070              :     {
   11071            6 :       error_at (expr_loc, "invalid application of %qs to something not a type", op_name);
   11072            6 :       parens.skip_until_found_close (parser);
   11073            6 :       goto fail;
   11074              :     }
   11075           94 :   type_name = c_parser_type_name (parser, true);
   11076           94 :   if (type_name == NULL)
   11077              :     {
   11078              :       // c_parser_type_name() has already diagnosed the error.
   11079            2 :       parens.skip_until_found_close (parser);
   11080            2 :       goto fail;
   11081              :     }
   11082           92 :   parens.skip_until_found_close (parser);
   11083           92 :   finish = parser->tokens_buf[0].location;
   11084           92 :   if (type_name->specs->alignas_p)
   11085            2 :     error_at (type_name->specs->locations[cdw_alignas],
   11086              :               "alignment specified for type name in %qs", op_name);
   11087           92 :   c_inhibit_evaluation_warnings--;
   11088           92 :   if (rid == RID_MAXOF)
   11089           46 :     result = c_expr_maxof_type (expr_loc, type_name);
   11090              :   else
   11091           46 :     result = c_expr_minof_type (expr_loc, type_name);
   11092           92 :   set_c_expr_source_range (&result, start, finish);
   11093           92 :   return result;
   11094           10 : fail:
   11095           10 :   c_inhibit_evaluation_warnings--;
   11096           10 :   result.set_error ();
   11097           10 :   result.original_code = ERROR_MARK;
   11098           10 :   result.original_type = NULL;
   11099           10 :   return result;
   11100              : }
   11101              : 
   11102              : /* Parse the __builtin_has_attribute ([expr|type], attribute-spec)
   11103              :    expression.  */
   11104              : 
   11105              : static struct c_expr
   11106          764 : c_parser_has_attribute_expression (c_parser *parser)
   11107              : {
   11108          764 :   gcc_assert (c_parser_next_token_is_keyword (parser,
   11109              :                                               RID_BUILTIN_HAS_ATTRIBUTE));
   11110          764 :   location_t start = c_parser_peek_token (parser)->location;
   11111          764 :   c_parser_consume_token (parser);
   11112              : 
   11113          764 :   c_inhibit_evaluation_warnings++;
   11114              : 
   11115          764 :   matching_parens parens;
   11116          764 :   if (!parens.require_open (parser))
   11117              :     {
   11118            0 :       c_inhibit_evaluation_warnings--;
   11119            0 :       in_typeof--;
   11120              : 
   11121            0 :       struct c_expr result;
   11122            0 :       result.set_error ();
   11123            0 :       result.original_code = ERROR_MARK;
   11124            0 :       result.original_type = NULL;
   11125            0 :       return result;
   11126              :     }
   11127              : 
   11128              :   /* Treat the type argument the same way as in typeof for the purposes
   11129              :      of warnings.  FIXME: Generalize this so the warning refers to
   11130              :      __builtin_has_attribute rather than typeof.  */
   11131          764 :   in_typeof++;
   11132              : 
   11133              :   /* The first operand: one of DECL, EXPR, or TYPE.  */
   11134          764 :   tree oper = NULL_TREE;
   11135          764 :   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
   11136              :     {
   11137          148 :       struct c_type_name *tname = c_parser_type_name (parser);
   11138          148 :       in_typeof--;
   11139          148 :       if (tname)
   11140              :         {
   11141          148 :           oper = groktypename (tname, NULL, NULL);
   11142          148 :           pop_maybe_used (c_type_variably_modified_p (oper));
   11143              :         }
   11144              :     }
   11145              :   else
   11146              :     {
   11147          616 :       struct c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
   11148          616 :       c_inhibit_evaluation_warnings--;
   11149          616 :       in_typeof--;
   11150          616 :       if (cexpr.value != error_mark_node)
   11151              :         {
   11152          613 :           mark_exp_read (cexpr.value);
   11153          613 :           oper = cexpr.value;
   11154          613 :           tree etype = TREE_TYPE (oper);
   11155          613 :           bool was_vm = c_type_variably_modified_p (etype);
   11156              :           /* This is returned with the type so that when the type is
   11157              :              evaluated, this can be evaluated.  */
   11158          613 :           if (was_vm)
   11159            0 :             oper = c_fully_fold (oper, false, NULL);
   11160          613 :           pop_maybe_used (was_vm);
   11161              :         }
   11162              :     }
   11163              : 
   11164          764 :   struct c_expr result;
   11165          764 :   result.original_code = ERROR_MARK;
   11166          764 :   result.original_type = NULL;
   11167              : 
   11168          764 :   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   11169              :     {
   11170              :       /* Consume the closing parenthesis if that's the next token
   11171              :          in the likely case the built-in was invoked with fewer
   11172              :          than two arguments.  */
   11173            4 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   11174            4 :         c_parser_consume_token (parser);
   11175            4 :       c_inhibit_evaluation_warnings--;
   11176            4 :       result.set_error ();
   11177            4 :       return result;
   11178              :     }
   11179              : 
   11180          760 :   bool save_translate_strings_p = parser->translate_strings_p;
   11181              : 
   11182          760 :   location_t atloc = c_parser_peek_token (parser)->location;
   11183              :   /* Parse a single attribute.  Require no leading comma and do not
   11184              :      allow empty attributes.  */
   11185          760 :   tree attr = c_parser_gnu_attribute (parser, NULL_TREE, false, false);
   11186              : 
   11187          760 :   parser->translate_strings_p = save_translate_strings_p;
   11188              : 
   11189          760 :   location_t finish = c_parser_peek_token (parser)->location;
   11190          760 :   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   11191          757 :     c_parser_consume_token (parser);
   11192              :   else
   11193              :     {
   11194            3 :       c_parser_error (parser, "expected identifier");
   11195            3 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11196              : 
   11197            3 :       result.set_error ();
   11198            3 :       return result;
   11199              :     }
   11200              : 
   11201          757 :   if (!attr)
   11202              :     {
   11203            0 :       error_at (atloc, "expected identifier");
   11204            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   11205              :                                  "expected %<)%>");
   11206            0 :       result.set_error ();
   11207            0 :       return result;
   11208              :     }
   11209              : 
   11210          757 :   result.original_code = INTEGER_CST;
   11211          757 :   result.original_type = boolean_type_node;
   11212              : 
   11213          757 :   if (has_attribute (atloc, oper, attr, default_conversion))
   11214          296 :     result.value = boolean_true_node;
   11215              :   else
   11216          461 :     result.value =  boolean_false_node;
   11217              : 
   11218          757 :   set_c_expr_source_range (&result, start, finish);
   11219          757 :   result.m_decimal = 0;
   11220          757 :   return result;
   11221              : }
   11222              : 
   11223              : /* Helper function to read arguments of builtins which are interfaces
   11224              :    for the middle-end nodes like COMPLEX_EXPR, VEC_PERM_EXPR and
   11225              :    others.  The name of the builtin is passed using BNAME parameter.
   11226              :    Function returns true if there were no errors while parsing and
   11227              :    stores the arguments in CEXPR_LIST.  If it returns true,
   11228              :    *OUT_CLOSE_PAREN_LOC is written to with the location of the closing
   11229              :    parenthesis.  */
   11230              : static bool
   11231      1561839 : c_parser_get_builtin_args (c_parser *parser, const char *bname,
   11232              :                            vec<c_expr_t, va_gc> **ret_cexpr_list,
   11233              :                            bool choose_expr_p,
   11234              :                            location_t *out_close_paren_loc)
   11235              : {
   11236      1561839 :   location_t loc = c_parser_peek_token (parser)->location;
   11237      1561839 :   vec<c_expr_t, va_gc> *cexpr_list;
   11238      1561839 :   c_expr_t expr;
   11239      1561839 :   bool saved_force_folding_builtin_constant_p;
   11240              : 
   11241      1561839 :   *ret_cexpr_list = NULL;
   11242      1561839 :   if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
   11243              :     {
   11244            1 :       error_at (loc, "cannot take address of %qs", bname);
   11245            1 :       return false;
   11246              :     }
   11247              : 
   11248      1561838 :   c_parser_consume_token (parser);
   11249              : 
   11250      1561838 :   if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   11251              :     {
   11252           19 :       *out_close_paren_loc = c_parser_peek_token (parser)->location;
   11253           19 :       c_parser_consume_token (parser);
   11254           19 :       return true;
   11255              :     }
   11256              : 
   11257      1561819 :   saved_force_folding_builtin_constant_p
   11258      1561819 :     = force_folding_builtin_constant_p;
   11259      1561819 :   force_folding_builtin_constant_p |= choose_expr_p;
   11260      1561819 :   expr = c_parser_expr_no_commas (parser, NULL);
   11261      1561819 :   force_folding_builtin_constant_p
   11262      1561819 :     = saved_force_folding_builtin_constant_p;
   11263      1561819 :   vec_alloc (cexpr_list, 1);
   11264      1561819 :   vec_safe_push (cexpr_list, expr);
   11265     18273112 :   while (c_parser_next_token_is (parser, CPP_COMMA))
   11266              :     {
   11267     15149474 :       c_parser_consume_token (parser);
   11268     15149474 :       if (c_parser_next_token_is (parser, CPP_EMBED))
   11269              :         {
   11270            2 :           c_token *embed = c_parser_peek_token (parser);
   11271            2 :           tree value = embed->value;
   11272            2 :           expr.original_code = INTEGER_CST;
   11273            2 :           expr.original_type = integer_type_node;
   11274            2 :           expr.value = NULL_TREE;
   11275            2 :           set_c_expr_source_range (&expr, embed->get_range ());
   11276            2 :           expr.m_decimal = 0;
   11277          510 :           for (unsigned int i = 0; i < (unsigned) RAW_DATA_LENGTH (value); i++)
   11278              :             {
   11279         1016 :               expr.value = build_int_cst (integer_type_node,
   11280          508 :                                           RAW_DATA_UCHAR_ELT (value, i));
   11281          508 :               vec_safe_push (cexpr_list, expr);
   11282              :             }
   11283            2 :           c_parser_consume_token (parser);
   11284            2 :           continue;
   11285            2 :         }
   11286     15149472 :       expr = c_parser_expr_no_commas (parser, NULL);
   11287     15149472 :       vec_safe_push (cexpr_list, expr);
   11288              :     }
   11289              : 
   11290      1561819 :   *out_close_paren_loc = c_parser_peek_token (parser)->location;
   11291      1561819 :   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   11292              :     return false;
   11293              : 
   11294      1561819 :   *ret_cexpr_list = cexpr_list;
   11295      1561819 :   return true;
   11296              : }
   11297              : 
   11298              : /* This represents a single generic-association.  */
   11299              : 
   11300              : struct c_generic_association
   11301              : {
   11302              :   /* The location of the starting token of the type.  */
   11303              :   location_t type_location;
   11304              :   /* The association's type, or NULL_TREE for 'default'.  */
   11305              :   tree type;
   11306              :   /* The association's expression.  */
   11307              :   struct c_expr expression;
   11308              : };
   11309              : 
   11310              : /* Parse a generic-selection.  (C11 6.5.1.1).
   11311              : 
   11312              :    generic-selection:
   11313              :      _Generic ( generic-controlling-operand , generic-assoc-list )
   11314              : 
   11315              :   generic-controlling-operand:
   11316              :     assignment-expression
   11317              :     type-name
   11318              : 
   11319              :   (The use of a type-name is new in C2Y.)
   11320              : 
   11321              :    generic-assoc-list:
   11322              :      generic-association
   11323              :      generic-assoc-list , generic-association
   11324              : 
   11325              :    generic-association:
   11326              :      type-name : assignment-expression
   11327              :      default : assignment-expression
   11328              : */
   11329              : 
   11330              : static struct c_expr
   11331          711 : c_parser_generic_selection (c_parser *parser)
   11332              : {
   11333          711 :   struct c_expr selector, error_expr;
   11334          711 :   tree selector_type;
   11335          711 :   struct c_generic_association matched_assoc;
   11336          711 :   int match_found = -1;
   11337          711 :   location_t generic_loc, selector_loc;
   11338              : 
   11339          711 :   error_expr.original_code = ERROR_MARK;
   11340          711 :   error_expr.original_type = NULL;
   11341          711 :   error_expr.set_error ();
   11342          711 :   matched_assoc.type_location = UNKNOWN_LOCATION;
   11343          711 :   matched_assoc.type = NULL_TREE;
   11344          711 :   matched_assoc.expression = error_expr;
   11345              : 
   11346          711 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_GENERIC));
   11347          711 :   generic_loc = c_parser_peek_token (parser)->location;
   11348          711 :   c_parser_consume_token (parser);
   11349          711 :   if (flag_isoc99)
   11350          709 :     pedwarn_c99 (generic_loc, OPT_Wpedantic,
   11351              :                  "ISO C99 does not support %<_Generic%>");
   11352              :   else
   11353            2 :     pedwarn_c99 (generic_loc, OPT_Wpedantic,
   11354              :                  "ISO C90 does not support %<_Generic%>");
   11355              : 
   11356          711 :   matching_parens parens;
   11357          711 :   if (!parens.require_open (parser))
   11358            0 :     return error_expr;
   11359              : 
   11360          711 :   selector_loc = c_parser_peek_token (parser)->location;
   11361          711 :   if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
   11362              :     {
   11363           38 :       c_inhibit_evaluation_warnings++;
   11364           38 :       pedwarn_c23 (selector_loc, OPT_Wpedantic,
   11365              :                    "ISO C does not support use of type name as %<_Generic%> "
   11366              :                    "controlling operand before C2Y");
   11367           38 :       struct c_type_name *type = c_parser_type_name (parser);
   11368           38 :       if (type)
   11369           37 :         selector_type = groktypename (type, NULL, NULL);
   11370           38 :       c_inhibit_evaluation_warnings--;
   11371           38 :       if (!type)
   11372              :         {
   11373            1 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11374            1 :           return error_expr;
   11375              :         }
   11376              :     }
   11377              :   else
   11378              :     {
   11379          673 :       c_inhibit_evaluation_warnings++;
   11380          673 :       in_generic++;
   11381          673 :       selector = c_parser_expr_no_commas (parser, NULL);
   11382          673 :       selector = default_function_array_conversion (selector_loc, selector);
   11383          673 :       c_inhibit_evaluation_warnings--;
   11384          673 :       in_generic--;
   11385          673 :       pop_maybe_used (!flag_isoc23);
   11386              : 
   11387          673 :       if (selector.value == error_mark_node)
   11388              :         {
   11389            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11390            0 :           return selector;
   11391              :         }
   11392          673 :       mark_exp_read (selector.value);
   11393          673 :       selector_type = TREE_TYPE (selector.value);
   11394              :       /* In ISO C terms, rvalues (including the controlling expression
   11395              :          of _Generic) do not have qualified types.  */
   11396          673 :       if (TREE_CODE (selector_type) != ARRAY_TYPE)
   11397          673 :         selector_type = TYPE_MAIN_VARIANT (selector_type);
   11398              :       /* In ISO C terms, _Noreturn is not part of the type of expressions
   11399              :          such as &abort, but in GCC it is represented internally as a type
   11400              :          qualifier.  */
   11401           74 :       if (FUNCTION_POINTER_TYPE_P (selector_type)
   11402          677 :           && TYPE_QUALS (TREE_TYPE (selector_type)) != TYPE_UNQUALIFIED)
   11403            1 :         selector_type
   11404            1 :           = c_build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (selector_type)));
   11405              :     }
   11406              : 
   11407          710 :   if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   11408              :     {
   11409            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11410            0 :       return error_expr;
   11411              :     }
   11412              : 
   11413          710 :   auto_vec<c_generic_association> associations;
   11414          710 :   struct maybe_used_decl *maybe_used_default = NULL;
   11415         1960 :   while (1)
   11416              :     {
   11417         1335 :       struct c_generic_association assoc, *iter;
   11418         1335 :       unsigned int ix;
   11419         1335 :       c_token *token = c_parser_peek_token (parser);
   11420              : 
   11421         1335 :       assoc.type_location = token->location;
   11422         1335 :       if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
   11423              :         {
   11424          514 :           c_parser_consume_token (parser);
   11425          514 :           assoc.type = NULL_TREE;
   11426              :         }
   11427              :       else
   11428              :         {
   11429          821 :           struct c_type_name *type_name;
   11430              : 
   11431          821 :           type_name = c_parser_type_name (parser);
   11432          821 :           if (type_name == NULL)
   11433              :             {
   11434            1 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11435            1 :               return error_expr;
   11436              :             }
   11437          820 :           assoc.type = grokgenassoc (type_name);
   11438          820 :           if (assoc.type == error_mark_node)
   11439              :             {
   11440            0 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11441            0 :               return error_expr;
   11442              :             }
   11443              : 
   11444          820 :           if (TREE_CODE (assoc.type) == FUNCTION_TYPE)
   11445            9 :             pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
   11446              :                          "ISO C does not support %<_Generic%> association with "
   11447              :                          "function type before C2Y");
   11448          811 :           else if (!COMPLETE_TYPE_P (assoc.type))
   11449           13 :             pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
   11450              :                          "ISO C does not support %<_Generic%> association with "
   11451              :                          "incomplete type before C2Y");
   11452              : 
   11453          820 :           if (c_type_variably_modified_p (assoc.type))
   11454            9 :             pedwarn_c23 (assoc.type_location, OPT_Wpedantic,
   11455              :                          "ISO C does not support %<_Generic%> association with "
   11456              :                          "variably-modified type before C2Y");
   11457              :         }
   11458              : 
   11459         1334 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   11460              :         {
   11461            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11462            0 :           return error_expr;
   11463              :         }
   11464              : 
   11465         1334 :       bool match = assoc.type == NULL_TREE
   11466         1334 :                    || comptypes (assoc.type, selector_type);
   11467              : 
   11468          178 :       if (!match)
   11469          178 :         c_inhibit_evaluation_warnings++;
   11470         1334 :       in_generic++;
   11471              : 
   11472         1334 :       assoc.expression = c_parser_expr_no_commas (parser, NULL);
   11473              : 
   11474         1334 :       if (!match)
   11475          178 :           c_inhibit_evaluation_warnings--;
   11476         1334 :       in_generic--;
   11477         1334 :       if (!match)
   11478          178 :         pop_maybe_used (!flag_isoc23);
   11479         1156 :       else if (assoc.type == NULL_TREE)
   11480          514 :         maybe_used_default = save_maybe_used ();
   11481              :       else
   11482          642 :         pop_maybe_used (true);
   11483              : 
   11484         1334 :       if (assoc.expression.value == error_mark_node)
   11485              :         {
   11486            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11487            0 :           return error_expr;
   11488              :         }
   11489              : 
   11490         2073 :       for (ix = 0; associations.iterate (ix, &iter); ++ix)
   11491              :         {
   11492          739 :           if (assoc.type == NULL_TREE)
   11493              :             {
   11494          219 :               if (iter->type == NULL_TREE)
   11495              :                 {
   11496            1 :                   error_at (assoc.type_location,
   11497              :                             "duplicate %<default%> case in %<_Generic%>");
   11498            1 :                   inform (iter->type_location, "original %<default%> is here");
   11499              :                 }
   11500              :             }
   11501          520 :           else if (iter->type != NULL_TREE)
   11502              :             {
   11503          178 :               if (comptypes (assoc.type, iter->type))
   11504              :                 {
   11505            1 :                   error_at (assoc.type_location,
   11506              :                             "%<_Generic%> specifies two compatible types");
   11507            1 :                   inform (iter->type_location, "compatible type is here");
   11508              :                 }
   11509              :             }
   11510              :         }
   11511              : 
   11512         1334 :       if (assoc.type == NULL_TREE)
   11513              :         {
   11514          514 :           if (match_found < 0)
   11515              :             {
   11516          360 :               matched_assoc = assoc;
   11517          409 :               match_found = associations.length ();
   11518              :             }
   11519              :         }
   11520          820 :       else if (match)
   11521              :         {
   11522          642 :           if (match_found < 0 || matched_assoc.type == NULL_TREE)
   11523              :             {
   11524          642 :               matched_assoc = assoc;
   11525          980 :               match_found = associations.length ();
   11526              :             }
   11527              :           else
   11528              :             {
   11529            0 :               error_at (assoc.type_location,
   11530              :                         "%<_Generic%> selector matches multiple associations");
   11531            0 :               inform (matched_assoc.type_location,
   11532              :                       "other match is here");
   11533              :             }
   11534              :         }
   11535              : 
   11536         1334 :       associations.safe_push (assoc);
   11537              : 
   11538         1334 :       if (c_parser_peek_token (parser)->type != CPP_COMMA)
   11539              :         break;
   11540          625 :       c_parser_consume_token (parser);
   11541          625 :     }
   11542              : 
   11543          709 :   if (match_found >= 0 && matched_assoc.type == NULL_TREE)
   11544              :     {
   11545              :       /* Declarations referenced in the default association are used.  */
   11546           64 :       restore_maybe_used (maybe_used_default);
   11547           64 :       pop_maybe_used (true);
   11548              :     }
   11549          645 :   else if (maybe_used_default)
   11550              :     {
   11551              :       /* Declarations referenced in the default association are not used, but
   11552              :          are treated as used before C23.  */
   11553            8 :       restore_maybe_used (maybe_used_default);
   11554            8 :       pop_maybe_used (!flag_isoc23);
   11555              :     }
   11556              : 
   11557              :   unsigned int ix;
   11558              :   struct c_generic_association *iter;
   11559         2042 :   FOR_EACH_VEC_ELT (associations, ix, iter)
   11560         1333 :     if (ix != (unsigned) match_found)
   11561          628 :       mark_exp_read (iter->expression.value);
   11562              : 
   11563          709 :   if (!parens.require_close (parser))
   11564              :     {
   11565            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11566            0 :       return error_expr;
   11567              :     }
   11568              : 
   11569          709 :   if (match_found < 0)
   11570              :     {
   11571            4 :       error_at (selector_loc, "%<_Generic%> selector of type %qT is not "
   11572              :                 "compatible with any association",
   11573              :                 selector_type);
   11574            4 :       return error_expr;
   11575              :     }
   11576              : 
   11577          705 :   return matched_assoc.expression;
   11578          710 : }
   11579              : 
   11580              : /* Check the validity of a function pointer argument *EXPR (argument
   11581              :    position POS) to __builtin_tgmath.  Return the number of function
   11582              :    arguments if possibly valid; return 0 having reported an error if
   11583              :    not valid.  */
   11584              : 
   11585              : static unsigned int
   11586         1755 : check_tgmath_function (c_expr *expr, unsigned int pos)
   11587              : {
   11588         1755 :   tree type = TREE_TYPE (expr->value);
   11589         1755 :   if (!FUNCTION_POINTER_TYPE_P (type))
   11590              :     {
   11591            2 :       error_at (expr->get_location (),
   11592              :                 "argument %u of %<__builtin_tgmath%> is not a function pointer",
   11593              :                 pos);
   11594            2 :       return 0;
   11595              :     }
   11596         1753 :   type = TREE_TYPE (type);
   11597         1753 :   if (!prototype_p (type))
   11598              :     {
   11599            2 :       error_at (expr->get_location (),
   11600              :                 "argument %u of %<__builtin_tgmath%> is unprototyped", pos);
   11601            2 :       return 0;
   11602              :     }
   11603         1751 :   if (stdarg_p (type))
   11604              :     {
   11605            2 :       error_at (expr->get_location (),
   11606              :                 "argument %u of %<__builtin_tgmath%> has variable arguments",
   11607              :                 pos);
   11608            2 :       return 0;
   11609              :     }
   11610         1749 :   unsigned int nargs = 0;
   11611         1749 :   function_args_iterator iter;
   11612         1749 :   tree t;
   11613         4176 :   FOREACH_FUNCTION_ARGS (type, t, iter)
   11614              :     {
   11615         4176 :       if (t == void_type_node)
   11616              :         break;
   11617         2427 :       nargs++;
   11618              :     }
   11619         1749 :   if (nargs == 0)
   11620              :     {
   11621            2 :       error_at (expr->get_location (),
   11622              :                 "argument %u of %<__builtin_tgmath%> has no arguments", pos);
   11623            2 :       return 0;
   11624              :     }
   11625              :   return nargs;
   11626              : }
   11627              : 
   11628              : /* Ways in which a parameter or return value of a type-generic macro
   11629              :    may vary between the different functions the macro may call.  */
   11630              : enum tgmath_parm_kind
   11631              :   {
   11632              :     tgmath_fixed, tgmath_real, tgmath_complex
   11633              :   };
   11634              : 
   11635              : /* Helper function for c_parser_postfix_expression.  Parse predefined
   11636              :    identifiers.  */
   11637              : 
   11638              : static struct c_expr
   11639        13278 : c_parser_predefined_identifier (c_parser *parser)
   11640              : {
   11641        13278 :   location_t loc = c_parser_peek_token (parser)->location;
   11642        13278 :   switch (c_parser_peek_token (parser)->keyword)
   11643              :     {
   11644          709 :     case RID_FUNCTION_NAME:
   11645          709 :       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
   11646              :                "identifier", "__FUNCTION__");
   11647          709 :       break;
   11648         6179 :     case RID_PRETTY_FUNCTION_NAME:
   11649         6179 :       pedwarn (loc, OPT_Wpedantic, "ISO C does not support %qs predefined "
   11650              :                "identifier", "__PRETTY_FUNCTION__");
   11651         6179 :       break;
   11652         6390 :     case RID_C99_FUNCTION_NAME:
   11653         6390 :       pedwarn_c90 (loc, OPT_Wpedantic, "ISO C90 does not support "
   11654              :                    "%<__func__%> predefined identifier");
   11655         6390 :       break;
   11656            0 :     default:
   11657            0 :       gcc_unreachable ();
   11658              :     }
   11659              : 
   11660        13278 :   struct c_expr expr;
   11661        13278 :   expr.original_code = ERROR_MARK;
   11662        13278 :   expr.original_type = NULL;
   11663        13278 :   expr.value = fname_decl (loc, c_parser_peek_token (parser)->keyword,
   11664        13278 :                            c_parser_peek_token (parser)->value);
   11665        13278 :   set_c_expr_source_range (&expr, loc, loc);
   11666        13278 :   expr.m_decimal = 0;
   11667        13278 :   c_parser_consume_token (parser);
   11668        13278 :   return expr;
   11669              : }
   11670              : 
   11671              : /* Check whether the REF has an counted-by object associated with it
   11672              :    through the "counted_by" attribute.  */
   11673              : 
   11674              : static bool
   11675           80 : has_counted_by_object (tree ref)
   11676              : {
   11677              :   /* Currently, there are two cases are valid:
   11678              :      A. when the ref is an indirect_ref to a call to the
   11679              :         .ACCESS_WITH_SIZE, return true. (this is for FAM)
   11680              :      B. when the ref is a call to .ACCESS_WITH_SIZE, return true.
   11681              :         (this is for pointer field inside a structure)
   11682              :      More cases can be included later when the counted_by attribute is
   11683              :      extended to other situations.  */
   11684           80 :   if ((TREE_CODE (ref) == INDIRECT_REF
   11685           25 :        && is_access_with_size_p (TREE_OPERAND (ref, 0)))
   11686           80 :       || is_access_with_size_p (ref))
   11687           50 :     return true;
   11688              :   return false;
   11689              : }
   11690              : 
   11691              : /* Get the reference to the counted-by object associated with the REF.  */
   11692              : 
   11693              : static tree
   11694           50 : get_counted_by_ref (tree ref)
   11695              : {
   11696              :   /* Currently, there are two cases are valid:
   11697              :      A. when the ref is an indirect_ref to a call to the
   11698              :         .ACCESS_WITH_SIZE, return true. (this is for FAM)
   11699              :      B. when the ref is a call to .ACCESS_WITH_SIZE, return true.
   11700              :         (this is for pointer field inside a structure)
   11701              :      More cases can be included later when the counted_by attribute is
   11702              :      extended to other situations.  */
   11703           50 :   if (TREE_CODE (ref) == INDIRECT_REF
   11704           50 :       && is_access_with_size_p (TREE_OPERAND (ref, 0)))
   11705           25 :     return CALL_EXPR_ARG (TREE_OPERAND (ref, 0), 1);
   11706           25 :   else if (is_access_with_size_p (ref))
   11707           25 :     return CALL_EXPR_ARG (ref, 1);
   11708              : 
   11709              :   return NULL_TREE;
   11710              : }
   11711              : 
   11712              : /* Parse a postfix expression (C90 6.3.1-6.3.2, C99 6.5.1-6.5.2,
   11713              :    C11 6.5.1-6.5.2).  Compound literals aren't handled here; callers have to
   11714              :    call c_parser_postfix_expression_after_paren_type on encountering them.
   11715              : 
   11716              :    postfix-expression:
   11717              :      primary-expression
   11718              :      postfix-expression [ expression ]
   11719              :      postfix-expression ( argument-expression-list[opt] )
   11720              :      postfix-expression . identifier
   11721              :      postfix-expression -> identifier
   11722              :      postfix-expression ++
   11723              :      postfix-expression --
   11724              :      ( storage-class-specifiers[opt] type-name ) { initializer-list[opt] }
   11725              :      ( storage-class-specifiers[opt] type-name ) { initializer-list , }
   11726              : 
   11727              :    argument-expression-list:
   11728              :      argument-expression
   11729              :      argument-expression-list , argument-expression
   11730              : 
   11731              :    primary-expression:
   11732              :      identifier
   11733              :      constant
   11734              :      string-literal
   11735              :      ( expression )
   11736              :      generic-selection
   11737              : 
   11738              :    GNU extensions:
   11739              : 
   11740              :    primary-expression:
   11741              :      __func__
   11742              :        (treated as a keyword in GNU C)
   11743              :      __FUNCTION__
   11744              :      __PRETTY_FUNCTION__
   11745              :      ( compound-statement )
   11746              :      __builtin_va_arg ( assignment-expression , type-name )
   11747              :      __builtin_offsetof ( type-name , offsetof-member-designator )
   11748              :      __builtin_choose_expr ( assignment-expression ,
   11749              :                              assignment-expression ,
   11750              :                              assignment-expression )
   11751              :      __builtin_types_compatible_p ( type-name , type-name )
   11752              :      __builtin_tgmath ( expr-list )
   11753              :      __builtin_complex ( assignment-expression , assignment-expression )
   11754              :      __builtin_shuffle ( assignment-expression , assignment-expression )
   11755              :      __builtin_shuffle ( assignment-expression ,
   11756              :                          assignment-expression ,
   11757              :                          assignment-expression, )
   11758              :      __builtin_convertvector ( assignment-expression , type-name )
   11759              :      __builtin_assoc_barrier ( assignment-expression )
   11760              : 
   11761              :    offsetof-member-designator:
   11762              :      identifier
   11763              :      offsetof-member-designator . identifier
   11764              :      offsetof-member-designator [ expression ]
   11765              : 
   11766              :    Objective-C:
   11767              : 
   11768              :    primary-expression:
   11769              :      [ objc-receiver objc-message-args ]
   11770              :      @selector ( objc-selector-arg )
   11771              :      @protocol ( identifier )
   11772              :      @encode ( type-name )
   11773              :      objc-string-literal
   11774              :      Classname . identifier
   11775              : */
   11776              : 
   11777              : static struct c_expr
   11778    235898210 : c_parser_postfix_expression (c_parser *parser)
   11779              : {
   11780    235898210 :   struct c_expr expr, e1;
   11781    235898210 :   struct c_type_name *t1, *t2;
   11782    235898210 :   location_t loc = c_parser_peek_token (parser)->location;
   11783    235898210 :   source_range tok_range = c_parser_peek_token (parser)->get_range ();
   11784    235898210 :   expr.original_code = ERROR_MARK;
   11785    235898210 :   expr.original_type = NULL;
   11786    235898210 :   expr.m_decimal = 0;
   11787    235898210 :   switch (c_parser_peek_token (parser)->type)
   11788              :     {
   11789     50880176 :     case CPP_NUMBER:
   11790     50880176 :       expr.value = c_parser_peek_token (parser)->value;
   11791     50880176 :       set_c_expr_source_range (&expr, tok_range);
   11792     50880176 :       loc = c_parser_peek_token (parser)->location;
   11793     50880176 :       expr.m_decimal = c_parser_peek_token (parser)->flags & DECIMAL_INT;
   11794     50880176 :       c_parser_consume_token (parser);
   11795     50880176 :       if (TREE_CODE (expr.value) == FIXED_CST
   11796     50880176 :           && !targetm.fixed_point_supported_p ())
   11797              :         {
   11798            6 :           error_at (loc, "fixed-point types not supported for this target");
   11799            6 :           expr.set_error ();
   11800              :         }
   11801              :       break;
   11802       113305 :     case CPP_CHAR:
   11803       113305 :     case CPP_CHAR16:
   11804       113305 :     case CPP_CHAR32:
   11805       113305 :     case CPP_UTF8CHAR:
   11806       113305 :     case CPP_WCHAR:
   11807       113305 :       expr.value = c_parser_peek_token (parser)->value;
   11808              :       /* For the purpose of warning when a pointer is compared with
   11809              :          a zero character constant.  */
   11810       113305 :       expr.original_type = char_type_node;
   11811       113305 :       set_c_expr_source_range (&expr, tok_range);
   11812       113305 :       c_parser_consume_token (parser);
   11813       113305 :       break;
   11814      1164664 :     case CPP_STRING:
   11815      1164664 :     case CPP_STRING16:
   11816      1164664 :     case CPP_STRING32:
   11817      1164664 :     case CPP_WSTRING:
   11818      1164664 :     case CPP_UTF8STRING:
   11819      1164664 :       expr = c_parser_string_literal (parser, parser->translate_strings_p,
   11820              :                                       true);
   11821      1164664 :       break;
   11822            0 :     case CPP_OBJC_STRING:
   11823            0 :       gcc_assert (c_dialect_objc ());
   11824            0 :       expr.value
   11825            0 :         = objc_build_string_object (c_parser_peek_token (parser)->value);
   11826            0 :       set_c_expr_source_range (&expr, tok_range);
   11827            0 :       c_parser_consume_token (parser);
   11828            0 :       break;
   11829    174587021 :     case CPP_NAME:
   11830    174587021 :       switch (c_parser_peek_token (parser)->id_kind)
   11831              :         {
   11832    174587019 :         case C_ID_ID:
   11833    174587019 :           {
   11834    174587019 :             tree id = c_parser_peek_token (parser)->value;
   11835    174587019 :             c_parser_consume_token (parser);
   11836    523761057 :             expr.value = build_external_ref (loc, id,
   11837    174587019 :                                              (c_parser_peek_token (parser)->type
   11838              :                                               == CPP_OPEN_PAREN),
   11839              :                                              &expr.original_type);
   11840    174587019 :             set_c_expr_source_range (&expr, tok_range);
   11841    174587019 :             break;
   11842              :           }
   11843            0 :         case C_ID_CLASSNAME:
   11844            0 :           {
   11845              :             /* Here we parse the Objective-C 2.0 Class.name dot
   11846              :                syntax.  */
   11847            0 :             tree class_name = c_parser_peek_token (parser)->value;
   11848            0 :             tree component;
   11849            0 :             c_parser_consume_token (parser);
   11850            0 :             gcc_assert (c_dialect_objc ());
   11851            0 :             if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
   11852              :               {
   11853            0 :                 expr.set_error ();
   11854            0 :                 break;
   11855              :               }
   11856            0 :             if (c_parser_next_token_is_not (parser, CPP_NAME))
   11857              :               {
   11858            0 :                 c_parser_error (parser, "expected identifier");
   11859            0 :                 expr.set_error ();
   11860            0 :                 break;
   11861              :               }
   11862            0 :             c_token *component_tok = c_parser_peek_token (parser);
   11863            0 :             component = component_tok->value;
   11864            0 :             location_t end_loc = component_tok->get_finish ();
   11865            0 :             c_parser_consume_token (parser);
   11866            0 :             expr.value = objc_build_class_component_ref (class_name,
   11867              :                                                          component);
   11868            0 :             set_c_expr_source_range (&expr, loc, end_loc);
   11869            0 :             break;
   11870              :           }
   11871            2 :         default:
   11872            2 :           c_parser_error (parser, "expected expression");
   11873            2 :           expr.set_error ();
   11874            2 :           break;
   11875              :         }
   11876              :       break;
   11877      7516556 :     case CPP_OPEN_PAREN:
   11878              :       /* A parenthesized expression, statement expression or compound
   11879              :          literal.  */
   11880      7516556 :       if (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_BRACE)
   11881              :         {
   11882              :           /* A statement expression.  */
   11883        34875 :           tree stmt;
   11884        34875 :           location_t brace_loc;
   11885        34875 :           bool save_c_omp_array_section_p = c_omp_array_section_p;
   11886        34875 :           c_parser_consume_token (parser);
   11887        34875 :           brace_loc = c_parser_peek_token (parser)->location;
   11888        34875 :           c_parser_consume_token (parser);
   11889              :           /* If we've not yet started the current function's statement list,
   11890              :              or we're in the parameter scope of an old-style function
   11891              :              declaration, statement expressions are not allowed.  */
   11892        34875 :           if (!building_stmt_list_p () || old_style_parameter_scope ())
   11893              :             {
   11894           24 :               error_at (loc, "braced-group within expression allowed "
   11895              :                         "only inside a function");
   11896           24 :               parser->error = true;
   11897           24 :               c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
   11898           24 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11899           24 :               expr.set_error ();
   11900           24 :               break;
   11901              :             }
   11902        34851 :           c_omp_array_section_p = false;
   11903        34851 :           stmt = c_begin_stmt_expr ();
   11904        34851 :           c_parser_compound_statement_nostart (parser);
   11905        34851 :           location_t close_loc = c_parser_peek_token (parser)->location;
   11906        34851 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   11907              :                                      "expected %<)%>");
   11908        34851 :           pedwarn (loc, OPT_Wpedantic,
   11909              :                    "ISO C forbids braced-groups within expressions");
   11910        34851 :           expr.value = c_finish_stmt_expr (brace_loc, stmt);
   11911        34851 :           set_c_expr_source_range (&expr, loc, close_loc);
   11912        34851 :           mark_exp_read (expr.value);
   11913        34851 :           c_omp_array_section_p = save_c_omp_array_section_p;
   11914              :         }
   11915              :       else
   11916              :         {
   11917              :           /* A parenthesized expression.  */
   11918      7481681 :           location_t loc_open_paren = c_parser_peek_token (parser)->location;
   11919      7481681 :           c_parser_consume_token (parser);
   11920      7481681 :           expr = c_parser_expression (parser);
   11921      7481681 :           if (TREE_CODE (expr.value) == MODIFY_EXPR)
   11922        38243 :             suppress_warning (expr.value, OPT_Wparentheses);
   11923      7481681 :           if (expr.original_code != C_MAYBE_CONST_EXPR
   11924      7481669 :               && expr.original_code != SIZEOF_EXPR)
   11925      7476768 :             expr.original_code = ERROR_MARK;
   11926              :           /* Remember that we saw ( ) around the sizeof.  */
   11927      7481681 :           if (expr.original_code == SIZEOF_EXPR)
   11928         4901 :             expr.original_code = PAREN_SIZEOF_EXPR;
   11929              :           /* Don't change EXPR.ORIGINAL_TYPE.  */
   11930      7481681 :           location_t loc_close_paren = c_parser_peek_token (parser)->location;
   11931      7481681 :           set_c_expr_source_range (&expr, loc_open_paren, loc_close_paren);
   11932      7481681 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   11933              :                                      "expected %<)%>", loc_open_paren);
   11934              :         }
   11935              :       break;
   11936      1635693 :     case CPP_KEYWORD:
   11937      1635693 :       switch (c_parser_peek_token (parser)->keyword)
   11938              :         {
   11939        13258 :         case RID_FUNCTION_NAME:
   11940        13258 :         case RID_PRETTY_FUNCTION_NAME:
   11941        13258 :         case RID_C99_FUNCTION_NAME:
   11942        13258 :           expr = c_parser_predefined_identifier (parser);
   11943        13258 :           break;
   11944        19884 :         case RID_VA_ARG:
   11945        19884 :           {
   11946        19884 :             location_t start_loc = loc;
   11947        19884 :             c_parser_consume_token (parser);
   11948        19884 :             matching_parens parens;
   11949        19884 :             if (!parens.require_open (parser))
   11950              :               {
   11951            0 :                 expr.set_error ();
   11952            0 :                 break;
   11953              :               }
   11954        19884 :             e1 = c_parser_expr_no_commas (parser, NULL);
   11955        19884 :             mark_exp_read (e1.value);
   11956        19884 :             e1.value = c_fully_fold (e1.value, false, NULL);
   11957        19884 :             if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   11958              :               {
   11959            0 :                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11960            0 :                 expr.set_error ();
   11961            0 :                 break;
   11962              :               }
   11963        19884 :             loc = c_parser_peek_token (parser)->location;
   11964        19884 :             t1 = c_parser_type_name (parser);
   11965        19884 :             location_t end_loc = c_parser_peek_token (parser)->get_finish ();
   11966        19884 :             c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   11967              :                                        "expected %<)%>");
   11968        19884 :             if (t1 == NULL)
   11969              :               {
   11970            0 :                 expr.set_error ();
   11971              :               }
   11972              :             else
   11973              :               {
   11974        19884 :                 tree type_expr = NULL_TREE;
   11975        19884 :                 tree type = groktypename (t1, &type_expr, NULL);
   11976        19884 :                 expr.value = c_build_va_arg (start_loc, e1.value, loc,
   11977              :                                              type, type_expr);
   11978        19884 :                 set_c_expr_source_range (&expr, start_loc, end_loc);
   11979              :               }
   11980              :           }
   11981        19884 :           break;
   11982        13619 :         case RID_C23_VA_START:
   11983        13619 :           {
   11984        13619 :             c_parser_consume_token (parser);
   11985        13619 :             matching_parens parens;
   11986        13619 :             if (!parens.require_open (parser))
   11987              :               {
   11988            0 :                 expr.set_error ();
   11989            0 :                 break;
   11990              :               }
   11991        13619 :             e1 = c_parser_expr_no_commas (parser, NULL);
   11992        13619 :             e1 = convert_lvalue_to_rvalue (e1.get_location (), e1, true, true);
   11993        13619 :             if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   11994              :               {
   11995        13441 :                 location_t cloc = c_parser_peek_token (parser)->location;
   11996        13441 :                 if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   11997              :                   {
   11998            0 :                     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   11999            0 :                     expr.set_error ();
   12000            0 :                     break;
   12001              :                   }
   12002        13441 :                 if (c_parser_next_token_is (parser, CPP_NAME)
   12003        13436 :                     && c_parser_peek_token (parser)->id_kind == C_ID_ID
   12004        26877 :                     && (c_parser_peek_2nd_token (parser)->type
   12005              :                         == CPP_CLOSE_PAREN))
   12006              :                   {
   12007        13415 :                     tree name = c_parser_peek_token (parser)->value;
   12008        13415 :                     location_t nloc = c_parser_peek_token (parser)->location;
   12009        13415 :                     tree decl = lookup_name (name);
   12010        13415 :                     tree last_parm
   12011        13415 :                       = tree_last (DECL_ARGUMENTS (current_function_decl));
   12012        13415 :                     if (!last_parm || decl != last_parm)
   12013            4 :                       warning_at (nloc, OPT_Wvarargs,
   12014              :                                   "optional second parameter of %<va_start%> "
   12015              :                                   "not last named argument");
   12016        13411 :                     else if (DECL_REGISTER (decl))
   12017            2 :                       warning_at (nloc, OPT_Wvarargs,
   12018              :                                   "undefined behavior when second parameter "
   12019              :                                   "of %<va_start%> is declared with "
   12020              :                                   "%<register%> storage");
   12021        13415 :                     c_parser_consume_token (parser);
   12022              :                   }
   12023              :                 else
   12024              :                   {
   12025           26 :                     unsigned nesting_depth = 0;
   12026           26 :                     location_t sloc = c_parser_peek_token (parser)->location;
   12027           26 :                     location_t eloc = sloc;
   12028              : 
   12029              :                     /* For va_start (ap,) the ) comes from stdarg.h.
   12030              :                        Use location of , in that case, otherwise without
   12031              :                        -Wsystem-headers nothing is reported.  After all,
   12032              :                        the problematic token is the comma in that case.  */
   12033           26 :                     if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   12034            1 :                       sloc = eloc = cloc;
   12035          492 :                     while (true)
   12036              :                       {
   12037          259 :                         c_token *token = c_parser_peek_token (parser);
   12038          259 :                         if (token->type == CPP_CLOSE_PAREN && !nesting_depth)
   12039              :                           break;
   12040              : 
   12041          233 :                         if (token->type == CPP_EOF)
   12042              :                           break;
   12043          233 :                         if (token->type == CPP_OPEN_PAREN)
   12044            8 :                           ++nesting_depth;
   12045          225 :                         else if (token->type == CPP_CLOSE_PAREN)
   12046            8 :                           --nesting_depth;
   12047          233 :                         eloc = token->location;
   12048          233 :                         c_parser_consume_token (parser);
   12049          233 :                       }
   12050           26 :                     if (sloc != eloc)
   12051           25 :                       sloc = make_location (sloc, sloc, eloc);
   12052           26 :                     warning_at (sloc, OPT_Wvarargs,
   12053              :                                 "%<va_start%> macro used with additional "
   12054              :                                 "arguments other than identifier of the "
   12055              :                                 "last named argument");
   12056              :                   }
   12057              :               }
   12058        13619 :             parens.skip_until_found_close (parser);
   12059        13619 :             tree fndecl = builtin_decl_explicit (BUILT_IN_VA_START);
   12060        13619 :             vec<tree, va_gc> *params;
   12061        13619 :             vec_alloc (params, 2);
   12062        13619 :             params->quick_push (e1.value);
   12063        13619 :             params->quick_push (integer_zero_node);
   12064        13619 :             auto_vec<location_t> arg_loc (2);
   12065        13619 :             arg_loc.quick_push (e1.get_location ());
   12066        13619 :             arg_loc.quick_push (UNKNOWN_LOCATION);
   12067        13619 :             expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
   12068              :                                                     params, NULL);
   12069        13619 :             set_c_expr_source_range (&expr, loc,
   12070              :                                      parser->tokens_buf[0].get_finish ());
   12071        13619 :             expr.m_decimal = 0;
   12072        13619 :             expr.original_code = ERROR_MARK;
   12073        13619 :             expr.original_type = NULL;
   12074        13619 :             release_tree_vector (params);
   12075        13619 :             break;
   12076        13619 :           }
   12077         3628 :         case RID_OFFSETOF:
   12078         3628 :           {
   12079         3628 :             c_parser_consume_token (parser);
   12080         3628 :             matching_parens parens;
   12081         3628 :             if (!parens.require_open (parser))
   12082              :               {
   12083            0 :                 expr.set_error ();
   12084            1 :                 break;
   12085              :               }
   12086         3628 :             t1 = c_parser_type_name (parser);
   12087         3628 :             if (t1 == NULL)
   12088            0 :               parser->error = true;
   12089         3628 :             if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   12090            1 :               gcc_assert (parser->error);
   12091         3628 :             if (parser->error)
   12092              :               {
   12093            1 :                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   12094            1 :                 expr.set_error ();
   12095            1 :                 break;
   12096              :               }
   12097         3627 :             tree type = groktypename (t1, NULL, NULL);
   12098         3627 :             tree offsetof_ref;
   12099         3627 :             if (type == error_mark_node)
   12100              :               offsetof_ref = error_mark_node;
   12101              :             else
   12102              :               {
   12103         3626 :                 offsetof_ref = build1 (INDIRECT_REF, type, null_pointer_node);
   12104         3626 :                 SET_EXPR_LOCATION (offsetof_ref, loc);
   12105              :               }
   12106              :             /* Parse the second argument to __builtin_offsetof.  We
   12107              :                must have one identifier, and beyond that we want to
   12108              :                accept sub structure and sub array references.  */
   12109         3627 :             if (c_parser_next_token_is (parser, CPP_NAME))
   12110              :               {
   12111         3627 :                 c_token *comp_tok = c_parser_peek_token (parser);
   12112         3627 :                 offsetof_ref
   12113         3627 :                   = build_component_ref (loc, offsetof_ref, comp_tok->value,
   12114              :                                          comp_tok->location, UNKNOWN_LOCATION);
   12115         3627 :                 c_parser_consume_token (parser);
   12116         3627 :                 while (c_parser_next_token_is (parser, CPP_DOT)
   12117         4089 :                        || c_parser_next_token_is (parser,
   12118              :                                                   CPP_OPEN_SQUARE)
   12119         7955 :                        || c_parser_next_token_is (parser,
   12120              :                                                   CPP_DEREF))
   12121              :                   {
   12122          700 :                     if (c_parser_next_token_is (parser, CPP_DEREF))
   12123              :                       {
   12124            1 :                         loc = c_parser_peek_token (parser)->location;
   12125            1 :                         offsetof_ref = build_array_ref (loc,
   12126              :                                                         offsetof_ref,
   12127              :                                                         integer_zero_node);
   12128            1 :                         goto do_dot;
   12129              :                       }
   12130          699 :                     else if (c_parser_next_token_is (parser, CPP_DOT))
   12131              :                       {
   12132          238 :                       do_dot:
   12133          239 :                         c_parser_consume_token (parser);
   12134          239 :                         if (c_parser_next_token_is_not (parser,
   12135              :                                                         CPP_NAME))
   12136              :                           {
   12137            0 :                             c_parser_error (parser, "expected identifier");
   12138            0 :                             break;
   12139              :                           }
   12140          239 :                         c_token *comp_tok = c_parser_peek_token (parser);
   12141          239 :                         offsetof_ref
   12142          239 :                           = build_component_ref (loc, offsetof_ref,
   12143              :                                                  comp_tok->value,
   12144              :                                                  comp_tok->location,
   12145              :                                                  UNKNOWN_LOCATION);
   12146          239 :                         c_parser_consume_token (parser);
   12147              :                       }
   12148              :                     else
   12149              :                       {
   12150          461 :                         struct c_expr ce;
   12151          461 :                         tree idx;
   12152          461 :                         loc = c_parser_peek_token (parser)->location;
   12153          461 :                         c_parser_consume_token (parser);
   12154          461 :                         ce = c_parser_expression (parser);
   12155          461 :                         ce = convert_lvalue_to_rvalue (loc, ce, false, false);
   12156          461 :                         idx = ce.value;
   12157          461 :                         idx = c_fully_fold (idx, false, NULL);
   12158          461 :                         c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
   12159              :                                                    "expected %<]%>");
   12160          461 :                         offsetof_ref = build_array_ref (loc, offsetof_ref, idx);
   12161              :                       }
   12162              :                   }
   12163              :               }
   12164              :             else
   12165            0 :               c_parser_error (parser, "expected identifier");
   12166         3627 :             location_t end_loc = c_parser_peek_token (parser)->get_finish ();
   12167         3627 :             c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   12168              :                                        "expected %<)%>");
   12169         3627 :             expr.value = fold_offsetof (offsetof_ref);
   12170         3627 :             set_c_expr_source_range (&expr, loc, end_loc);
   12171              :           }
   12172         3627 :           break;
   12173         1167 :         case RID_CHOOSE_EXPR:
   12174         1167 :           {
   12175         1167 :             vec<c_expr_t, va_gc> *cexpr_list;
   12176         1167 :             c_expr_t *e1_p, *e2_p, *e3_p;
   12177         1167 :             tree c;
   12178         1167 :             location_t close_paren_loc;
   12179              : 
   12180         1167 :             c_parser_consume_token (parser);
   12181         1167 :             if (!c_parser_get_builtin_args (parser,
   12182              :                                             "__builtin_choose_expr",
   12183              :                                             &cexpr_list, true,
   12184              :                                             &close_paren_loc))
   12185              :               {
   12186            0 :                 expr.set_error ();
   12187            0 :                 break;
   12188              :               }
   12189              : 
   12190         1167 :             if (vec_safe_length (cexpr_list) != 3)
   12191              :               {
   12192            0 :                 error_at (loc, "wrong number of arguments to "
   12193              :                                "%<__builtin_choose_expr%>");
   12194            0 :                 expr.set_error ();
   12195            0 :                 break;
   12196              :               }
   12197              : 
   12198         1167 :             e1_p = &(*cexpr_list)[0];
   12199         1167 :             e2_p = &(*cexpr_list)[1];
   12200         1167 :             e3_p = &(*cexpr_list)[2];
   12201              : 
   12202         1167 :             c = e1_p->value;
   12203         1167 :             mark_exp_read (e2_p->value);
   12204         1167 :             mark_exp_read (e3_p->value);
   12205         1167 :             if (TREE_CODE (c) != INTEGER_CST
   12206         1167 :                 || !INTEGRAL_TYPE_P (TREE_TYPE (c)))
   12207            7 :               error_at (loc,
   12208              :                         "first argument to %<__builtin_choose_expr%> not"
   12209              :                         " a constant");
   12210         1167 :             constant_expression_warning (c);
   12211         1167 :             expr = integer_zerop (c) ? *e3_p : *e2_p;
   12212         1167 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12213         1167 :             break;
   12214              :           }
   12215          673 :         case RID_TYPES_COMPATIBLE_P:
   12216          673 :           {
   12217          673 :             c_parser_consume_token (parser);
   12218          673 :             matching_parens parens;
   12219          673 :             if (!parens.require_open (parser))
   12220              :               {
   12221            0 :                 expr.set_error ();
   12222            2 :                 break;
   12223              :               }
   12224          673 :             t1 = c_parser_type_name (parser);
   12225          673 :             if (t1 == NULL)
   12226              :               {
   12227            0 :                 expr.set_error ();
   12228            0 :                 break;
   12229              :               }
   12230          673 :             if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   12231              :               {
   12232            1 :                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   12233            1 :                 expr.set_error ();
   12234            1 :                 break;
   12235              :               }
   12236          672 :             t2 = c_parser_type_name (parser);
   12237          672 :             if (t2 == NULL)
   12238              :               {
   12239            0 :                 expr.set_error ();
   12240            0 :                 break;
   12241              :               }
   12242          672 :             location_t close_paren_loc = c_parser_peek_token (parser)->location;
   12243          672 :             parens.skip_until_found_close (parser);
   12244          672 :             tree e1, e2;
   12245          672 :             e1 = groktypename (t1, NULL, NULL);
   12246          672 :             e2 = groktypename (t2, NULL, NULL);
   12247          672 :             if (e1 == error_mark_node || e2 == error_mark_node)
   12248              :               {
   12249            1 :                 expr.set_error ();
   12250            1 :                 break;
   12251              :               }
   12252              : 
   12253          671 :             e1 = TYPE_MAIN_VARIANT (e1);
   12254          671 :             e2 = TYPE_MAIN_VARIANT (e2);
   12255              : 
   12256          671 :             expr.value
   12257          671 :               = comptypes (e1, e2) ? integer_one_node : integer_zero_node;
   12258          671 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12259              :           }
   12260          671 :           break;
   12261          356 :         case RID_BUILTIN_TGMATH:
   12262          356 :           {
   12263          356 :             vec<c_expr_t, va_gc> *cexpr_list;
   12264          356 :             location_t close_paren_loc;
   12265              : 
   12266          356 :             c_parser_consume_token (parser);
   12267          356 :             if (!c_parser_get_builtin_args (parser,
   12268              :                                             "__builtin_tgmath",
   12269              :                                             &cexpr_list, false,
   12270              :                                             &close_paren_loc))
   12271              :               {
   12272            0 :                 expr.set_error ();
   12273          327 :                 break;
   12274              :               }
   12275              : 
   12276          356 :             if (vec_safe_length (cexpr_list) < 3)
   12277              :               {
   12278            3 :                 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
   12279            3 :                 expr.set_error ();
   12280            3 :                 break;
   12281              :               }
   12282              : 
   12283              :             unsigned int i;
   12284              :             c_expr_t *p;
   12285         2587 :             FOR_EACH_VEC_ELT (*cexpr_list, i, p)
   12286         2234 :               *p = convert_lvalue_to_rvalue (loc, *p, true, true);
   12287          353 :             unsigned int nargs = check_tgmath_function (&(*cexpr_list)[0], 1);
   12288          353 :             if (nargs == 0)
   12289              :               {
   12290            4 :                 expr.set_error ();
   12291            4 :                 break;
   12292              :               }
   12293          698 :             if (vec_safe_length (cexpr_list) < nargs)
   12294              :               {
   12295            1 :                 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
   12296            1 :                 expr.set_error ();
   12297            1 :                 break;
   12298              :               }
   12299          348 :             unsigned int num_functions = vec_safe_length (cexpr_list) - nargs;
   12300          348 :             if (num_functions < 2)
   12301              :               {
   12302            1 :                 error_at (loc, "too few arguments to %<__builtin_tgmath%>");
   12303            1 :                 expr.set_error ();
   12304            1 :                 break;
   12305              :               }
   12306              : 
   12307              :             /* The first NUM_FUNCTIONS expressions are the function
   12308              :                pointers.  The remaining NARGS expressions are the
   12309              :                arguments that are to be passed to one of those
   12310              :                functions, chosen following <tgmath.h> rules.  */
   12311         1744 :             for (unsigned int j = 1; j < num_functions; j++)
   12312              :               {
   12313         1402 :                 unsigned int this_nargs
   12314         1402 :                   = check_tgmath_function (&(*cexpr_list)[j], j + 1);
   12315         1402 :                 if (this_nargs == 0)
   12316              :                   {
   12317            4 :                     expr.set_error ();
   12318           29 :                     goto out;
   12319              :                   }
   12320         1398 :                 if (this_nargs != nargs)
   12321              :                   {
   12322            1 :                     error_at ((*cexpr_list)[j].get_location (),
   12323              :                               "argument %u of %<__builtin_tgmath%> has "
   12324              :                               "wrong number of arguments", j + 1);
   12325            1 :                     expr.set_error ();
   12326            1 :                     goto out;
   12327              :                   }
   12328              :               }
   12329              : 
   12330              :             /* The functions all have the same number of arguments.
   12331              :                Determine whether arguments and return types vary in
   12332              :                ways permitted for <tgmath.h> functions.  */
   12333              :             /* The first entry in each of these vectors is for the
   12334              :                return type, subsequent entries for parameter
   12335              :                types.  */
   12336          342 :             auto_vec<enum tgmath_parm_kind> parm_kind (nargs + 1);
   12337          342 :             auto_vec<tree> parm_first (nargs + 1);
   12338          342 :             auto_vec<bool> parm_complex (nargs + 1);
   12339          342 :             auto_vec<bool> parm_varies (nargs + 1);
   12340          342 :             tree first_type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[0].value));
   12341          342 :             tree first_ret = TYPE_MAIN_VARIANT (TREE_TYPE (first_type));
   12342          342 :             parm_first.quick_push (first_ret);
   12343          342 :             parm_complex.quick_push (TREE_CODE (first_ret) == COMPLEX_TYPE);
   12344          342 :             parm_varies.quick_push (false);
   12345          342 :             function_args_iterator iter;
   12346          342 :             tree t;
   12347          342 :             unsigned int argpos;
   12348          802 :             FOREACH_FUNCTION_ARGS (first_type, t, iter)
   12349              :               {
   12350          802 :                 if (t == void_type_node)
   12351              :                   break;
   12352          460 :                 parm_first.quick_push (TYPE_MAIN_VARIANT (t));
   12353          460 :                 parm_complex.quick_push (TREE_CODE (t) == COMPLEX_TYPE);
   12354          460 :                 parm_varies.quick_push (false);
   12355              :               }
   12356         1727 :             for (unsigned int j = 1; j < num_functions; j++)
   12357              :               {
   12358         1397 :                 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
   12359         1397 :                 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
   12360         1397 :                 if (ret != parm_first[0])
   12361              :                   {
   12362         1294 :                     parm_varies[0] = true;
   12363         1294 :                     if (!SCALAR_FLOAT_TYPE_P (parm_first[0])
   12364         1294 :                         && !COMPLEX_FLOAT_TYPE_P (parm_first[0]))
   12365              :                       {
   12366            3 :                         error_at ((*cexpr_list)[0].get_location (),
   12367              :                                   "invalid type-generic return type for "
   12368              :                                   "argument %u of %<__builtin_tgmath%>",
   12369              :                                   1);
   12370            3 :                         expr.set_error ();
   12371            3 :                         goto out;
   12372              :                       }
   12373         1291 :                     if (!SCALAR_FLOAT_TYPE_P (ret)
   12374         1291 :                         && !COMPLEX_FLOAT_TYPE_P (ret))
   12375              :                       {
   12376            3 :                         error_at ((*cexpr_list)[j].get_location (),
   12377              :                                   "invalid type-generic return type for "
   12378              :                                   "argument %u of %<__builtin_tgmath%>",
   12379              :                                   j + 1);
   12380            3 :                         expr.set_error ();
   12381            3 :                         goto out;
   12382              :                       }
   12383              :                   }
   12384         1391 :                 if (TREE_CODE (ret) == COMPLEX_TYPE)
   12385          342 :                   parm_complex[0] = true;
   12386         1391 :                 argpos = 1;
   12387         3329 :                 FOREACH_FUNCTION_ARGS (type, t, iter)
   12388              :                   {
   12389         3329 :                     if (t == void_type_node)
   12390              :                       break;
   12391         1944 :                     t = TYPE_MAIN_VARIANT (t);
   12392         1944 :                     if (t != parm_first[argpos])
   12393              :                       {
   12394         1919 :                         parm_varies[argpos] = true;
   12395         1919 :                         if (!SCALAR_FLOAT_TYPE_P (parm_first[argpos])
   12396         1919 :                             && !COMPLEX_FLOAT_TYPE_P (parm_first[argpos]))
   12397              :                           {
   12398            3 :                             error_at ((*cexpr_list)[0].get_location (),
   12399              :                                       "invalid type-generic type for "
   12400              :                                       "argument %u of argument %u of "
   12401              :                                       "%<__builtin_tgmath%>", argpos, 1);
   12402            3 :                             expr.set_error ();
   12403            3 :                             goto out;
   12404              :                           }
   12405         1916 :                         if (!SCALAR_FLOAT_TYPE_P (t)
   12406         1916 :                             && !COMPLEX_FLOAT_TYPE_P (t))
   12407              :                           {
   12408            3 :                             error_at ((*cexpr_list)[j].get_location (),
   12409              :                                       "invalid type-generic type for "
   12410              :                                       "argument %u of argument %u of "
   12411              :                                       "%<__builtin_tgmath%>", argpos, j + 1);
   12412            3 :                             expr.set_error ();
   12413            3 :                             goto out;
   12414              :                           }
   12415              :                       }
   12416         1938 :                     if (TREE_CODE (t) == COMPLEX_TYPE)
   12417          674 :                       parm_complex[argpos] = true;
   12418         1938 :                     argpos++;
   12419              :                   }
   12420              :               }
   12421              :             enum tgmath_parm_kind max_variation = tgmath_fixed;
   12422         1108 :             for (unsigned int j = 0; j <= nargs; j++)
   12423              :               {
   12424          778 :                 enum tgmath_parm_kind this_kind;
   12425          778 :                 if (parm_varies[j])
   12426              :                   {
   12427          731 :                     if (parm_complex[j])
   12428          394 :                       max_variation = this_kind = tgmath_complex;
   12429              :                     else
   12430              :                       {
   12431          337 :                         this_kind = tgmath_real;
   12432          337 :                         if (max_variation != tgmath_complex)
   12433          778 :                           max_variation = tgmath_real;
   12434              :                       }
   12435              :                   }
   12436              :                 else
   12437           47 :                   this_kind = tgmath_fixed;
   12438          778 :                 parm_kind.quick_push (this_kind);
   12439              :               }
   12440          330 :             if (max_variation == tgmath_fixed)
   12441              :               {
   12442            1 :                 error_at (loc, "function arguments of %<__builtin_tgmath%> "
   12443              :                           "all have the same type");
   12444            1 :                 expr.set_error ();
   12445            1 :                 break;
   12446              :               }
   12447              : 
   12448              :             /* Identify a parameter (not the return type) that varies,
   12449              :                including with complex types if any variation includes
   12450              :                complex types; there must be at least one such
   12451              :                parameter.  */
   12452          341 :             unsigned int tgarg = 0;
   12453          341 :             for (unsigned int j = 1; j <= nargs; j++)
   12454          339 :               if (parm_kind[j] == max_variation)
   12455              :                 {
   12456              :                   tgarg = j;
   12457              :                   break;
   12458              :                 }
   12459          329 :             if (tgarg == 0)
   12460              :               {
   12461            2 :                 error_at (loc, "function arguments of %<__builtin_tgmath%> "
   12462              :                           "lack type-generic parameter");
   12463            2 :                 expr.set_error ();
   12464            2 :                 break;
   12465              :               }
   12466              : 
   12467              :             /* Determine the type of the relevant parameter for each
   12468              :                function.  */
   12469          327 :             auto_vec<tree> tg_type (num_functions);
   12470         2035 :             for (unsigned int j = 0; j < num_functions; j++)
   12471              :               {
   12472         1708 :                 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
   12473         1708 :                 argpos = 1;
   12474         1738 :                 FOREACH_FUNCTION_ARGS (type, t, iter)
   12475              :                   {
   12476         1738 :                     if (argpos == tgarg)
   12477              :                       {
   12478         1708 :                         tg_type.quick_push (TYPE_MAIN_VARIANT (t));
   12479         1708 :                         break;
   12480              :                       }
   12481           30 :                     argpos++;
   12482              :                   }
   12483              :               }
   12484              : 
   12485              :             /* Verify that the corresponding types are different for
   12486              :                all the listed functions.  Also determine whether all
   12487              :                the types are complex, whether all the types are
   12488              :                standard or binary, and whether all the types are
   12489              :                decimal.  */
   12490          327 :             bool all_complex = true;
   12491          327 :             bool all_binary = true;
   12492          327 :             bool all_decimal = true;
   12493          327 :             hash_set<tree> tg_types;
   12494         2687 :             FOR_EACH_VEC_ELT (tg_type, i, t)
   12495              :               {
   12496         1708 :                 if (TREE_CODE (t) == COMPLEX_TYPE)
   12497              :                   all_decimal = false;
   12498              :                 else
   12499              :                   {
   12500         1186 :                     all_complex = false;
   12501         1186 :                     if (DECIMAL_FLOAT_TYPE_P (t))
   12502              :                       all_binary = false;
   12503              :                     else
   12504              :                       all_decimal = false;
   12505              :                   }
   12506         1708 :                 if (tg_types.add (t))
   12507              :                   {
   12508            1 :                     error_at ((*cexpr_list)[i].get_location (),
   12509              :                               "duplicate type-generic parameter type for "
   12510              :                               "function argument %u of %<__builtin_tgmath%>",
   12511              :                               i + 1);
   12512            1 :                     expr.set_error ();
   12513            1 :                     goto out;
   12514              :                   }
   12515              :               }
   12516              : 
   12517              :             /* Verify that other parameters and the return type whose
   12518              :                types vary have their types varying in the correct
   12519              :                way.  */
   12520         2029 :             for (unsigned int j = 0; j < num_functions; j++)
   12521              :               {
   12522         1705 :                 tree exp_type = tg_type[j];
   12523         1705 :                 tree exp_real_type = exp_type;
   12524         1705 :                 if (TREE_CODE (exp_type) == COMPLEX_TYPE)
   12525          522 :                   exp_real_type = TREE_TYPE (exp_type);
   12526         1705 :                 tree type = TREE_TYPE (TREE_TYPE ((*cexpr_list)[j].value));
   12527         1705 :                 tree ret = TYPE_MAIN_VARIANT (TREE_TYPE (type));
   12528         2606 :                 if ((parm_kind[0] == tgmath_complex && ret != exp_type)
   12529         2606 :                     || (parm_kind[0] == tgmath_real && ret != exp_real_type))
   12530              :                   {
   12531            1 :                     error_at ((*cexpr_list)[j].get_location (),
   12532              :                               "bad return type for function argument %u "
   12533              :                               "of %<__builtin_tgmath%>", j + 1);
   12534            1 :                     expr.set_error ();
   12535            1 :                     goto out;
   12536              :                   }
   12537         1704 :                 argpos = 1;
   12538         4078 :                 FOREACH_FUNCTION_ARGS (type, t, iter)
   12539              :                   {
   12540         4078 :                     if (t == void_type_node)
   12541              :                       break;
   12542         2375 :                     t = TYPE_MAIN_VARIANT (t);
   12543         2375 :                     if ((parm_kind[argpos] == tgmath_complex
   12544         1787 :                          && t != exp_type)
   12545         4162 :                         || (parm_kind[argpos] == tgmath_real
   12546          558 :                             && t != exp_real_type))
   12547              :                       {
   12548            1 :                         error_at ((*cexpr_list)[j].get_location (),
   12549              :                                   "bad type for argument %u of "
   12550              :                                   "function argument %u of "
   12551              :                                   "%<__builtin_tgmath%>", argpos, j + 1);
   12552            1 :                         expr.set_error ();
   12553            1 :                         goto out;
   12554              :                       }
   12555         2374 :                     argpos++;
   12556              :                   }
   12557              :               }
   12558              : 
   12559              :             /* The functions listed are a valid set of functions for a
   12560              :                <tgmath.h> macro to select between.  Identify the
   12561              :                matching function, if any.  First, the argument types
   12562              :                must be combined following <tgmath.h> rules.  Integer
   12563              :                types are treated as _Decimal64 if any type-generic
   12564              :                argument is decimal, or if the only alternatives for
   12565              :                type-generic arguments are of decimal types, and are
   12566              :                otherwise treated as _Float32x (or _Complex _Float32x
   12567              :                for complex integer types) if any type-generic argument
   12568              :                has _FloatNx type, otherwise as double (or _Complex
   12569              :                double for complex integer types).  After that
   12570              :                adjustment, types are combined following the usual
   12571              :                arithmetic conversions.  If the function only accepts
   12572              :                complex arguments, a complex type is produced.  */
   12573              :             bool arg_complex = all_complex;
   12574              :             bool arg_binary = all_binary;
   12575              :             bool arg_int_decimal = all_decimal;
   12576              :             bool arg_int_floatnx = false;
   12577              :             bool arg_int_decimalx = false;
   12578          756 :             for (unsigned int j = 1; j <= nargs; j++)
   12579              :               {
   12580          441 :                 if (parm_kind[j] == tgmath_fixed)
   12581           10 :                   continue;
   12582          431 :                 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
   12583          431 :                 tree type = TREE_TYPE (ce->value);
   12584          431 :                 if (!INTEGRAL_TYPE_P (type)
   12585          431 :                     && !SCALAR_FLOAT_TYPE_P (type)
   12586           89 :                     && TREE_CODE (type) != COMPLEX_TYPE)
   12587              :                   {
   12588            1 :                     error_at (ce->get_location (),
   12589              :                               "invalid type of argument %u of type-generic "
   12590              :                               "function", j);
   12591            1 :                     expr.set_error ();
   12592            1 :                     goto out;
   12593              :                   }
   12594          430 :                 if (DECIMAL_FLOAT_TYPE_P (type))
   12595              :                   {
   12596           68 :                     arg_int_decimal = true;
   12597           68 :                     if (all_complex)
   12598              :                       {
   12599            1 :                         error_at (ce->get_location (),
   12600              :                                   "decimal floating-point argument %u to "
   12601              :                                   "complex-only type-generic function", j);
   12602            1 :                         expr.set_error ();
   12603            1 :                         goto out;
   12604              :                       }
   12605           67 :                     else if (all_binary)
   12606              :                       {
   12607            1 :                         error_at (ce->get_location (),
   12608              :                                   "decimal floating-point argument %u to "
   12609              :                                   "binary-only type-generic function", j);
   12610            1 :                         expr.set_error ();
   12611            1 :                         goto out;
   12612              :                       }
   12613           66 :                     else if (arg_complex)
   12614              :                       {
   12615            1 :                         error_at (ce->get_location (),
   12616              :                                   "both complex and decimal floating-point "
   12617              :                                   "arguments to type-generic function");
   12618            1 :                         expr.set_error ();
   12619            1 :                         goto out;
   12620              :                       }
   12621           65 :                     else if (arg_binary)
   12622              :                       {
   12623            1 :                         error_at (ce->get_location (),
   12624              :                                   "both binary and decimal floating-point "
   12625              :                                   "arguments to type-generic function");
   12626            1 :                         expr.set_error ();
   12627            1 :                         goto out;
   12628              :                       }
   12629              :                   }
   12630          362 :                 else if (TREE_CODE (type) == COMPLEX_TYPE)
   12631              :                   {
   12632           88 :                     arg_complex = true;
   12633           88 :                     if (COMPLEX_FLOAT_TYPE_P (type))
   12634              :                       arg_binary = true;
   12635           88 :                     if (all_decimal)
   12636              :                       {
   12637            1 :                         error_at (ce->get_location (),
   12638              :                                   "complex argument %u to "
   12639              :                                   "decimal-only type-generic function", j);
   12640            1 :                         expr.set_error ();
   12641            1 :                         goto out;
   12642              :                       }
   12643           87 :                     else if (arg_int_decimal)
   12644              :                       {
   12645            1 :                         error_at (ce->get_location (),
   12646              :                                   "both complex and decimal floating-point "
   12647              :                                   "arguments to type-generic function");
   12648            1 :                         expr.set_error ();
   12649            1 :                         goto out;
   12650              :                       }
   12651              :                   }
   12652          274 :                 else if (SCALAR_FLOAT_TYPE_P (type))
   12653              :                   {
   12654          180 :                     arg_binary = true;
   12655          180 :                     if (all_decimal)
   12656              :                       {
   12657            1 :                         error_at (ce->get_location (),
   12658              :                                   "binary argument %u to "
   12659              :                                   "decimal-only type-generic function", j);
   12660            1 :                         expr.set_error ();
   12661            1 :                         goto out;
   12662              :                       }
   12663          179 :                     else if (arg_int_decimal)
   12664              :                       {
   12665            1 :                         error_at (ce->get_location (),
   12666              :                                   "both binary and decimal floating-point "
   12667              :                                   "arguments to type-generic function");
   12668            1 :                         expr.set_error ();
   12669            1 :                         goto out;
   12670              :                       }
   12671              :                   }
   12672          422 :                 tree rtype = TYPE_MAIN_VARIANT (type);
   12673          422 :                 if (TREE_CODE (rtype) == COMPLEX_TYPE)
   12674           86 :                   rtype = TREE_TYPE (rtype);
   12675          422 :                 if (SCALAR_FLOAT_TYPE_P (rtype))
   12676         1208 :                   for (unsigned int j = 0; j < NUM_FLOATNX_TYPES; j++)
   12677          908 :                     if (rtype == FLOATNX_TYPE_NODE (j))
   12678              :                       {
   12679              :                         arg_int_floatnx = true;
   12680              :                         break;
   12681              :                       }
   12682          422 :                 if (rtype == dfloat64x_type_node)
   12683            0 :                   arg_int_decimalx = true;
   12684              :               }
   12685              :             tree arg_real = NULL_TREE;
   12686          743 :             for (unsigned int j = 1; j <= nargs; j++)
   12687              :               {
   12688          428 :                 if (parm_kind[j] == tgmath_fixed)
   12689           10 :                   continue;
   12690          418 :                 c_expr_t *ce = &(*cexpr_list)[num_functions + j - 1];
   12691          418 :                 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ce->value));
   12692          418 :                 if (TREE_CODE (type) == COMPLEX_TYPE)
   12693           85 :                   type = TREE_TYPE (type);
   12694          418 :                 if (INTEGRAL_TYPE_P (type))
   12695          114 :                   type = (arg_int_decimalx
   12696          114 :                           ? dfloat64x_type_node
   12697              :                           : arg_int_floatnx
   12698          114 :                           ? float32x_type_node
   12699              :                           : arg_int_decimal
   12700          106 :                           ? dfloat64_type_node
   12701              :                           : double_type_node);
   12702          418 :                 if (arg_real == NULL_TREE)
   12703              :                   arg_real = type;
   12704              :                 else
   12705          103 :                   arg_real = common_type (arg_real, type);
   12706          418 :                 if (arg_real == error_mark_node)
   12707              :                   {
   12708            0 :                     expr.set_error ();
   12709            0 :                     goto out;
   12710              :                   }
   12711              :               }
   12712          315 :             tree arg_type = (arg_complex
   12713          315 :                              ? build_complex_type (arg_real)
   12714              :                              : arg_real);
   12715              : 
   12716              :             /* Look for a function to call with type-generic parameter
   12717              :                type ARG_TYPE.  */
   12718          315 :             c_expr_t *fn = NULL;
   12719          976 :             for (unsigned int j = 0; j < num_functions; j++)
   12720              :               {
   12721          970 :                 if (tg_type[j] == arg_type)
   12722              :                   {
   12723          309 :                     fn = &(*cexpr_list)[j];
   12724          309 :                     break;
   12725              :                   }
   12726              :               }
   12727          315 :             if (fn == NULL
   12728            6 :                 && parm_kind[0] == tgmath_fixed
   12729            4 :                 && SCALAR_FLOAT_TYPE_P (parm_first[0]))
   12730              :               {
   12731              :                 /* Presume this is a macro that rounds its result to a
   12732              :                    narrower type, and look for the first function with
   12733              :                    at least the range and precision of the argument
   12734              :                    type.  */
   12735            4 :                 for (unsigned int j = 0; j < num_functions; j++)
   12736              :                   {
   12737            8 :                     if (arg_complex
   12738            4 :                         != (TREE_CODE (tg_type[j]) == COMPLEX_TYPE))
   12739            0 :                       continue;
   12740            4 :                     tree real_tg_type = (arg_complex
   12741            4 :                                          ? TREE_TYPE (tg_type[j])
   12742            0 :                                          : tg_type[j]);
   12743            8 :                     if (DECIMAL_FLOAT_TYPE_P (arg_real)
   12744            4 :                         != DECIMAL_FLOAT_TYPE_P (real_tg_type))
   12745            0 :                       continue;
   12746            4 :                     scalar_float_mode arg_mode
   12747            4 :                       = SCALAR_FLOAT_TYPE_MODE (arg_real);
   12748            4 :                     scalar_float_mode tg_mode
   12749            4 :                       = SCALAR_FLOAT_TYPE_MODE (real_tg_type);
   12750            4 :                     const real_format *arg_fmt = REAL_MODE_FORMAT (arg_mode);
   12751            4 :                     const real_format *tg_fmt = REAL_MODE_FORMAT (tg_mode);
   12752            4 :                     if (arg_fmt->b == tg_fmt->b
   12753            4 :                         && arg_fmt->p <= tg_fmt->p
   12754            4 :                         && arg_fmt->emax <= tg_fmt->emax
   12755            4 :                         && (arg_fmt->emin - arg_fmt->p
   12756            4 :                             >= tg_fmt->emin - tg_fmt->p))
   12757              :                       {
   12758            4 :                         fn = &(*cexpr_list)[j];
   12759            4 :                         break;
   12760              :                       }
   12761              :                   }
   12762              :               }
   12763          315 :             if (fn == NULL)
   12764              :               {
   12765            2 :                 error_at (loc, "no matching function for type-generic call");
   12766            2 :                 expr.set_error ();
   12767            2 :                 break;
   12768              :               }
   12769              : 
   12770              :             /* Construct a call to FN.  */
   12771          313 :             vec<tree, va_gc> *args;
   12772          313 :             vec_alloc (args, nargs);
   12773          313 :             vec<tree, va_gc> *origtypes;
   12774          313 :             vec_alloc (origtypes, nargs);
   12775          313 :             auto_vec<location_t> arg_loc (nargs);
   12776          739 :             for (unsigned int j = 0; j < nargs; j++)
   12777              :               {
   12778          426 :                 c_expr_t *ce = &(*cexpr_list)[num_functions + j];
   12779          426 :                 args->quick_push (ce->value);
   12780          426 :                 arg_loc.quick_push (ce->get_location ());
   12781          426 :                 origtypes->quick_push (ce->original_type);
   12782              :               }
   12783          313 :             expr.value = c_build_function_call_vec (loc, arg_loc, fn->value,
   12784              :                                                     args, origtypes);
   12785          313 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12786          313 :             break;
   12787          982 :           }
   12788           22 :         case RID_BUILTIN_CALL_WITH_STATIC_CHAIN:
   12789           22 :           {
   12790           22 :             vec<c_expr_t, va_gc> *cexpr_list;
   12791           22 :             c_expr_t *e2_p;
   12792           22 :             tree chain_value;
   12793           22 :             location_t close_paren_loc;
   12794              : 
   12795           22 :             c_parser_consume_token (parser);
   12796           22 :             if (!c_parser_get_builtin_args (parser,
   12797              :                                             "__builtin_call_with_static_chain",
   12798              :                                             &cexpr_list, false,
   12799              :                                             &close_paren_loc))
   12800              :               {
   12801            0 :                 expr.set_error ();
   12802            0 :                 break;
   12803              :               }
   12804           22 :             if (vec_safe_length (cexpr_list) != 2)
   12805              :               {
   12806            0 :                 error_at (loc, "wrong number of arguments to "
   12807              :                                "%<__builtin_call_with_static_chain%>");
   12808            0 :                 expr.set_error ();
   12809            0 :                 break;
   12810              :               }
   12811              : 
   12812           22 :             expr = (*cexpr_list)[0];
   12813           22 :             e2_p = &(*cexpr_list)[1];
   12814           22 :             *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
   12815           22 :             chain_value = e2_p->value;
   12816           22 :             mark_exp_read (chain_value);
   12817              : 
   12818           22 :             if (TREE_CODE (expr.value) != CALL_EXPR)
   12819            3 :               error_at (loc, "first argument to "
   12820              :                         "%<__builtin_call_with_static_chain%> "
   12821              :                         "must be a call expression");
   12822           19 :             else if (TREE_CODE (TREE_TYPE (chain_value)) != POINTER_TYPE)
   12823            1 :               error_at (loc, "second argument to "
   12824              :                         "%<__builtin_call_with_static_chain%> "
   12825              :                         "must be a pointer type");
   12826              :             else
   12827           18 :               CALL_EXPR_STATIC_CHAIN (expr.value) = chain_value;
   12828           22 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12829           22 :             break;
   12830              :           }
   12831        12078 :         case RID_BUILTIN_COMPLEX:
   12832        12078 :           {
   12833        12078 :             vec<c_expr_t, va_gc> *cexpr_list;
   12834        12078 :             c_expr_t *e1_p, *e2_p;
   12835        12078 :             location_t close_paren_loc;
   12836              : 
   12837        12078 :             c_parser_consume_token (parser);
   12838        12078 :             if (!c_parser_get_builtin_args (parser,
   12839              :                                             "__builtin_complex",
   12840              :                                             &cexpr_list, false,
   12841              :                                             &close_paren_loc))
   12842              :               {
   12843            1 :                 expr.set_error ();
   12844            1 :                 break;
   12845              :               }
   12846              : 
   12847        12077 :             if (vec_safe_length (cexpr_list) != 2)
   12848              :               {
   12849            2 :                 error_at (loc, "wrong number of arguments to "
   12850              :                                "%<__builtin_complex%>");
   12851            2 :                 expr.set_error ();
   12852            2 :                 break;
   12853              :               }
   12854              : 
   12855        12075 :             e1_p = &(*cexpr_list)[0];
   12856        12075 :             e2_p = &(*cexpr_list)[1];
   12857              : 
   12858        12075 :             *e1_p = convert_lvalue_to_rvalue (loc, *e1_p, true, true);
   12859        12075 :             if (TREE_CODE (e1_p->value) == EXCESS_PRECISION_EXPR)
   12860           56 :               e1_p->value = convert (TREE_TYPE (e1_p->value),
   12861           56 :                                      TREE_OPERAND (e1_p->value, 0));
   12862        12075 :             *e2_p = convert_lvalue_to_rvalue (loc, *e2_p, true, true);
   12863        12075 :             if (TREE_CODE (e2_p->value) == EXCESS_PRECISION_EXPR)
   12864           56 :               e2_p->value = convert (TREE_TYPE (e2_p->value),
   12865           56 :                                      TREE_OPERAND (e2_p->value, 0));
   12866        12075 :             if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
   12867        12074 :                 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e1_p->value))
   12868        12073 :                 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (e2_p->value))
   12869        24147 :                 || DECIMAL_FLOAT_TYPE_P (TREE_TYPE (e2_p->value)))
   12870              :               {
   12871            3 :                 error_at (loc, "%<__builtin_complex%> operand "
   12872              :                           "not of real binary floating-point type");
   12873            3 :                 expr.set_error ();
   12874            3 :                 break;
   12875              :               }
   12876        12072 :             if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
   12877        12072 :                 != TYPE_MAIN_VARIANT (TREE_TYPE (e2_p->value)))
   12878              :               {
   12879            1 :                 error_at (loc,
   12880              :                           "%<__builtin_complex%> operands of different types");
   12881            1 :                 expr.set_error ();
   12882            1 :                 break;
   12883              :               }
   12884        12071 :             pedwarn_c90 (loc, OPT_Wpedantic,
   12885              :                          "ISO C90 does not support complex types");
   12886        12071 :             expr.value = build2_loc (loc, COMPLEX_EXPR,
   12887              :                                      build_complex_type
   12888        12071 :                                      (TYPE_MAIN_VARIANT
   12889              :                                       (TREE_TYPE (e1_p->value))),
   12890              :                                      e1_p->value, e2_p->value);
   12891        12071 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12892        12071 :             break;
   12893              :           }
   12894           88 :         case RID_BUILTIN_COUNTED_BY_REF:
   12895           88 :           {
   12896           88 :             vec<c_expr_t, va_gc> *cexpr_list;
   12897           88 :             c_expr_t *e_p;
   12898           88 :             location_t close_paren_loc;
   12899              : 
   12900           88 :             c_parser_consume_token (parser);
   12901           88 :             if (!c_parser_get_builtin_args (parser,
   12902              :                                             "__builtin_counted_by_ref",
   12903              :                                             &cexpr_list, false,
   12904              :                                             &close_paren_loc))
   12905              :               {
   12906            0 :                 expr.set_error ();
   12907            0 :                 break;
   12908              :               }
   12909           88 :             if (vec_safe_length (cexpr_list) != 1)
   12910              :               {
   12911            4 :                 error_at (loc, "wrong number of arguments to "
   12912              :                                "%<__builtin_counted_by_ref%>");
   12913            4 :                 expr.set_error ();
   12914            4 :                 break;
   12915              :               }
   12916              : 
   12917           84 :             e_p = &(*cexpr_list)[0];
   12918           84 :             tree ref = e_p->value;
   12919              : 
   12920           84 :             if (TREE_CODE (TREE_TYPE (ref)) != ARRAY_TYPE
   12921           84 :                  && TREE_CODE (TREE_TYPE (ref)) != POINTER_TYPE)
   12922              :               {
   12923            2 :                 error_at (loc, "the argument to %<__builtin_counted_by_ref%>"
   12924              :                                 " must be an array or pointer");
   12925            2 :                 expr.set_error ();
   12926            2 :                 break;
   12927              :               }
   12928              : 
   12929           82 :             if (TREE_CODE (ref) != COMPONENT_REF)
   12930              :               {
   12931            2 :                 error_at (loc, "the argument to %<__builtin_counted_by_ref%>"
   12932              :                                 " must be a field of a structure");
   12933            2 :                 expr.set_error ();
   12934            2 :                 break;
   12935              :               }
   12936              : 
   12937              :             /* If the ref is inside TYPEOF or ALIGNOF, the call to
   12938              :                .ACCESS_WITH_SIZE was not generated by the routine
   12939              :                build_component_ref by default, we should generate it here.  */
   12940           80 :             if (TREE_CODE (ref) == COMPONENT_REF)
   12941           80 :               ref = handle_counted_by_for_component_ref (loc, ref);
   12942              : 
   12943           80 :             if (has_counted_by_object (ref))
   12944           50 :               expr.value = get_counted_by_ref (ref);
   12945              :             else
   12946           30 :               expr.value = null_pointer_node;
   12947              : 
   12948           80 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12949           80 :             break;
   12950              :           }
   12951       469676 :         case RID_BUILTIN_SHUFFLE:
   12952       469676 :           {
   12953       469676 :             vec<c_expr_t, va_gc> *cexpr_list;
   12954       469676 :             unsigned int i;
   12955       469676 :             c_expr_t *p;
   12956       469676 :             location_t close_paren_loc;
   12957              : 
   12958       469676 :             c_parser_consume_token (parser);
   12959       469676 :             if (!c_parser_get_builtin_args (parser,
   12960              :                                             "__builtin_shuffle",
   12961              :                                             &cexpr_list, false,
   12962              :                                             &close_paren_loc))
   12963              :               {
   12964            0 :                 expr.set_error ();
   12965            0 :                 break;
   12966              :               }
   12967              : 
   12968      1450519 :             FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
   12969       980843 :               *p = convert_lvalue_to_rvalue (loc, *p, true, true);
   12970              : 
   12971       469676 :             if (vec_safe_length (cexpr_list) == 2)
   12972       428185 :               expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
   12973              :                                                   NULL_TREE,
   12974       428185 :                                                   (*cexpr_list)[1].value);
   12975              : 
   12976        41491 :             else if (vec_safe_length (cexpr_list) == 3)
   12977        41491 :               expr.value = c_build_vec_perm_expr (loc, (*cexpr_list)[0].value,
   12978        41491 :                                                   (*cexpr_list)[1].value,
   12979        41491 :                                                   (*cexpr_list)[2].value);
   12980              :             else
   12981              :               {
   12982            0 :                 error_at (loc, "wrong number of arguments to "
   12983              :                                "%<__builtin_shuffle%>");
   12984            0 :                 expr.set_error ();
   12985              :               }
   12986       469676 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   12987       469676 :             break;
   12988              :           }
   12989      1077379 :         case RID_BUILTIN_SHUFFLEVECTOR:
   12990      1077379 :           {
   12991      1077379 :             vec<c_expr_t, va_gc> *cexpr_list;
   12992      1077379 :             unsigned int i;
   12993      1077379 :             c_expr_t *p;
   12994      1077379 :             location_t close_paren_loc;
   12995              : 
   12996      1077379 :             c_parser_consume_token (parser);
   12997      1077379 :             if (!c_parser_get_builtin_args (parser,
   12998              :                                             "__builtin_shufflevector",
   12999              :                                             &cexpr_list, false,
   13000              :                                             &close_paren_loc))
   13001              :               {
   13002            0 :                 expr.set_error ();
   13003            0 :                 break;
   13004              :               }
   13005              : 
   13006     16776957 :             FOR_EACH_VEC_SAFE_ELT (cexpr_list, i, p)
   13007     15699578 :               *p = convert_lvalue_to_rvalue (loc, *p, true, true);
   13008              : 
   13009      1077379 :             if (vec_safe_length (cexpr_list) < 3)
   13010              :               {
   13011            0 :                 error_at (loc, "wrong number of arguments to "
   13012              :                                "%<__builtin_shuffle%>");
   13013            0 :                 expr.set_error ();
   13014              :               }
   13015              :             else
   13016              :               {
   13017      1077379 :                 auto_vec<tree, 16> mask;
   13018     14622199 :                 for (i = 2; i < cexpr_list->length (); ++i)
   13019     13544820 :                   mask.safe_push ((*cexpr_list)[i].value);
   13020      1077379 :                 expr.value = c_build_shufflevector (loc, (*cexpr_list)[0].value,
   13021      1077379 :                                                     (*cexpr_list)[1].value,
   13022              :                                                     mask);
   13023      1077379 :               }
   13024      1077379 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   13025      1077379 :             break;
   13026              :           }
   13027          396 :         case RID_BUILTIN_CONVERTVECTOR:
   13028          396 :           {
   13029          396 :             location_t start_loc = loc;
   13030          396 :             c_parser_consume_token (parser);
   13031          396 :             matching_parens parens;
   13032          396 :             if (!parens.require_open (parser))
   13033              :               {
   13034            0 :                 expr.set_error ();
   13035            2 :                 break;
   13036              :               }
   13037          396 :             e1 = c_parser_expr_no_commas (parser, NULL);
   13038          396 :             mark_exp_read (e1.value);
   13039          396 :             if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   13040              :               {
   13041            2 :                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   13042            2 :                 expr.set_error ();
   13043            2 :                 break;
   13044              :               }
   13045          394 :             loc = c_parser_peek_token (parser)->location;
   13046          394 :             t1 = c_parser_type_name (parser);
   13047          394 :             location_t end_loc = c_parser_peek_token (parser)->get_finish ();
   13048          394 :             c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   13049              :                                        "expected %<)%>");
   13050          394 :             if (t1 == NULL)
   13051            1 :               expr.set_error ();
   13052              :             else
   13053              :               {
   13054          393 :                 tree type_expr = NULL_TREE;
   13055          393 :                 expr.value = c_build_vec_convert (start_loc, e1.value, loc,
   13056              :                                                   groktypename (t1, &type_expr,
   13057              :                                                                 NULL));
   13058          393 :                 set_c_expr_source_range (&expr, start_loc, end_loc);
   13059              :               }
   13060              :           }
   13061          394 :           break;
   13062           10 :         case RID_BUILTIN_ASSOC_BARRIER:
   13063           10 :           {
   13064           10 :             location_t start_loc = loc;
   13065           10 :             c_parser_consume_token (parser);
   13066           10 :             matching_parens parens;
   13067           10 :             if (!parens.require_open (parser))
   13068              :               {
   13069            0 :                 expr.set_error ();
   13070            0 :                 break;
   13071              :               }
   13072           10 :             e1 = c_parser_expr_no_commas (parser, NULL);
   13073           10 :             mark_exp_read (e1.value);
   13074           10 :             location_t end_loc = c_parser_peek_token (parser)->get_finish ();
   13075           10 :             parens.skip_until_found_close (parser);
   13076           10 :             expr = parser_build_unary_op (loc, PAREN_EXPR, e1);
   13077           10 :             set_c_expr_source_range (&expr, start_loc, end_loc);
   13078              :           }
   13079           10 :           break;
   13080         1073 :         case RID_BUILTIN_STDC:
   13081         1073 :           {
   13082         1073 :             vec<c_expr_t, va_gc> *cexpr_list;
   13083         1073 :             c_expr_t *arg_p;
   13084         1073 :             location_t close_paren_loc;
   13085         1073 :             enum c_builtin_stdc {
   13086              :               C_BUILTIN_STDC_BIT_CEIL,
   13087              :               C_BUILTIN_STDC_BIT_FLOOR,
   13088              :               C_BUILTIN_STDC_BIT_WIDTH,
   13089              :               C_BUILTIN_STDC_COUNT_ONES,
   13090              :               C_BUILTIN_STDC_COUNT_ZEROS,
   13091              :               C_BUILTIN_STDC_FIRST_LEADING_ONE,
   13092              :               C_BUILTIN_STDC_FIRST_LEADING_ZERO,
   13093              :               C_BUILTIN_STDC_FIRST_TRAILING_ONE,
   13094              :               C_BUILTIN_STDC_FIRST_TRAILING_ZERO,
   13095              :               C_BUILTIN_STDC_HAS_SINGLE_BIT,
   13096              :               C_BUILTIN_STDC_LEADING_ONES,
   13097              :               C_BUILTIN_STDC_LEADING_ZEROS,
   13098              :               C_BUILTIN_STDC_ROTATE_LEFT,
   13099              :               C_BUILTIN_STDC_ROTATE_RIGHT,
   13100              :               C_BUILTIN_STDC_TRAILING_ONES,
   13101              :               C_BUILTIN_STDC_TRAILING_ZEROS,
   13102              :               C_BUILTIN_STDC_MAX
   13103         1073 :             } stdc_rid = C_BUILTIN_STDC_MAX;
   13104         1073 :             const char *name
   13105         1073 :               = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   13106         1073 :             unsigned num_args = 1;
   13107         1073 :             switch (name[sizeof ("__builtin_stdc_") - 1])
   13108              :               {
   13109          202 :               case 'b':
   13110          202 :                 switch (name[sizeof ("__builtin_stdc_bit_") - 1])
   13111              :                   {
   13112              :                   case 'c':
   13113              :                     stdc_rid = C_BUILTIN_STDC_BIT_CEIL;
   13114              :                     break;
   13115           64 :                   case 'f':
   13116           64 :                     stdc_rid = C_BUILTIN_STDC_BIT_FLOOR;
   13117           64 :                     break;
   13118           58 :                   default:
   13119           58 :                     stdc_rid = C_BUILTIN_STDC_BIT_WIDTH;
   13120           58 :                     break;
   13121              :                   }
   13122              :                 break;
   13123          106 :               case 'c':
   13124          106 :                 if (name[sizeof ("__builtin_stdc_count_") - 1] == 'o')
   13125              :                   stdc_rid = C_BUILTIN_STDC_COUNT_ONES;
   13126              :                 else
   13127           53 :                   stdc_rid = C_BUILTIN_STDC_COUNT_ZEROS;
   13128              :                 break;
   13129          215 :               case 'f':
   13130          215 :                 switch (name[sizeof ("__builtin_stdc_first_trailing_") - 1])
   13131              :                   {
   13132              :                   case 'n':
   13133              :                     stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ONE;
   13134              :                     break;
   13135              :                   case 'e':
   13136              :                     stdc_rid = C_BUILTIN_STDC_FIRST_LEADING_ZERO;
   13137              :                     break;
   13138              :                   case 'o':
   13139              :                     stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ONE;
   13140              :                     break;
   13141              :                   default:
   13142              :                     stdc_rid = C_BUILTIN_STDC_FIRST_TRAILING_ZERO;
   13143              :                     break;
   13144              :                   }
   13145              :                 break;
   13146              :               case 'h':
   13147              :                 stdc_rid = C_BUILTIN_STDC_HAS_SINGLE_BIT;
   13148              :                 break;
   13149          106 :               case 'l':
   13150          106 :                 if (name[sizeof ("__builtin_stdc_leading_") - 1] == 'o')
   13151              :                   stdc_rid = C_BUILTIN_STDC_LEADING_ONES;
   13152              :                 else
   13153           53 :                   stdc_rid = C_BUILTIN_STDC_LEADING_ZEROS;
   13154              :                 break;
   13155          285 :               case 'r':
   13156          285 :                 if (name[sizeof ("__builtin_stdc_rotate_") - 1] == 'l')
   13157              :                   stdc_rid = C_BUILTIN_STDC_ROTATE_LEFT;
   13158              :                 else
   13159          138 :                   stdc_rid = C_BUILTIN_STDC_ROTATE_RIGHT;
   13160              :                 num_args = 2;
   13161              :                 break;
   13162          106 :               case 't':
   13163          106 :                 if (name[sizeof ("__builtin_stdc_trailing_") - 1] == 'o')
   13164              :                   stdc_rid = C_BUILTIN_STDC_TRAILING_ONES;
   13165              :                 else
   13166           53 :                   stdc_rid = C_BUILTIN_STDC_TRAILING_ZEROS;
   13167              :                 break;
   13168              :               }
   13169          281 :             gcc_checking_assert (stdc_rid != C_BUILTIN_STDC_MAX);
   13170              : 
   13171         1073 :             c_parser_consume_token (parser);
   13172         1073 :             if (!c_parser_get_builtin_args (parser, name,
   13173              :                                             &cexpr_list, false,
   13174              :                                             &close_paren_loc))
   13175              :               {
   13176            0 :                 expr.set_error ();
   13177            0 :                 break;
   13178              :               }
   13179              : 
   13180         2130 :             if (vec_safe_length (cexpr_list) != num_args)
   13181              :               {
   13182           34 :                 error_at (loc, "wrong number of arguments to %qs", name);
   13183           34 :                 expr.set_error ();
   13184           34 :                 break;
   13185              :               }
   13186              : 
   13187         1039 :             arg_p = &(*cexpr_list)[0];
   13188         1039 :             *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
   13189         1039 :             if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
   13190              :               {
   13191           80 :                 error_at (loc, "%qs operand not an integral type", name);
   13192           80 :                 expr.set_error ();
   13193           80 :                 break;
   13194              :               }
   13195          959 :             if (TREE_CODE (TREE_TYPE (arg_p->value)) == ENUMERAL_TYPE)
   13196              :               {
   13197           16 :                 error_at (loc, "argument %u in call to function "
   13198              :                           "%qs has enumerated type", 1, name);
   13199           16 :                 expr.set_error ();
   13200           16 :                 break;
   13201              :               }
   13202          943 :             if (TREE_CODE (TREE_TYPE (arg_p->value)) == BOOLEAN_TYPE)
   13203              :               {
   13204           16 :                 error_at (loc, "argument %u in call to function "
   13205              :                           "%qs has boolean type", 1, name);
   13206           16 :                 expr.set_error ();
   13207           16 :                 break;
   13208              :               }
   13209          927 :             if (!TYPE_UNSIGNED (TREE_TYPE (arg_p->value)))
   13210              :               {
   13211           16 :                 error_at (loc, "argument 1 in call to function "
   13212              :                           "%qs has signed type", name);
   13213           16 :                 expr.set_error ();
   13214           16 :                 break;
   13215              :               }
   13216          911 :             if (TYPE_MAIN_VARIANT (TREE_TYPE (arg_p->value))
   13217          911 :                 == char_type_node)
   13218              :               {
   13219           16 :                 error_at (loc, "argument 1 in call to function "
   13220              :                           "%qs has %<char%> type", name);
   13221           16 :                 expr.set_error ();
   13222           16 :                 break;
   13223              :               }
   13224          895 :             tree arg = arg_p->value;
   13225          895 :             tree type = TYPE_MAIN_VARIANT (TREE_TYPE (arg));
   13226              :             /* Expand:
   13227              :                __builtin_stdc_leading_zeros (arg) as
   13228              :                  (unsigned int) __builtin_clzg (arg, prec)
   13229              :                __builtin_stdc_leading_ones (arg) as
   13230              :                  (unsigned int) __builtin_clzg ((type) ~arg, prec)
   13231              :                __builtin_stdc_trailing_zeros (arg) as
   13232              :                  (unsigned int) __builtin_ctzg (arg, prec)
   13233              :                __builtin_stdc_trailing_ones (arg) as
   13234              :                  (unsigned int) __builtin_ctzg ((type) ~arg, prec)
   13235              :                __builtin_stdc_first_leading_zero (arg) as
   13236              :                  __builtin_clzg ((type) ~arg, -1) + 1U
   13237              :                __builtin_stdc_first_leading_one (arg) as
   13238              :                  __builtin_clzg (arg, -1) + 1U
   13239              :                __builtin_stdc_first_trailing_zero (arg) as
   13240              :                  __builtin_ctzg ((type) ~arg, -1) + 1U
   13241              :                __builtin_stdc_first_trailing_one (arg) as
   13242              :                  __builtin_ctzg (arg, -1) + 1U
   13243              :                __builtin_stdc_count_zeros (arg) as
   13244              :                  (unsigned int) __builtin_popcountg ((type) ~arg)
   13245              :                __builtin_stdc_count_ones (arg) as
   13246              :                  (unsigned int) __builtin_popcountg (arg)
   13247              :                __builtin_stdc_has_single_bit (arg) as
   13248              :                  (_Bool) (__builtin_popcountg (arg) == 1)
   13249              :                __builtin_stdc_bit_width (arg) as
   13250              :                  (unsigned int) (prec - __builtin_clzg (arg, prec))
   13251              :                __builtin_stdc_bit_floor (arg) as
   13252              :                  arg == 0 ? (type) 0
   13253              :                           : (type) 1 << (prec - 1 - __builtin_clzg (arg))
   13254              :                __builtin_stdc_bit_ceil (arg) as
   13255              :                  arg <= 1 ? (type) 1
   13256              :                           : (type) 2 << (prec - 1 - __builtin_clzg (arg - 1))
   13257              :                without evaluating arg multiple times, type being
   13258              :                __typeof (arg) and prec __builtin_popcountg ((type) ~0)).  */
   13259          895 :             int prec = TYPE_PRECISION (type);
   13260          895 :             if (num_args == 2)
   13261              :               {
   13262              :                 /* Expand:
   13263              :                    __builtin_stdc_rotate_left (arg1, arg2) as
   13264              :                    arg1 r<< (arg2 % prec)
   13265              :                    __builtin_stdc_rotate_right (arg1, arg2) as
   13266              :                    arg1 r>> (arg2 % prec).  */
   13267          261 :                 arg_p = &(*cexpr_list)[1];
   13268          261 :                 *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
   13269          261 :                 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
   13270              :                   {
   13271           10 :                     error_at (loc, "%qs operand not an integral type", name);
   13272           10 :                     expr.set_error ();
   13273           10 :                     break;
   13274              :                   }
   13275          251 :                 if (TREE_CODE (TREE_TYPE (arg_p->value)) == ENUMERAL_TYPE)
   13276              :                   {
   13277            2 :                     error_at (loc, "argument %u in call to function "
   13278              :                                    "%qs has enumerated type", 2, name);
   13279            2 :                     expr.set_error ();
   13280            2 :                     break;
   13281              :                   }
   13282          249 :                 tree arg1 = save_expr (arg);
   13283          249 :                 tree arg2 = save_expr (arg_p->value);
   13284          249 :                 tree_code code;
   13285          249 :                 if (stdc_rid == C_BUILTIN_STDC_ROTATE_LEFT)
   13286              :                   code = LROTATE_EXPR;
   13287              :                 else
   13288          120 :                   code = RROTATE_EXPR;
   13289              : 
   13290          249 :                 if (TREE_CODE (arg2) == INTEGER_CST
   13291          249 :                     && tree_int_cst_sgn (arg2) < 0)
   13292           20 :                   warning_at (loc, OPT_Wshift_count_negative,
   13293              :                               "rotate count is negative");
   13294              : 
   13295          249 :                 tree instrument_expr = NULL_TREE;
   13296          249 :                 if (sanitize_flags_p (SANITIZE_SHIFT))
   13297           28 :                   instrument_expr = ubsan_instrument_shift (loc, code,
   13298              :                                                             arg1, arg2);
   13299              : 
   13300              :                 /* Promote arg2 to unsigned just so that we don't
   13301              :                    need to deal with arg2 type not being able to represent
   13302              :                    prec.  In the end gimplification uses unsigned int
   13303              :                    for all shifts/rotates anyway.  */
   13304          249 :                 if (TYPE_PRECISION (TREE_TYPE (arg2))
   13305          249 :                     < TYPE_PRECISION (integer_type_node))
   13306           13 :                   arg2 = fold_convert (unsigned_type_node, arg2);
   13307              : 
   13308          249 :                 if (TYPE_UNSIGNED (TREE_TYPE (arg2)))
   13309           26 :                   arg2 = build2_loc (loc, TRUNC_MOD_EXPR, TREE_TYPE (arg2),
   13310           26 :                                      arg2, build_int_cst (TREE_TYPE (arg2),
   13311           26 :                                                           prec));
   13312              :                 else
   13313              :                   {
   13314              :                     /* When second argument is signed, just do the modulo in
   13315              :                        unsigned type, that results in better generated code
   13316              :                        (for power of 2 precisions bitwise AND).  */
   13317          223 :                     tree utype = c_common_unsigned_type (TREE_TYPE (arg2));
   13318          223 :                     arg2 = build2_loc (loc, TRUNC_MOD_EXPR, utype,
   13319              :                                        fold_convert (utype, arg2),
   13320          223 :                                        build_int_cst (utype, prec));
   13321              :                   }
   13322              : 
   13323              :                 /* The middle-end isn't prepared to handle {L,R}ROTATE_EXPR
   13324              :                    on types without mode precision, except for large/huge
   13325              :                    _BitInt types.  */
   13326          249 :                 if (type_has_mode_precision_p (TREE_TYPE (arg1))
   13327          249 :                     || (TREE_CODE (TREE_TYPE (arg1)) == BITINT_TYPE
   13328          150 :                         && prec > MAX_FIXED_MODE_SIZE))
   13329          192 :                   expr.value = build2_loc (loc, code, TREE_TYPE (arg1), arg1,
   13330              :                                            arg2);
   13331              :                 else
   13332              :                   {
   13333           57 :                     arg2 = save_expr (arg2);
   13334           82 :                     tree t1 = build2_loc (loc, (code == LROTATE_EXPR
   13335              :                                                 ? LSHIFT_EXPR : RSHIFT_EXPR),
   13336           57 :                                           TREE_TYPE (arg1), arg1, arg2);
   13337          114 :                     tree t2 = build2_loc (loc, MINUS_EXPR,
   13338           57 :                                           TREE_TYPE (arg2),
   13339           57 :                                           build_int_cst (TREE_TYPE (arg2),
   13340           57 :                                                          prec), arg2);
   13341           82 :                     t2 = build2_loc (loc, (code == LROTATE_EXPR
   13342              :                                            ? RSHIFT_EXPR : LSHIFT_EXPR),
   13343           57 :                                      TREE_TYPE (arg1), arg1, t2);
   13344           57 :                     suppress_warning (t2, OPT_Wshift_count_overflow);
   13345           57 :                     tree t3 = build2_loc (loc, BIT_IOR_EXPR,
   13346           57 :                                           TREE_TYPE (arg1), t1, t2);
   13347           57 :                     tree t4 = build2_loc (loc, NE_EXPR, boolean_type_node,
   13348              :                                           arg2,
   13349           57 :                                           build_zero_cst (TREE_TYPE (arg2)));
   13350           57 :                     t4 = build2_loc (loc, COMPOUND_EXPR, boolean_type_node,
   13351              :                                      arg1, t4);
   13352           57 :                     expr.value = build3_loc (loc, COND_EXPR,
   13353           57 :                                              TREE_TYPE (arg1), t4, t3, arg1);
   13354              :                   }
   13355          249 :                 if (instrument_expr)
   13356           28 :                   expr.value = build2_loc (loc, COMPOUND_EXPR,
   13357           28 :                                            TREE_TYPE (expr.value),
   13358              :                                            instrument_expr, expr.value);
   13359          249 :                 set_c_expr_source_range (&expr, loc, close_paren_loc);
   13360          249 :                 break;
   13361              :               }
   13362          634 :             tree barg1 = arg;
   13363          634 :             switch (stdc_rid)
   13364              :               {
   13365           69 :               case C_BUILTIN_STDC_BIT_CEIL:
   13366           69 :                 arg = save_expr (arg);
   13367           69 :                 barg1 = build2_loc (loc, PLUS_EXPR, type, arg,
   13368              :                                     build_int_cst (type, -1));
   13369           69 :                 break;
   13370           53 :               case C_BUILTIN_STDC_BIT_FLOOR:
   13371           53 :                 barg1 = arg = save_expr (arg);
   13372           53 :                 break;
   13373          211 :               case C_BUILTIN_STDC_COUNT_ZEROS:
   13374          211 :               case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
   13375          211 :               case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
   13376          211 :               case C_BUILTIN_STDC_LEADING_ONES:
   13377          211 :               case C_BUILTIN_STDC_TRAILING_ONES:
   13378          211 :                 barg1 = build1_loc (loc, BIT_NOT_EXPR, type, arg);
   13379          211 :                 break;
   13380              :               default:
   13381              :                 break;
   13382              :               }
   13383          634 :             tree barg2 = NULL_TREE;
   13384          634 :             switch (stdc_rid)
   13385              :               {
   13386          215 :               case C_BUILTIN_STDC_BIT_WIDTH:
   13387          215 :               case C_BUILTIN_STDC_LEADING_ONES:
   13388          215 :               case C_BUILTIN_STDC_LEADING_ZEROS:
   13389          215 :               case C_BUILTIN_STDC_TRAILING_ONES:
   13390          215 :               case C_BUILTIN_STDC_TRAILING_ZEROS:
   13391          215 :                 barg2 = build_int_cst (integer_type_node, prec);
   13392          215 :                 break;
   13393          171 :               case C_BUILTIN_STDC_FIRST_LEADING_ONE:
   13394          171 :               case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
   13395          171 :               case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
   13396          171 :               case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
   13397          171 :                 barg2 = integer_minus_one_node;
   13398          171 :                 break;
   13399              :               default:
   13400              :                 break;
   13401              :               }
   13402          634 :             tree fndecl = NULL_TREE;
   13403          634 :             switch (stdc_rid)
   13404              :               {
   13405          340 :               case C_BUILTIN_STDC_BIT_CEIL:
   13406          340 :               case C_BUILTIN_STDC_BIT_FLOOR:
   13407          340 :               case C_BUILTIN_STDC_BIT_WIDTH:
   13408          340 :               case C_BUILTIN_STDC_FIRST_LEADING_ONE:
   13409          340 :               case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
   13410          340 :               case C_BUILTIN_STDC_LEADING_ONES:
   13411          340 :               case C_BUILTIN_STDC_LEADING_ZEROS:
   13412          340 :                 fndecl = builtin_decl_explicit (BUILT_IN_CLZG);
   13413          340 :                 break;
   13414          168 :               case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
   13415          168 :               case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
   13416          168 :               case C_BUILTIN_STDC_TRAILING_ONES:
   13417          168 :               case C_BUILTIN_STDC_TRAILING_ZEROS:
   13418          168 :                 fndecl = builtin_decl_explicit (BUILT_IN_CTZG);
   13419          168 :                 break;
   13420          126 :               case C_BUILTIN_STDC_COUNT_ONES:
   13421          126 :               case C_BUILTIN_STDC_COUNT_ZEROS:
   13422          126 :               case C_BUILTIN_STDC_HAS_SINGLE_BIT:
   13423          126 :                 fndecl = builtin_decl_explicit (BUILT_IN_POPCOUNTG);
   13424          126 :                 break;
   13425            0 :               default:
   13426            0 :                 gcc_unreachable ();
   13427              :               }
   13428              :             /* Construct a call to __builtin_{clz,ctz,popcount}g.  */
   13429          634 :             int nargs = barg2 != NULL_TREE ? 2 : 1;
   13430          634 :             vec<tree, va_gc> *args;
   13431          634 :             vec_alloc (args, nargs);
   13432          634 :             vec<tree, va_gc> *origtypes;
   13433          634 :             vec_alloc (origtypes, nargs);
   13434         1268 :             auto_vec<location_t> arg_loc (nargs);
   13435          634 :             args->quick_push (barg1);
   13436          634 :             arg_loc.quick_push (arg_p->get_location ());
   13437          634 :             origtypes->quick_push (arg_p->original_type);
   13438          634 :             if (nargs == 2)
   13439              :               {
   13440          386 :                 args->quick_push (barg2);
   13441          386 :                 arg_loc.quick_push (loc);
   13442          386 :                 origtypes->quick_push (integer_type_node);
   13443              :               }
   13444          634 :             expr.value = c_build_function_call_vec (loc, arg_loc, fndecl,
   13445              :                                                     args, origtypes);
   13446          634 :             set_c_expr_source_range (&expr, loc, close_paren_loc);
   13447          634 :             if (expr.value == error_mark_node)
   13448              :               break;
   13449          634 :             switch (stdc_rid)
   13450              :               {
   13451          122 :               case C_BUILTIN_STDC_BIT_CEIL:
   13452          122 :               case C_BUILTIN_STDC_BIT_FLOOR:
   13453          122 :                 --prec;
   13454              :                 /* FALLTHRU */
   13455          169 :               case C_BUILTIN_STDC_BIT_WIDTH:
   13456          169 :                 expr.value = build2_loc (loc, MINUS_EXPR, integer_type_node,
   13457              :                                          build_int_cst (integer_type_node,
   13458          169 :                                                         prec), expr.value);
   13459          169 :                 break;
   13460          171 :               case C_BUILTIN_STDC_FIRST_LEADING_ONE:
   13461          171 :               case C_BUILTIN_STDC_FIRST_LEADING_ZERO:
   13462          171 :               case C_BUILTIN_STDC_FIRST_TRAILING_ONE:
   13463          171 :               case C_BUILTIN_STDC_FIRST_TRAILING_ZERO:
   13464          171 :                 expr.value = build2_loc (loc, PLUS_EXPR, integer_type_node,
   13465              :                                          expr.value, integer_one_node);
   13466          171 :                 break;
   13467           42 :               case C_BUILTIN_STDC_HAS_SINGLE_BIT:
   13468           42 :                 expr.value = build2_loc (loc, EQ_EXPR, boolean_type_node,
   13469              :                                          expr.value, integer_one_node);
   13470           42 :                 break;
   13471              :               default:
   13472              :                 break;
   13473              :               }
   13474              : 
   13475          382 :             if (stdc_rid != C_BUILTIN_STDC_BIT_CEIL
   13476              :                 && stdc_rid != C_BUILTIN_STDC_BIT_FLOOR)
   13477              :               {
   13478          512 :                 if (stdc_rid != C_BUILTIN_STDC_HAS_SINGLE_BIT)
   13479          470 :                   expr.value = fold_convert_loc (loc, unsigned_type_node,
   13480              :                                                  expr.value);
   13481              :                 break;
   13482              :               }
   13483              :             /* For __builtin_stdc_bit_ceil (0U) or __builtin_stdc_bit_ceil (1U)
   13484              :                or __builtin_stdc_bit_floor (0U) avoid bogus -Wshift-count-*
   13485              :                warnings.  The LSHIFT_EXPR is in dead code in that case.  */
   13486          122 :             if (integer_zerop (arg)
   13487          122 :                 || (stdc_rid == C_BUILTIN_STDC_BIT_CEIL && integer_onep (arg)))
   13488           42 :               expr.value = build_int_cst (type, 0);
   13489              :             else
   13490           80 :               expr.value
   13491           80 :                 = build2_loc (loc, LSHIFT_EXPR, type,
   13492              :                               build_int_cst (type,
   13493              :                                              (stdc_rid
   13494              :                                               == C_BUILTIN_STDC_BIT_CEIL
   13495          114 :                                               ? 2 : 1)), expr.value);
   13496          122 :             if (stdc_rid == C_BUILTIN_STDC_BIT_CEIL)
   13497           69 :               expr.value = build3_loc (loc, COND_EXPR, type,
   13498              :                                        build2_loc (loc, LE_EXPR,
   13499              :                                                    boolean_type_node, arg,
   13500              :                                                    build_int_cst (type, 1)),
   13501              :                                        build_int_cst (type, 1),
   13502              :                                        expr.value);
   13503              :             else
   13504           53 :               expr.value = build3_loc (loc, COND_EXPR, type,
   13505              :                                        build2_loc (loc, EQ_EXPR,
   13506              :                                                    boolean_type_node, arg,
   13507              :                                                    build_int_cst (type, 0)),
   13508              :                                        build_int_cst (type, 0),
   13509              :                                        expr.value);
   13510              :             break;
   13511              :           }
   13512            0 :         case RID_AT_SELECTOR:
   13513            0 :           {
   13514            0 :             gcc_assert (c_dialect_objc ());
   13515            0 :             c_parser_consume_token (parser);
   13516            0 :             matching_parens parens;
   13517            0 :             if (!parens.require_open (parser))
   13518              :               {
   13519            0 :                 expr.set_error ();
   13520            0 :                 break;
   13521              :               }
   13522            0 :             tree sel = c_parser_objc_selector_arg (parser);
   13523            0 :             location_t close_loc = c_parser_peek_token (parser)->location;
   13524            0 :             parens.skip_until_found_close (parser);
   13525            0 :             expr.value = objc_build_selector_expr (loc, sel);
   13526            0 :             set_c_expr_source_range (&expr, loc, close_loc);
   13527              :           }
   13528            0 :           break;
   13529            0 :         case RID_AT_PROTOCOL:
   13530            0 :           {
   13531            0 :             gcc_assert (c_dialect_objc ());
   13532            0 :             c_parser_consume_token (parser);
   13533            0 :             matching_parens parens;
   13534            0 :             if (!parens.require_open (parser))
   13535              :               {
   13536            0 :                 expr.set_error ();
   13537            0 :                 break;
   13538              :               }
   13539            0 :             if (c_parser_next_token_is_not (parser, CPP_NAME))
   13540              :               {
   13541            0 :                 c_parser_error (parser, "expected identifier");
   13542            0 :                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   13543            0 :                 expr.set_error ();
   13544            0 :                 break;
   13545              :               }
   13546            0 :             tree id = c_parser_peek_token (parser)->value;
   13547            0 :             c_parser_consume_token (parser);
   13548            0 :             location_t close_loc = c_parser_peek_token (parser)->location;
   13549            0 :             parens.skip_until_found_close (parser);
   13550            0 :             expr.value = objc_build_protocol_expr (id);
   13551            0 :             set_c_expr_source_range (&expr, loc, close_loc);
   13552              :           }
   13553            0 :           break;
   13554            0 :         case RID_AT_ENCODE:
   13555            0 :           {
   13556              :             /* Extension to support C-structures in the archiver.  */
   13557            0 :             gcc_assert (c_dialect_objc ());
   13558            0 :             c_parser_consume_token (parser);
   13559            0 :             matching_parens parens;
   13560            0 :             if (!parens.require_open (parser))
   13561              :               {
   13562            0 :                 expr.set_error ();
   13563            0 :                 break;
   13564              :               }
   13565            0 :             t1 = c_parser_type_name (parser);
   13566            0 :             if (t1 == NULL)
   13567              :               {
   13568            0 :                 expr.set_error ();
   13569            0 :                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   13570            0 :                 break;
   13571              :               }
   13572            0 :             location_t close_loc = c_parser_peek_token (parser)->location;
   13573            0 :             parens.skip_until_found_close (parser);
   13574            0 :             tree type = groktypename (t1, NULL, NULL);
   13575            0 :             expr.value = objc_build_encode_expr (type);
   13576            0 :             set_c_expr_source_range (&expr, loc, close_loc);
   13577              :           }
   13578            0 :           break;
   13579          711 :         case RID_GENERIC:
   13580          711 :           expr = c_parser_generic_selection (parser);
   13581          711 :           break;
   13582            3 :         case RID_OMP_ALL_MEMORY:
   13583            3 :           gcc_assert (flag_openmp);
   13584            3 :           c_parser_consume_token (parser);
   13585            3 :           error_at (loc, "%<omp_all_memory%> may only be used in OpenMP "
   13586              :                          "%<depend%> clause");
   13587            3 :           expr.set_error ();
   13588            3 :           break;
   13589              :         /* C23 'nullptr' literal.  */
   13590        11401 :         case RID_NULLPTR:
   13591        11401 :           c_parser_consume_token (parser);
   13592        11401 :           expr.value = nullptr_node;
   13593        11401 :           set_c_expr_source_range (&expr, tok_range);
   13594        11401 :           pedwarn_c11 (loc, OPT_Wpedantic,
   13595              :                        "ISO C does not support %qs before C23", "nullptr");
   13596        11401 :           break;
   13597         5444 :         case RID_TRUE:
   13598         5444 :           c_parser_consume_token (parser);
   13599         5444 :           expr.value = boolean_true_node;
   13600         5444 :           set_c_expr_source_range (&expr, tok_range);
   13601         5444 :           break;
   13602         4790 :         case RID_FALSE:
   13603         4790 :           c_parser_consume_token (parser);
   13604         4790 :           expr.value = boolean_false_node;
   13605         4790 :           set_c_expr_source_range (&expr, tok_range);
   13606         4790 :           break;
   13607           37 :         default:
   13608           37 :           c_parser_error (parser, "expected expression");
   13609           37 :           expr.set_error ();
   13610           37 :           break;
   13611              :         }
   13612              :       break;
   13613            2 :     case CPP_OPEN_SQUARE:
   13614            2 :       if (c_dialect_objc ())
   13615              :         {
   13616            0 :           tree receiver, args;
   13617            0 :           c_parser_consume_token (parser);
   13618            0 :           receiver = c_parser_objc_receiver (parser);
   13619            0 :           args = c_parser_objc_message_args (parser);
   13620            0 :           location_t close_loc = c_parser_peek_token (parser)->location;
   13621            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
   13622              :                                      "expected %<]%>");
   13623            0 :           expr.value = objc_build_message_expr (receiver, args);
   13624            0 :           set_c_expr_source_range (&expr, loc, close_loc);
   13625            0 :           break;
   13626              :         }
   13627              :       /* Else fall through to report error.  */
   13628              :       /* FALLTHRU */
   13629          795 :     default:
   13630          795 :       c_parser_error (parser, "expected expression");
   13631          795 :       expr.set_error ();
   13632          795 :       break;
   13633              :     }
   13634    235898210 :  out:
   13635    235898210 :   return c_parser_postfix_expression_after_primary
   13636    235898210 :     (parser, EXPR_LOC_OR_LOC (expr.value, loc), expr);
   13637              : }
   13638              : 
   13639              : /* Parse a postfix expression after a parenthesized type name: the
   13640              :    brace-enclosed initializer of a compound literal, possibly followed
   13641              :    by some postfix operators.  This is separate because it is not
   13642              :    possible to tell until after the type name whether a cast
   13643              :    expression has a cast or a compound literal, or whether the operand
   13644              :    of sizeof is a parenthesized type name or starts with a compound
   13645              :    literal.  TYPE_LOC is the location where TYPE_NAME starts--the
   13646              :    location of the first token after the parentheses around the type
   13647              :    name.  */
   13648              : 
   13649              : static struct c_expr
   13650       917721 : c_parser_postfix_expression_after_paren_type (c_parser *parser,
   13651              :                                               struct c_declspecs *scspecs,
   13652              :                                               struct c_type_name *type_name,
   13653              :                                               location_t type_loc)
   13654              : {
   13655       917721 :   tree type;
   13656       917721 :   struct c_expr init;
   13657       917721 :   bool non_const;
   13658       917721 :   struct c_expr expr;
   13659       917721 :   location_t start_loc;
   13660       917721 :   tree type_expr = NULL_TREE;
   13661       917721 :   bool type_expr_const = true;
   13662       917721 :   bool constexpr_p = scspecs ? scspecs->constexpr_p : false;
   13663       917721 :   unsigned int underspec_state = 0;
   13664       917721 :   check_compound_literal_type (type_loc, type_name);
   13665       917721 :   rich_location richloc (line_table, type_loc);
   13666       917721 :   start_loc = c_parser_peek_token (parser)->location;
   13667       917721 :   if (constexpr_p)
   13668              :     {
   13669          234 :       underspec_state = start_underspecified_init (start_loc, NULL_TREE);
   13670              :       /* A constexpr compound literal is subject to the constraints on
   13671              :          underspecified declarations, which may not declare tags or
   13672              :          members or structures or unions; it is undefined behavior to
   13673              :          declare the members of an enumeration.  Where the structure,
   13674              :          union or enumeration type is declared within the compound
   13675              :          literal initializer, this is diagnosed elsewhere as a result
   13676              :          of the above call to start_underspecified_init.  Diagnose
   13677              :          here the case of declaring such a type in the type specifiers
   13678              :          of the compound literal.  */
   13679          234 :       switch (type_name->specs->typespec_kind)
   13680              :         {
   13681            2 :         case ctsk_tagfirstref:
   13682            2 :         case ctsk_tagfirstref_attrs:
   13683            2 :           error_at (type_loc, "%qT declared in %<constexpr%> compound literal",
   13684              :                     type_name->specs->type);
   13685            2 :           break;
   13686              : 
   13687            4 :         case ctsk_tagdef:
   13688            4 :           error_at (type_loc, "%qT defined in %<constexpr%> compound literal",
   13689              :                     type_name->specs->type);
   13690            4 :           break;
   13691              : 
   13692              :         default:
   13693              :           break;
   13694              :         }
   13695              :     }
   13696       917721 :   start_init (NULL_TREE, NULL,
   13697       917721 :               (global_bindings_p ()
   13698       917467 :                || (scspecs && scspecs->storage_class == csc_static)
   13699      1835158 :                || constexpr_p), constexpr_p, &richloc);
   13700       917721 :   type = groktypename (type_name, &type_expr, &type_expr_const);
   13701       917721 :   bool varsize_p = false;
   13702       917721 :   if (type != error_mark_node && C_TYPE_VARIABLE_SIZE (type))
   13703              :     {
   13704           16 :       pedwarn (type_loc, OPT_Wpedantic, "compound literal has variable size");
   13705           16 :       varsize_p = true;
   13706              :     }
   13707       917705 :   else if (TREE_CODE (type) == FUNCTION_TYPE)
   13708              :     {
   13709            3 :       error_at (type_loc, "compound literal has function type");
   13710            3 :       type = error_mark_node;
   13711              :     }
   13712       917721 :   if (constexpr_p && type != error_mark_node)
   13713              :     {
   13714          234 :       tree type_no_array = strip_array_types (type);
   13715              :       /* The type of a constexpr object must not be variably modified
   13716              :          (which applies to all compound literals), volatile, atomic or
   13717              :          restrict qualified or have a member with such a qualifier.
   13718              :          const qualification is implicitly added.  */
   13719          234 :       if (TYPE_QUALS (type_no_array)
   13720          234 :           & (TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC))
   13721            9 :         error_at (type_loc, "invalid qualifiers for %<constexpr%> object");
   13722          225 :       else if (RECORD_OR_UNION_TYPE_P (type_no_array)
   13723          225 :                && C_TYPE_FIELDS_NON_CONSTEXPR (type_no_array))
   13724            8 :         error_at (type_loc, "invalid qualifiers for field of "
   13725              :                   "%<constexpr%> object");
   13726          468 :       type = c_build_qualified_type (type,
   13727          234 :                                      (TYPE_QUALS (type_no_array)
   13728              :                                       | TYPE_QUAL_CONST));
   13729              :     }
   13730       917721 :   init = c_parser_braced_init (parser, type, false, NULL, varsize_p);
   13731       917721 :   if (constexpr_p)
   13732          234 :     finish_underspecified_init (NULL_TREE, underspec_state);
   13733       917721 :   finish_init ();
   13734       917721 :   maybe_warn_string_init (type_loc, type, init);
   13735              : 
   13736       917721 :   if (type != error_mark_node
   13737       917714 :       && !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (type))
   13738       917721 :       && current_function_decl)
   13739              :     {
   13740            0 :       error ("compound literal qualified by address-space qualifier");
   13741            0 :       type = error_mark_node;
   13742              :     }
   13743              : 
   13744      1835137 :   if (!pedwarn_c90 (start_loc, OPT_Wpedantic,
   13745       917721 :                     "ISO C90 forbids compound literals") && scspecs)
   13746          305 :     pedwarn_c11 (start_loc, OPT_Wpedantic,
   13747              :                  "ISO C forbids storage class specifiers in compound literals "
   13748              :                  "before C23");
   13749       917721 :   non_const = ((init.value && TREE_CODE (init.value) == CONSTRUCTOR)
   13750      1834979 :                ? CONSTRUCTOR_NON_CONST (init.value)
   13751          463 :                : init.original_code == C_MAYBE_CONST_EXPR);
   13752       917721 :   non_const |= !type_expr_const;
   13753       917721 :   unsigned int alignas_align = 0;
   13754       917721 :   if (type != error_mark_node
   13755       917714 :       && type_name->specs->align_log != -1)
   13756              :     {
   13757            4 :       alignas_align = 1U << type_name->specs->align_log;
   13758            4 :       if (alignas_align < min_align_of_type (type))
   13759              :         {
   13760            1 :           error_at (type_name->specs->locations[cdw_alignas],
   13761              :                     "%<_Alignas%> specifiers cannot reduce "
   13762              :                     "alignment of compound literal");
   13763            1 :           alignas_align = 0;
   13764              :         }
   13765              :     }
   13766       917721 :   expr.value = build_compound_literal (start_loc, type, init.value, non_const,
   13767              :                                        alignas_align, scspecs);
   13768       917721 :   set_c_expr_source_range (&expr, init.src_range);
   13769       917721 :   expr.m_decimal = 0;
   13770       917721 :   expr.original_code = ERROR_MARK;
   13771       917721 :   expr.original_type = NULL;
   13772       917721 :   if (type != error_mark_node
   13773       917714 :       && expr.value != error_mark_node
   13774       917642 :       && type_expr)
   13775              :     {
   13776           41 :       if (TREE_CODE (expr.value) == C_MAYBE_CONST_EXPR)
   13777              :         {
   13778           19 :           gcc_assert (C_MAYBE_CONST_EXPR_PRE (expr.value) == NULL_TREE);
   13779           19 :           C_MAYBE_CONST_EXPR_PRE (expr.value) = type_expr;
   13780              :         }
   13781              :       else
   13782              :         {
   13783           22 :           gcc_assert (!non_const);
   13784           22 :           expr.value = build2 (C_MAYBE_CONST_EXPR, type,
   13785              :                                type_expr, expr.value);
   13786              :         }
   13787              :     }
   13788       917721 :   return c_parser_postfix_expression_after_primary (parser, start_loc, expr);
   13789       917721 : }
   13790              : 
   13791              : /* Callback function for sizeof_pointer_memaccess_warning to compare
   13792              :    types.  */
   13793              : 
   13794              : static bool
   13795         3456 : sizeof_ptr_memacc_comptypes (tree type1, tree type2)
   13796              : {
   13797         3456 :   return comptypes (type1, type2) == 1;
   13798              : }
   13799              : 
   13800              : /* Warn for patterns where abs-like function appears to be used incorrectly,
   13801              :    gracefully ignore any non-abs-like function.  The warning location should
   13802              :    be LOC.  FNDECL is the declaration of called function, it must be a
   13803              :    BUILT_IN_NORMAL function.  ARG is the first and only argument of the
   13804              :    call.  */
   13805              : 
   13806              : static void
   13807        57427 : warn_for_abs (location_t loc, tree fndecl, tree arg)
   13808              : {
   13809              :   /* Avoid warning in unreachable subexpressions.  */
   13810        57427 :   if (c_inhibit_evaluation_warnings)
   13811              :     return;
   13812              : 
   13813        31089 :   tree atype = TREE_TYPE (arg);
   13814              : 
   13815              :   /* Casts from pointers (and thus arrays and fndecls) will generate
   13816              :      -Wint-conversion warnings.  Most other wrong types hopefully lead to type
   13817              :      mismatch errors.  TODO: Think about what to do with FIXED_POINT_TYPE_P
   13818              :      types and possibly other exotic types.  */
   13819        31089 :   if (!INTEGRAL_TYPE_P (atype)
   13820        31089 :       && !SCALAR_FLOAT_TYPE_P (atype)
   13821         5131 :       && TREE_CODE (atype) != COMPLEX_TYPE)
   13822              :     return;
   13823              : 
   13824        26436 :   enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
   13825              : 
   13826        26436 :   switch (fcode)
   13827              :     {
   13828           35 :     case BUILT_IN_ABS:
   13829           35 :     case BUILT_IN_LABS:
   13830           35 :     case BUILT_IN_LLABS:
   13831           35 :     case BUILT_IN_IMAXABS:
   13832           35 :       if (!INTEGRAL_TYPE_P (atype))
   13833              :         {
   13834            4 :           if (SCALAR_FLOAT_TYPE_P (atype))
   13835            3 :             warning_at (loc, OPT_Wabsolute_value,
   13836              :                         "using integer absolute value function %qD when "
   13837              :                         "argument is of floating-point type %qT",
   13838              :                         fndecl, atype);
   13839            1 :           else if (TREE_CODE (atype) == COMPLEX_TYPE)
   13840            1 :             warning_at (loc, OPT_Wabsolute_value,
   13841              :                         "using integer absolute value function %qD when "
   13842              :                         "argument is of complex type %qT", fndecl, atype);
   13843              :           else
   13844              :             gcc_unreachable ();
   13845            4 :           return;
   13846              :         }
   13847           31 :       if (TYPE_UNSIGNED (atype))
   13848            9 :         warning_at (loc, OPT_Wabsolute_value,
   13849              :                     "taking the absolute value of unsigned type %qT "
   13850              :                     "has no effect", atype);
   13851              :       break;
   13852              : 
   13853          334 :     CASE_FLT_FN (BUILT_IN_FABS):
   13854          334 :     CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
   13855          334 :       if (!SCALAR_FLOAT_TYPE_P (atype)
   13856          334 :           || DECIMAL_FLOAT_MODE_P (TYPE_MODE (atype)))
   13857              :         {
   13858            4 :           if (INTEGRAL_TYPE_P (atype))
   13859            2 :             warning_at (loc, OPT_Wabsolute_value,
   13860              :                         "using floating-point absolute value function %qD "
   13861              :                         "when argument is of integer type %qT", fndecl, atype);
   13862            2 :           else if (DECIMAL_FLOAT_TYPE_P (atype))
   13863            1 :             warning_at (loc, OPT_Wabsolute_value,
   13864              :                         "using floating-point absolute value function %qD "
   13865              :                         "when argument is of decimal floating-point type %qT",
   13866              :                         fndecl, atype);
   13867            1 :           else if (TREE_CODE (atype) == COMPLEX_TYPE)
   13868            1 :             warning_at (loc, OPT_Wabsolute_value,
   13869              :                         "using floating-point absolute value function %qD when "
   13870              :                         "argument is of complex type %qT", fndecl, atype);
   13871              :           else
   13872            0 :             gcc_unreachable ();
   13873            4 :           return;
   13874              :         }
   13875              :       break;
   13876              : 
   13877            7 :     CASE_FLT_FN (BUILT_IN_CABS):
   13878            7 :       if (TREE_CODE (atype) != COMPLEX_TYPE)
   13879              :         {
   13880            4 :           if (INTEGRAL_TYPE_P (atype))
   13881            2 :             warning_at (loc, OPT_Wabsolute_value,
   13882              :                         "using complex absolute value function %qD when "
   13883              :                         "argument is of integer type %qT", fndecl, atype);
   13884            2 :           else if (SCALAR_FLOAT_TYPE_P (atype))
   13885            2 :             warning_at (loc, OPT_Wabsolute_value,
   13886              :                         "using complex absolute value function %qD when "
   13887              :                         "argument is of floating-point type %qT",
   13888              :                         fndecl, atype);
   13889              :           else
   13890              :             gcc_unreachable ();
   13891              : 
   13892            4 :           return;
   13893              :         }
   13894              :       break;
   13895              : 
   13896            6 :     case BUILT_IN_FABSD32:
   13897            6 :     case BUILT_IN_FABSD64:
   13898            6 :     case BUILT_IN_FABSD128:
   13899            6 :     case BUILT_IN_FABSD64X:
   13900            6 :       if (!DECIMAL_FLOAT_TYPE_P (atype))
   13901              :         {
   13902            4 :           if (INTEGRAL_TYPE_P (atype))
   13903            1 :             warning_at (loc, OPT_Wabsolute_value,
   13904              :                         "using decimal floating-point absolute value "
   13905              :                         "function %qD when argument is of integer type %qT",
   13906              :                         fndecl, atype);
   13907            3 :           else if (SCALAR_FLOAT_TYPE_P (atype))
   13908            2 :             warning_at (loc, OPT_Wabsolute_value,
   13909              :                         "using decimal floating-point absolute value "
   13910              :                         "function %qD when argument is of floating-point "
   13911              :                         "type %qT", fndecl, atype);
   13912            1 :           else if (TREE_CODE (atype) == COMPLEX_TYPE)
   13913            1 :             warning_at (loc, OPT_Wabsolute_value,
   13914              :                         "using decimal floating-point absolute value "
   13915              :                         "function %qD when argument is of complex type %qT",
   13916              :                         fndecl, atype);
   13917              :           else
   13918            0 :             gcc_unreachable ();
   13919            4 :           return;
   13920              :         }
   13921              :       break;
   13922              : 
   13923              :     default:
   13924              :       return;
   13925              :     }
   13926              : 
   13927          366 :   if (!TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
   13928              :     return;
   13929              : 
   13930          365 :   tree ftype = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
   13931          365 :   if (TREE_CODE (atype) == COMPLEX_TYPE)
   13932              :     {
   13933            3 :       gcc_assert (TREE_CODE (ftype) == COMPLEX_TYPE);
   13934            3 :       atype = TREE_TYPE (atype);
   13935            3 :       ftype = TREE_TYPE (ftype);
   13936              :     }
   13937              : 
   13938          365 :   if (TYPE_PRECISION (ftype) < TYPE_PRECISION (atype))
   13939            9 :     warning_at (loc, OPT_Wabsolute_value,
   13940              :                 "absolute value function %qD given an argument of type %qT "
   13941              :                 "but has parameter of type %qT which may cause truncation "
   13942              :                 "of value", fndecl, atype, ftype);
   13943              : }
   13944              : 
   13945              : 
   13946              : /* Parse a postfix expression after the initial primary or compound
   13947              :    literal; that is, parse a series of postfix operators.
   13948              : 
   13949              :    EXPR_LOC is the location of the primary expression.  */
   13950              : 
   13951              : static struct c_expr
   13952    236815981 : c_parser_postfix_expression_after_primary (c_parser *parser,
   13953              :                                            location_t expr_loc,
   13954              :                                            struct c_expr expr)
   13955              : {
   13956    236815981 :   struct c_expr orig_expr;
   13957    236815981 :   tree ident, idx, len;
   13958    236815981 :   location_t sizeof_arg_loc[6], comp_loc;
   13959    236815981 :   tree sizeof_arg[6];
   13960    236815981 :   unsigned int literal_zero_mask;
   13961    236815981 :   unsigned int i;
   13962    236815981 :   vec<tree, va_gc> *exprlist;
   13963    236815981 :   vec<tree, va_gc> *origtypes = NULL;
   13964    236815981 :   vec<location_t> arg_loc = vNULL;
   13965    292943883 :   location_t start;
   13966    292943883 :   location_t finish;
   13967              : 
   13968    292943883 :   while (true)
   13969              :     {
   13970    292943883 :       location_t op_loc = c_parser_peek_token (parser)->location;
   13971    292943883 :       switch (c_parser_peek_token (parser)->type)
   13972              :         {
   13973      3461416 :         case CPP_OPEN_SQUARE:
   13974              :           /* Array reference.  */
   13975      3461416 :           c_parser_consume_token (parser);
   13976      3461416 :           idx = len = NULL_TREE;
   13977      3461416 :           if (!c_omp_array_section_p
   13978      3462138 :               || c_parser_next_token_is_not (parser, CPP_COLON))
   13979      3461223 :             idx = c_parser_expression (parser).value;
   13980              : 
   13981      3461416 :           if (c_omp_array_section_p
   13982      3462138 :               && c_parser_next_token_is (parser, CPP_COLON))
   13983              :             {
   13984          577 :               c_parser_consume_token (parser);
   13985          577 :               if (c_parser_next_token_is_not (parser, CPP_CLOSE_SQUARE))
   13986          542 :                 len = c_parser_expression (parser).value;
   13987              : 
   13988          577 :               expr.value = build_omp_array_section (op_loc, expr.value, idx,
   13989              :                                                     len);
   13990              :             }
   13991              :           else
   13992      3460839 :             expr.value = build_array_ref (op_loc, expr.value, idx);
   13993              : 
   13994      3461416 :           c_parser_skip_until_found (parser, CPP_CLOSE_SQUARE,
   13995              :                                      "expected %<]%>");
   13996              : 
   13997      3461416 :           start = expr.get_start ();
   13998      3461416 :           finish = parser->tokens_buf[0].location;
   13999      3461416 :           set_c_expr_source_range (&expr, start, finish);
   14000      3461416 :           expr.original_code = ERROR_MARK;
   14001      3461416 :           expr.original_type = NULL;
   14002      3461416 :           expr.m_decimal = 0;
   14003      3461416 :           break;
   14004     49709222 :         case CPP_OPEN_PAREN:
   14005              :           /* Function call.  */
   14006     49709222 :           {
   14007     49709222 :             matching_parens parens;
   14008     49709222 :             parens.consume_open (parser);
   14009    397673776 :             for (i = 0; i < 6; i++)
   14010              :               {
   14011    298255332 :                 sizeof_arg[i] = NULL_TREE;
   14012    298255332 :                 sizeof_arg_loc[i] = UNKNOWN_LOCATION;
   14013              :               }
   14014     49709222 :             literal_zero_mask = 0;
   14015     49709222 :             if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   14016              :               exprlist = NULL;
   14017     38017589 :             else if (TREE_CODE (expr.value) == FUNCTION_DECL
   14018     37950248 :                      && fndecl_built_in_p (expr.value, BUILT_IN_CLASSIFY_TYPE)
   14019     38019369 :                      && c_parser_next_tokens_start_typename (parser,
   14020              :                                                              cla_prefer_id))
   14021              :               {
   14022              :                 /* __builtin_classify_type (type)  */
   14023           29 :                 c_inhibit_evaluation_warnings++;
   14024           29 :                 in_alignof++;
   14025           29 :                 struct c_type_name *type = c_parser_type_name (parser);
   14026           29 :                 c_inhibit_evaluation_warnings--;
   14027           29 :                 in_alignof--;
   14028           29 :                 struct c_typespec ret;
   14029           29 :                 ret.expr = NULL_TREE;
   14030           29 :                 ret.spec = error_mark_node;
   14031           29 :                 ret.expr_const_operands = false;
   14032           29 :                 if (type != NULL)
   14033           29 :                   ret.spec = groktypename (type, &ret.expr,
   14034              :                                            &ret.expr_const_operands);
   14035           29 :                 parens.skip_until_found_close (parser);
   14036           29 :                 expr.value = build_int_cst (integer_type_node,
   14037           29 :                                             type_to_class (ret.spec));
   14038           29 :                 break;
   14039              :               }
   14040              :             else
   14041     38017560 :               exprlist = c_parser_expr_list (parser, true, false, &origtypes,
   14042              :                                              sizeof_arg_loc, sizeof_arg,
   14043              :                                              &arg_loc, &literal_zero_mask);
   14044     49709193 :             parens.skip_until_found_close (parser);
   14045              :           }
   14046     49709193 :           orig_expr = expr;
   14047     49709193 :           mark_exp_read (expr.value);
   14048     49709193 :           if (warn_sizeof_pointer_memaccess)
   14049      4547031 :             sizeof_pointer_memaccess_warning (sizeof_arg_loc,
   14050              :                                               expr.value, exprlist,
   14051              :                                               sizeof_arg,
   14052              :                                               sizeof_ptr_memacc_comptypes);
   14053     49709193 :           if (TREE_CODE (expr.value) == FUNCTION_DECL)
   14054              :             {
   14055     49632118 :               if (fndecl_built_in_p (expr.value, BUILT_IN_MEMSET)
   14056     49663459 :                   && vec_safe_length (exprlist) == 3)
   14057              :                 {
   14058        31341 :                   tree arg0 = (*exprlist)[0];
   14059        31341 :                   tree arg2 = (*exprlist)[2];
   14060        31341 :                   warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
   14061              :                 }
   14062     49632118 :               if (warn_absolute_value
   14063      4273037 :                   && fndecl_built_in_p (expr.value, BUILT_IN_NORMAL)
   14064     49771307 :                   && vec_safe_length (exprlist) == 1)
   14065        57427 :                 warn_for_abs (expr_loc, expr.value, (*exprlist)[0]);
   14066     49632118 :               if (parser->omp_for_parse_state
   14067          178 :                   && parser->omp_for_parse_state->in_intervening_code
   14068     49632257 :                   && omp_runtime_api_call (expr.value))
   14069              :                 {
   14070            2 :                   error_at (expr_loc, "calls to the OpenMP runtime API are "
   14071              :                                       "not permitted in intervening code");
   14072            2 :                   parser->omp_for_parse_state->fail = true;
   14073              :                 }
   14074     49632118 :               if (warn_calloc_transposed_args)
   14075      4273012 :                 if (tree attr = lookup_attribute ("alloc_size",
   14076      4273012 :                                                   TYPE_ATTRIBUTES
   14077              :                                                     (TREE_TYPE (expr.value))))
   14078         1259 :                   if (TREE_VALUE (attr) && TREE_CHAIN (TREE_VALUE (attr)))
   14079          146 :                     warn_for_calloc (sizeof_arg_loc, expr.value, exprlist,
   14080              :                                      sizeof_arg, attr);
   14081              :             }
   14082              : 
   14083     49709193 :           start = expr.get_start ();
   14084     49709193 :           finish = parser->tokens_buf[0].get_finish ();
   14085     49709193 :           expr.value
   14086     49709193 :             = c_build_function_call_vec (expr_loc, arg_loc, expr.value,
   14087              :                                          exprlist, origtypes);
   14088     49709193 :           set_c_expr_source_range (&expr, start, finish);
   14089     49709193 :           expr.m_decimal = 0;
   14090              : 
   14091     49709193 :           expr.original_code = ERROR_MARK;
   14092     49709193 :           if (TREE_CODE (expr.value) == INTEGER_CST
   14093        12724 :               && TREE_CODE (orig_expr.value) == FUNCTION_DECL
   14094     49721917 :               && fndecl_built_in_p (orig_expr.value, BUILT_IN_CONSTANT_P))
   14095         1549 :             expr.original_code = C_MAYBE_CONST_EXPR;
   14096     49709193 :           expr.original_type = NULL;
   14097     49709193 :           if (exprlist)
   14098              :             {
   14099     38017560 :               release_tree_vector (exprlist);
   14100     38017560 :               release_tree_vector (origtypes);
   14101              :             }
   14102     49709193 :           arg_loc.release ();
   14103     49709193 :           break;
   14104      1763351 :         case CPP_DOT:
   14105              :           /* Structure element reference.  */
   14106      1763351 :           c_parser_consume_token (parser);
   14107      1763351 :           expr = default_function_array_conversion (expr_loc, expr);
   14108      1763351 :           if (c_parser_next_token_is (parser, CPP_NAME))
   14109              :             {
   14110      1763351 :               c_token *comp_tok = c_parser_peek_token (parser);
   14111      1763351 :               ident = comp_tok->value;
   14112      1763351 :               comp_loc = comp_tok->location;
   14113              :             }
   14114              :           else
   14115              :             {
   14116            0 :               c_parser_error (parser, "expected identifier");
   14117            0 :               expr.set_error ();
   14118            0 :               expr.original_code = ERROR_MARK;
   14119            0 :               expr.original_type = NULL;
   14120            0 :               return expr;
   14121              :             }
   14122      1763351 :           start = expr.get_start ();
   14123      1763351 :           finish = c_parser_peek_token (parser)->get_finish ();
   14124      1763351 :           c_parser_consume_token (parser);
   14125      1763351 :           expr.value = build_component_ref (op_loc, expr.value, ident,
   14126              :                                             comp_loc, UNKNOWN_LOCATION);
   14127      1763351 :           set_c_expr_source_range (&expr, start, finish);
   14128      1763351 :           expr.original_code = ERROR_MARK;
   14129      1763351 :           if (TREE_CODE (expr.value) != COMPONENT_REF)
   14130           32 :             expr.original_type = NULL;
   14131              :           else
   14132              :             {
   14133              :               /* Remember the original type of a bitfield.  */
   14134      1763319 :               tree field = TREE_OPERAND (expr.value, 1);
   14135      1763319 :               if (TREE_CODE (field) != FIELD_DECL)
   14136            0 :                 expr.original_type = NULL;
   14137              :               else
   14138      1763319 :                 expr.original_type = DECL_BIT_FIELD_TYPE (field);
   14139              :             }
   14140      1763351 :           expr.m_decimal = 0;
   14141      1763351 :           break;
   14142       499925 :         case CPP_DEREF:
   14143              :           /* Structure element reference.  */
   14144       499925 :           c_parser_consume_token (parser);
   14145       499925 :           expr = convert_lvalue_to_rvalue (expr_loc, expr, true, false);
   14146       499925 :           if (c_parser_next_token_is (parser, CPP_NAME))
   14147              :             {
   14148       499893 :               c_token *comp_tok = c_parser_peek_token (parser);
   14149       499893 :               ident = comp_tok->value;
   14150       499893 :               comp_loc = comp_tok->location;
   14151              :             }
   14152              :           else
   14153              :             {
   14154           32 :               c_parser_error (parser, "expected identifier");
   14155           32 :               expr.set_error ();
   14156           32 :               expr.original_code = ERROR_MARK;
   14157           32 :               expr.original_type = NULL;
   14158           32 :               return expr;
   14159              :             }
   14160       499893 :           start = expr.get_start ();
   14161       499893 :           finish = c_parser_peek_token (parser)->get_finish ();
   14162       499893 :           c_parser_consume_token (parser);
   14163       499893 :           expr.value = build_component_ref (op_loc,
   14164              :                                             build_indirect_ref (op_loc,
   14165              :                                                                 expr.value,
   14166              :                                                                 RO_ARROW),
   14167              :                                             ident, comp_loc,
   14168              :                                             expr.get_location ());
   14169       499893 :           set_c_expr_source_range (&expr, start, finish);
   14170       499893 :           expr.original_code = ERROR_MARK;
   14171       499893 :           if (TREE_CODE (expr.value) != COMPONENT_REF)
   14172          121 :             expr.original_type = NULL;
   14173              :           else
   14174              :             {
   14175              :               /* Remember the original type of a bitfield.  */
   14176       499772 :               tree field = TREE_OPERAND (expr.value, 1);
   14177       499772 :               if (TREE_CODE (field) != FIELD_DECL)
   14178            0 :                 expr.original_type = NULL;
   14179              :               else
   14180       499772 :                 expr.original_type = DECL_BIT_FIELD_TYPE (field);
   14181              :             }
   14182       499893 :           expr.m_decimal = 0;
   14183       499893 :           break;
   14184       676000 :         case CPP_PLUS_PLUS:
   14185              :           /* Postincrement.  */
   14186       676000 :           start = expr.get_start ();
   14187       676000 :           finish = c_parser_peek_token (parser)->get_finish ();
   14188       676000 :           c_parser_consume_token (parser);
   14189       237089 :           if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL)
   14190       603820 :               && !DECL_READ_P (expr.value)
   14191       161491 :               && (VAR_P (expr.value) ? warn_unused_but_set_variable
   14192              :                                      : warn_unused_but_set_parameter) > 1
   14193       706971 :               && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE)
   14194              :             {
   14195        30971 :               expr = default_function_array_read_conversion (expr_loc, expr);
   14196        30971 :               DECL_READ_P (expr.value) = 0;
   14197              :             }
   14198              :           else
   14199       645029 :             expr = default_function_array_read_conversion (expr_loc, expr);
   14200       676000 :           expr.value = build_unary_op (op_loc, POSTINCREMENT_EXPR,
   14201              :                                        expr.value, false);
   14202       676000 :           set_c_expr_source_range (&expr, start, finish);
   14203       676000 :           expr.original_code = ERROR_MARK;
   14204       676000 :           expr.original_type = NULL;
   14205       676000 :           break;
   14206        18020 :         case CPP_MINUS_MINUS:
   14207              :           /* Postdecrement.  */
   14208        18020 :           start = expr.get_start ();
   14209        18020 :           finish = c_parser_peek_token (parser)->get_finish ();
   14210        18020 :           c_parser_consume_token (parser);
   14211         6474 :           if ((VAR_P (expr.value) || TREE_CODE (expr.value) == PARM_DECL)
   14212        14982 :               && !DECL_READ_P (expr.value)
   14213         3395 :               && (VAR_P (expr.value) ? warn_unused_but_set_variable
   14214              :                                      : warn_unused_but_set_parameter) > 1
   14215        18356 :               && TREE_CODE (TREE_TYPE (expr.value)) != ARRAY_TYPE)
   14216              :             {
   14217          336 :               expr = default_function_array_read_conversion (expr_loc, expr);
   14218          336 :               DECL_READ_P (expr.value) = 0;
   14219              :             }
   14220              :           else
   14221        17684 :             expr = default_function_array_read_conversion (expr_loc, expr);
   14222        18020 :           expr.value = build_unary_op (op_loc, POSTDECREMENT_EXPR,
   14223              :                                        expr.value, false);
   14224        18020 :           set_c_expr_source_range (&expr, start, finish);
   14225        18020 :           expr.original_code = ERROR_MARK;
   14226        18020 :           expr.original_type = NULL;
   14227        18020 :           break;
   14228    236815949 :         default:
   14229    236815949 :           return expr;
   14230              :         }
   14231              :     }
   14232              : }
   14233              : 
   14234              : /* Parse an expression (C90 6.3.17, C99 6.5.17, C11 6.5.17).
   14235              : 
   14236              :    expression:
   14237              :      assignment-expression
   14238              :      expression , assignment-expression
   14239              : */
   14240              : 
   14241              : static struct c_expr
   14242     55395620 : c_parser_expression (c_parser *parser)
   14243              : {
   14244     55395620 :   location_t tloc = c_parser_peek_token (parser)->location;
   14245     55395620 :   struct c_expr expr;
   14246     55395620 :   expr = c_parser_expr_no_commas (parser, NULL);
   14247     55395620 :   if (c_parser_next_token_is (parser, CPP_COMMA))
   14248        88593 :     expr = convert_lvalue_to_rvalue (tloc, expr, true, false);
   14249     55497395 :   while (c_parser_next_token_is (parser, CPP_COMMA))
   14250              :     {
   14251       101775 :       struct c_expr next;
   14252       101775 :       tree lhsval;
   14253       101775 :       location_t loc = c_parser_peek_token (parser)->location;
   14254       101775 :       location_t expr_loc;
   14255       101775 :       c_parser_consume_token (parser);
   14256       101775 :       expr_loc = c_parser_peek_token (parser)->location;
   14257       101775 :       lhsval = expr.value;
   14258       101775 :       while (TREE_CODE (lhsval) == COMPOUND_EXPR
   14259       115811 :              || TREE_CODE (lhsval) == NOP_EXPR)
   14260              :         {
   14261        14036 :           if (TREE_CODE (lhsval) == COMPOUND_EXPR)
   14262        13938 :             lhsval = TREE_OPERAND (lhsval, 1);
   14263              :           else
   14264           98 :             lhsval = TREE_OPERAND (lhsval, 0);
   14265              :         }
   14266       101775 :       if (DECL_P (lhsval) || handled_component_p (lhsval))
   14267           89 :         mark_exp_read (lhsval);
   14268       101775 :       if (c_parser_next_token_is (parser, CPP_EMBED))
   14269              :         {
   14270              :           /* Users aren't interested in milions of -Wunused-value
   14271              :              warnings when using #embed inside of a comma expression,
   14272              :              and one CPP_NUMBER plus CPP_COMMA before it and one
   14273              :              CPP_COMMA plus CPP_NUMBER after it is guaranteed by
   14274              :              the preprocessor.  Thus, parse the whole CPP_EMBED just
   14275              :              as a single INTEGER_CST, the last byte in it.  */
   14276            1 :           c_token *embed = c_parser_peek_token (parser);
   14277            1 :           tree val = embed->value;
   14278            1 :           unsigned last = RAW_DATA_LENGTH (val) - 1;
   14279            1 :           next.value = build_int_cst (TREE_TYPE (val),
   14280            1 :                                       RAW_DATA_UCHAR_ELT (val, last));
   14281            1 :           next.original_type = integer_type_node;
   14282            1 :           c_parser_consume_token (parser);
   14283              :         }
   14284              :       else
   14285              :         {
   14286       101774 :           next = c_parser_expr_no_commas (parser, NULL);
   14287       101774 :           next = convert_lvalue_to_rvalue (expr_loc, next, true, false);
   14288              :         }
   14289       101775 :       expr.value = build_compound_expr (loc, expr.value, next.value);
   14290       101775 :       expr.original_code = COMPOUND_EXPR;
   14291       101775 :       expr.original_type = next.original_type;
   14292       101775 :       expr.m_decimal = 0;
   14293              :     }
   14294     55395620 :   return expr;
   14295              : }
   14296              : 
   14297              : /* Parse an expression and convert functions or arrays to pointers and
   14298              :    lvalues to rvalues.  */
   14299              : 
   14300              : static struct c_expr
   14301     42364664 : c_parser_expression_conv (c_parser *parser)
   14302              : {
   14303     42364664 :   struct c_expr expr;
   14304     42364664 :   location_t loc = c_parser_peek_token (parser)->location;
   14305     42364664 :   expr = c_parser_expression (parser);
   14306     42364664 :   expr = convert_lvalue_to_rvalue (loc, expr, true, false);
   14307     42364664 :   return expr;
   14308              : }
   14309              : 
   14310              : /* Helper function of c_parser_expr_list.  Check if IDXth (0 based)
   14311              :    argument is a literal zero alone and if so, set it in literal_zero_mask.  */
   14312              : 
   14313              : static inline void
   14314    126043522 : c_parser_check_literal_zero (c_parser *parser, unsigned *literal_zero_mask,
   14315              :                              unsigned int idx)
   14316              : {
   14317    126043522 :   if (idx >= HOST_BITS_PER_INT)
   14318              :     return;
   14319              : 
   14320    126021497 :   c_token *tok = c_parser_peek_token (parser);
   14321    126021497 :   switch (tok->type)
   14322              :     {
   14323      6887805 :     case CPP_NUMBER:
   14324      6887805 :     case CPP_CHAR:
   14325      6887805 :     case CPP_WCHAR:
   14326      6887805 :     case CPP_CHAR16:
   14327      6887805 :     case CPP_CHAR32:
   14328      6887805 :     case CPP_UTF8CHAR:
   14329              :       /* If a parameter is literal zero alone, remember it
   14330              :          for -Wmemset-transposed-args warning.  */
   14331      6887805 :       if (integer_zerop (tok->value)
   14332      1260920 :           && !TREE_OVERFLOW (tok->value)
   14333      8148725 :           && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
   14334       873608 :               || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
   14335      1260086 :         *literal_zero_mask |= 1U << idx;
   14336              :     default:
   14337              :       break;
   14338              :     }
   14339              : }
   14340              : 
   14341              : /* Parse a non-empty list of expressions.  If CONVERT_P, convert
   14342              :    functions and arrays to pointers and lvalues to rvalues.  If
   14343              :    FOLD_P, fold the expressions.  If LOCATIONS is non-NULL, save the
   14344              :    locations of function arguments into this vector.
   14345              : 
   14346              :    nonempty-expr-list:
   14347              :      assignment-expression
   14348              :      nonempty-expr-list , assignment-expression
   14349              : */
   14350              : 
   14351              : static vec<tree, va_gc> *
   14352     42502436 : c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p,
   14353              :                     vec<tree, va_gc> **p_orig_types,
   14354              :                     location_t *sizeof_arg_loc, tree *sizeof_arg,
   14355              :                     vec<location_t> *locations,
   14356              :                     unsigned int *literal_zero_mask)
   14357              : {
   14358     42502436 :   vec<tree, va_gc> *ret;
   14359     42502436 :   vec<tree, va_gc> *orig_types;
   14360     42502436 :   struct c_expr expr;
   14361     42502436 :   unsigned int idx = 0;
   14362     42502436 :   bool save_c_omp_array_section_p = c_omp_array_section_p;
   14363     42502436 :   c_omp_array_section_p = false;
   14364              : 
   14365     42502436 :   ret = make_tree_vector ();
   14366     42502436 :   if (p_orig_types == NULL)
   14367      4484876 :     orig_types = NULL;
   14368              :   else
   14369     38017560 :     orig_types = make_tree_vector ();
   14370              : 
   14371     42502436 :   if (literal_zero_mask)
   14372     38017560 :     c_parser_check_literal_zero (parser, literal_zero_mask, 0);
   14373     42502436 :   expr = c_parser_expr_no_commas (parser, NULL);
   14374     42502436 :   if (convert_p)
   14375     38018031 :     expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true, true);
   14376     42502436 :   if (fold_p)
   14377      4484876 :     expr.value = c_fully_fold (expr.value, false, NULL);
   14378     42502436 :   ret->quick_push (expr.value);
   14379     42502436 :   if (orig_types)
   14380     38017560 :     orig_types->quick_push (expr.original_type);
   14381     42502436 :   if (locations)
   14382     38017560 :     locations->safe_push (expr.get_location ());
   14383     42502436 :   if (sizeof_arg != NULL
   14384     38017560 :       && (expr.original_code == SIZEOF_EXPR
   14385     38017560 :           || expr.original_code == PAREN_SIZEOF_EXPR))
   14386              :     {
   14387         2115 :       sizeof_arg[0] = c_last_sizeof_arg;
   14388         2115 :       sizeof_arg_loc[0] = c_last_sizeof_loc;
   14389              :     }
   14390    131865522 :   while (c_parser_next_token_is (parser, CPP_COMMA))
   14391              :     {
   14392     89363086 :       c_parser_consume_token (parser);
   14393     89363086 :       if (c_parser_next_token_is (parser, CPP_EMBED))
   14394              :         {
   14395            3 :           c_token *embed = c_parser_peek_token (parser);
   14396            3 :           tree value = embed->value;
   14397            3 :           expr.original_code = INTEGER_CST;
   14398            3 :           expr.original_type = integer_type_node;
   14399            3 :           expr.value = NULL_TREE;
   14400            3 :           set_c_expr_source_range (&expr, embed->get_range ());
   14401            3 :           expr.m_decimal = 0;
   14402          381 :           for (unsigned int i = 0; i < (unsigned) RAW_DATA_LENGTH (value); i++)
   14403              :             {
   14404          378 :               if (literal_zero_mask
   14405          126 :                   && idx + 1 < HOST_BITS_PER_INT
   14406          409 :                   && RAW_DATA_POINTER (value)[i] == 0)
   14407            0 :                 *literal_zero_mask |= 1U << (idx + 1);
   14408          378 :               expr.value = build_int_cst (integer_type_node,
   14409          378 :                                           RAW_DATA_UCHAR_ELT (value, i));
   14410          378 :               vec_safe_push (ret, expr.value);
   14411          378 :               if (orig_types)
   14412          126 :                 vec_safe_push (orig_types, expr.original_type);
   14413          378 :               if (locations)
   14414          126 :                 locations->safe_push (expr.get_location ());
   14415          378 :               ++idx;
   14416              :             }
   14417            3 :           c_parser_consume_token (parser);
   14418            3 :           continue;
   14419            3 :         }
   14420     89363083 :       if (literal_zero_mask)
   14421     88025962 :         c_parser_check_literal_zero (parser, literal_zero_mask, idx + 1);
   14422     89363083 :       expr = c_parser_expr_no_commas (parser, NULL);
   14423     89363083 :       if (convert_p)
   14424     88026228 :         expr = convert_lvalue_to_rvalue (expr.get_location (), expr, true,
   14425              :                                          true);
   14426     89363083 :       if (fold_p)
   14427      1337121 :         expr.value = c_fully_fold (expr.value, false, NULL);
   14428     89363083 :       vec_safe_push (ret, expr.value);
   14429     89363083 :       if (orig_types)
   14430     88025962 :         vec_safe_push (orig_types, expr.original_type);
   14431     89363083 :       if (locations)
   14432     88025962 :         locations->safe_push (expr.get_location ());
   14433     89363083 :       if (++idx < 6
   14434     87814569 :           && sizeof_arg != NULL
   14435     89363083 :           && (expr.original_code == SIZEOF_EXPR
   14436     86477462 :               || expr.original_code == PAREN_SIZEOF_EXPR))
   14437              :         {
   14438        79108 :           sizeof_arg[idx] = c_last_sizeof_arg;
   14439        79108 :           sizeof_arg_loc[idx] = c_last_sizeof_loc;
   14440              :         }
   14441              :     }
   14442     42502436 :   if (orig_types)
   14443     38017560 :     *p_orig_types = orig_types;
   14444     42502436 :   c_omp_array_section_p = save_c_omp_array_section_p;
   14445     42502436 :   return ret;
   14446              : }
   14447              : 
   14448              : /* Parse Objective-C-specific constructs.  */
   14449              : 
   14450              : /* Parse an objc-class-definition.
   14451              : 
   14452              :    objc-class-definition:
   14453              :      @interface identifier objc-superclass[opt] objc-protocol-refs[opt]
   14454              :        objc-class-instance-variables[opt] objc-methodprotolist @end
   14455              :      @implementation identifier objc-superclass[opt]
   14456              :        objc-class-instance-variables[opt]
   14457              :      @interface identifier ( identifier ) objc-protocol-refs[opt]
   14458              :        objc-methodprotolist @end
   14459              :      @interface identifier ( ) objc-protocol-refs[opt]
   14460              :        objc-methodprotolist @end
   14461              :      @implementation identifier ( identifier )
   14462              : 
   14463              :    objc-superclass:
   14464              :      : identifier
   14465              : 
   14466              :    "@interface identifier (" must start "@interface identifier (
   14467              :    identifier ) ...": objc-methodprotolist in the first production may
   14468              :    not start with a parenthesized identifier as a declarator of a data
   14469              :    definition with no declaration specifiers if the objc-superclass,
   14470              :    objc-protocol-refs and objc-class-instance-variables are omitted.  */
   14471              : 
   14472              : static void
   14473            0 : c_parser_objc_class_definition (c_parser *parser, tree attributes)
   14474              : {
   14475            0 :   bool iface_p;
   14476            0 :   tree id1;
   14477            0 :   tree superclass;
   14478            0 :   if (c_parser_next_token_is_keyword (parser, RID_AT_INTERFACE))
   14479              :     iface_p = true;
   14480            0 :   else if (c_parser_next_token_is_keyword (parser, RID_AT_IMPLEMENTATION))
   14481              :     iface_p = false;
   14482              :   else
   14483            0 :     gcc_unreachable ();
   14484              : 
   14485            0 :   c_parser_consume_token (parser);
   14486            0 :   if (c_parser_next_token_is_not (parser, CPP_NAME))
   14487              :     {
   14488            0 :       c_parser_error (parser, "expected identifier");
   14489            0 :       return;
   14490              :     }
   14491            0 :   id1 = c_parser_peek_token (parser)->value;
   14492            0 :   location_t loc1 = c_parser_peek_token (parser)->location;
   14493            0 :   c_parser_consume_token (parser);
   14494            0 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   14495              :     {
   14496              :       /* We have a category or class extension.  */
   14497            0 :       tree id2;
   14498            0 :       tree proto = NULL_TREE;
   14499            0 :       matching_parens parens;
   14500            0 :       parens.consume_open (parser);
   14501            0 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   14502              :         {
   14503            0 :           if (iface_p && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   14504              :             {
   14505              :               /* We have a class extension.  */
   14506              :               id2 = NULL_TREE;
   14507              :             }
   14508              :           else
   14509              :             {
   14510            0 :               c_parser_error (parser, "expected identifier or %<)%>");
   14511            0 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   14512            0 :               return;
   14513              :             }
   14514              :         }
   14515              :       else
   14516              :         {
   14517            0 :           id2 = c_parser_peek_token (parser)->value;
   14518            0 :           c_parser_consume_token (parser);
   14519              :         }
   14520            0 :       parens.skip_until_found_close (parser);
   14521            0 :       if (!iface_p)
   14522              :         {
   14523            0 :           objc_start_category_implementation (id1, id2);
   14524            0 :           return;
   14525              :         }
   14526            0 :       if (c_parser_next_token_is (parser, CPP_LESS))
   14527            0 :         proto = c_parser_objc_protocol_refs (parser);
   14528            0 :       objc_start_category_interface (id1, id2, proto, attributes);
   14529            0 :       c_parser_objc_methodprotolist (parser);
   14530            0 :       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
   14531            0 :       objc_finish_interface ();
   14532            0 :       return;
   14533              :     }
   14534            0 :   if (c_parser_next_token_is (parser, CPP_COLON))
   14535              :     {
   14536            0 :       c_parser_consume_token (parser);
   14537            0 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   14538              :         {
   14539            0 :           c_parser_error (parser, "expected identifier");
   14540            0 :           return;
   14541              :         }
   14542            0 :       superclass = c_parser_peek_token (parser)->value;
   14543            0 :       c_parser_consume_token (parser);
   14544              :     }
   14545              :   else
   14546              :     superclass = NULL_TREE;
   14547            0 :   if (iface_p)
   14548              :     {
   14549            0 :       tree proto = NULL_TREE;
   14550            0 :       if (c_parser_next_token_is (parser, CPP_LESS))
   14551            0 :         proto = c_parser_objc_protocol_refs (parser);
   14552            0 :       objc_start_class_interface (id1, loc1, superclass, proto, attributes);
   14553              :     }
   14554              :   else
   14555            0 :     objc_start_class_implementation (id1, superclass);
   14556            0 :   if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   14557            0 :     c_parser_objc_class_instance_variables (parser);
   14558            0 :   if (iface_p)
   14559              :     {
   14560            0 :       objc_continue_interface ();
   14561            0 :       c_parser_objc_methodprotolist (parser);
   14562            0 :       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
   14563            0 :       objc_finish_interface ();
   14564              :     }
   14565              :   else
   14566              :     {
   14567            0 :       objc_continue_implementation ();
   14568            0 :       return;
   14569              :     }
   14570              : }
   14571              : 
   14572              : /* Parse objc-class-instance-variables.
   14573              : 
   14574              :    objc-class-instance-variables:
   14575              :      { objc-instance-variable-decl-list[opt] }
   14576              : 
   14577              :    objc-instance-variable-decl-list:
   14578              :      objc-visibility-spec
   14579              :      objc-instance-variable-decl ;
   14580              :      ;
   14581              :      objc-instance-variable-decl-list objc-visibility-spec
   14582              :      objc-instance-variable-decl-list objc-instance-variable-decl ;
   14583              :      objc-instance-variable-decl-list ;
   14584              : 
   14585              :    objc-visibility-spec:
   14586              :      @private
   14587              :      @protected
   14588              :      @public
   14589              : 
   14590              :    objc-instance-variable-decl:
   14591              :      struct-declaration
   14592              : */
   14593              : 
   14594              : static void
   14595            0 : c_parser_objc_class_instance_variables (c_parser *parser)
   14596              : {
   14597            0 :   gcc_assert (c_parser_next_token_is (parser, CPP_OPEN_BRACE));
   14598            0 :   c_parser_consume_token (parser);
   14599            0 :   while (c_parser_next_token_is_not (parser, CPP_EOF))
   14600              :     {
   14601            0 :       tree decls;
   14602              :       /* Parse any stray semicolon.  */
   14603            0 :       if (c_parser_next_token_is (parser, CPP_SEMICOLON))
   14604              :         {
   14605            0 :           pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
   14606              :                    "extra semicolon");
   14607            0 :           c_parser_consume_token (parser);
   14608            0 :           continue;
   14609              :         }
   14610              :       /* Stop if at the end of the instance variables.  */
   14611            0 :       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   14612              :         {
   14613            0 :           c_parser_consume_token (parser);
   14614            0 :           break;
   14615              :         }
   14616              :       /* Parse any objc-visibility-spec.  */
   14617            0 :       if (c_parser_next_token_is_keyword (parser, RID_AT_PRIVATE))
   14618              :         {
   14619            0 :           c_parser_consume_token (parser);
   14620            0 :           objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
   14621            0 :           continue;
   14622              :         }
   14623            0 :       else if (c_parser_next_token_is_keyword (parser, RID_AT_PROTECTED))
   14624              :         {
   14625            0 :           c_parser_consume_token (parser);
   14626            0 :           objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
   14627            0 :           continue;
   14628              :         }
   14629            0 :       else if (c_parser_next_token_is_keyword (parser, RID_AT_PUBLIC))
   14630              :         {
   14631            0 :           c_parser_consume_token (parser);
   14632            0 :           objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
   14633            0 :           continue;
   14634              :         }
   14635            0 :       else if (c_parser_next_token_is_keyword (parser, RID_AT_PACKAGE))
   14636              :         {
   14637            0 :           c_parser_consume_token (parser);
   14638            0 :           objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
   14639            0 :           continue;
   14640              :         }
   14641            0 :       else if (c_parser_next_token_is (parser, CPP_PRAGMA))
   14642              :         {
   14643            0 :           c_parser_pragma (parser, pragma_external, NULL, NULL_TREE);
   14644            0 :           continue;
   14645              :         }
   14646              : 
   14647              :       /* Parse some comma-separated declarations.  */
   14648            0 :       decls = c_parser_struct_declaration (parser, NULL);
   14649            0 :       if (decls == NULL)
   14650              :         {
   14651              :           /* There is a syntax error.  We want to skip the offending
   14652              :              tokens up to the next ';' (included) or '}'
   14653              :              (excluded).  */
   14654              : 
   14655              :           /* First, skip manually a ')' or ']'.  This is because they
   14656              :              reduce the nesting level, so c_parser_skip_until_found()
   14657              :              wouldn't be able to skip past them.  */
   14658            0 :           c_token *token = c_parser_peek_token (parser);
   14659            0 :           if (token->type == CPP_CLOSE_PAREN || token->type == CPP_CLOSE_SQUARE)
   14660            0 :             c_parser_consume_token (parser);
   14661              : 
   14662              :           /* Then, do the standard skipping.  */
   14663            0 :           c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   14664              : 
   14665              :           /* We hopefully recovered.  Start normal parsing again.  */
   14666            0 :           parser->error = false;
   14667            0 :           continue;
   14668            0 :         }
   14669              :       else
   14670              :         {
   14671              :           /* Comma-separated instance variables are chained together
   14672              :              in reverse order; add them one by one.  */
   14673            0 :           tree ivar = nreverse (decls);
   14674            0 :           for (; ivar; ivar = DECL_CHAIN (ivar))
   14675            0 :             objc_add_instance_variable (copy_node (ivar));
   14676              :         }
   14677            0 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   14678              :     }
   14679            0 : }
   14680              : 
   14681              : /* Parse an objc-class-declaration.
   14682              : 
   14683              :    objc-class-declaration:
   14684              :      @class identifier-list ;
   14685              : */
   14686              : 
   14687              : static void
   14688            0 : c_parser_objc_class_declaration (c_parser *parser)
   14689              : {
   14690            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_CLASS));
   14691            0 :   c_parser_consume_token (parser);
   14692              :   /* Any identifiers, including those declared as type names, are OK
   14693              :      here.  */
   14694            0 :   while (true)
   14695              :     {
   14696            0 :       tree id;
   14697            0 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   14698              :         {
   14699            0 :           c_parser_error (parser, "expected identifier");
   14700            0 :           c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   14701            0 :           parser->error = false;
   14702            0 :           return;
   14703              :         }
   14704            0 :       id = c_parser_peek_token (parser)->value;
   14705            0 :       objc_declare_class (id);
   14706            0 :       c_parser_consume_token (parser);
   14707            0 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   14708            0 :         c_parser_consume_token (parser);
   14709              :       else
   14710              :         break;
   14711            0 :     }
   14712            0 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   14713              : }
   14714              : 
   14715              : /* Parse an objc-alias-declaration.
   14716              : 
   14717              :    objc-alias-declaration:
   14718              :      @compatibility_alias identifier identifier ;
   14719              : */
   14720              : 
   14721              : static void
   14722            0 : c_parser_objc_alias_declaration (c_parser *parser)
   14723              : {
   14724            0 :   tree id1, id2;
   14725            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_ALIAS));
   14726            0 :   c_parser_consume_token (parser);
   14727            0 :   if (c_parser_next_token_is_not (parser, CPP_NAME))
   14728              :     {
   14729            0 :       c_parser_error (parser, "expected identifier");
   14730            0 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   14731            0 :       return;
   14732              :     }
   14733            0 :   id1 = c_parser_peek_token (parser)->value;
   14734            0 :   c_parser_consume_token (parser);
   14735            0 :   if (c_parser_next_token_is_not (parser, CPP_NAME))
   14736              :     {
   14737            0 :       c_parser_error (parser, "expected identifier");
   14738            0 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   14739            0 :       return;
   14740              :     }
   14741            0 :   id2 = c_parser_peek_token (parser)->value;
   14742            0 :   c_parser_consume_token (parser);
   14743            0 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   14744            0 :   objc_declare_alias (id1, id2);
   14745              : }
   14746              : 
   14747              : /* Parse an objc-protocol-definition.
   14748              : 
   14749              :    objc-protocol-definition:
   14750              :      @protocol identifier objc-protocol-refs[opt] objc-methodprotolist @end
   14751              :      @protocol identifier-list ;
   14752              : 
   14753              :    "@protocol identifier ;" should be resolved as "@protocol
   14754              :    identifier-list ;": objc-methodprotolist may not start with a
   14755              :    semicolon in the first alternative if objc-protocol-refs are
   14756              :    omitted.  */
   14757              : 
   14758              : static void
   14759            0 : c_parser_objc_protocol_definition (c_parser *parser, tree attributes)
   14760              : {
   14761            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROTOCOL));
   14762              : 
   14763            0 :   c_parser_consume_token (parser);
   14764            0 :   if (c_parser_next_token_is_not (parser, CPP_NAME))
   14765              :     {
   14766            0 :       c_parser_error (parser, "expected identifier");
   14767            0 :       return;
   14768              :     }
   14769            0 :   if (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
   14770            0 :       || c_parser_peek_2nd_token (parser)->type == CPP_SEMICOLON)
   14771              :     {
   14772              :       /* Any identifiers, including those declared as type names, are
   14773              :          OK here.  */
   14774            0 :       while (true)
   14775              :         {
   14776            0 :           tree id;
   14777            0 :           if (c_parser_next_token_is_not (parser, CPP_NAME))
   14778              :             {
   14779            0 :               c_parser_error (parser, "expected identifier");
   14780            0 :               break;
   14781              :             }
   14782            0 :           id = c_parser_peek_token (parser)->value;
   14783            0 :           objc_declare_protocol (id, attributes);
   14784            0 :           c_parser_consume_token (parser);
   14785            0 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   14786            0 :             c_parser_consume_token (parser);
   14787              :           else
   14788              :             break;
   14789            0 :         }
   14790            0 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   14791              :     }
   14792              :   else
   14793              :     {
   14794            0 :       tree id = c_parser_peek_token (parser)->value;
   14795            0 :       tree proto = NULL_TREE;
   14796            0 :       c_parser_consume_token (parser);
   14797            0 :       if (c_parser_next_token_is (parser, CPP_LESS))
   14798            0 :         proto = c_parser_objc_protocol_refs (parser);
   14799            0 :       parser->objc_pq_context = true;
   14800            0 :       objc_start_protocol (id, proto, attributes);
   14801            0 :       c_parser_objc_methodprotolist (parser);
   14802            0 :       c_parser_require_keyword (parser, RID_AT_END, "expected %<@end%>");
   14803            0 :       parser->objc_pq_context = false;
   14804            0 :       objc_finish_interface ();
   14805              :     }
   14806              : }
   14807              : 
   14808              : /* Parse an objc-method-type.
   14809              : 
   14810              :    objc-method-type:
   14811              :      +
   14812              :      -
   14813              : 
   14814              :    Return true if it is a class method (+) and false if it is
   14815              :    an instance method (-).
   14816              : */
   14817              : static inline bool
   14818            0 : c_parser_objc_method_type (c_parser *parser)
   14819              : {
   14820            0 :   switch (c_parser_peek_token (parser)->type)
   14821              :     {
   14822            0 :     case CPP_PLUS:
   14823            0 :       c_parser_consume_token (parser);
   14824            0 :       return true;
   14825            0 :     case CPP_MINUS:
   14826            0 :       c_parser_consume_token (parser);
   14827            0 :       return false;
   14828            0 :     default:
   14829            0 :       gcc_unreachable ();
   14830              :     }
   14831              : }
   14832              : 
   14833              : /* Parse an objc-method-definition.
   14834              : 
   14835              :    objc-method-definition:
   14836              :      objc-method-type objc-method-decl ;[opt] compound-statement
   14837              : */
   14838              : 
   14839              : static void
   14840            0 : c_parser_objc_method_definition (c_parser *parser)
   14841              : {
   14842            0 :   bool is_class_method = c_parser_objc_method_type (parser);
   14843            0 :   tree decl, attributes = NULL_TREE, expr = NULL_TREE;
   14844            0 :   parser->objc_pq_context = true;
   14845            0 :   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
   14846              :                                     &expr);
   14847            0 :   if (decl == error_mark_node)
   14848            0 :     return;  /* Bail here. */
   14849              : 
   14850            0 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
   14851              :     {
   14852            0 :       c_parser_consume_token (parser);
   14853            0 :       pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
   14854              :                "extra semicolon in method definition specified");
   14855              :     }
   14856              : 
   14857            0 :   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   14858              :     {
   14859            0 :       c_parser_error (parser, "expected %<{%>");
   14860            0 :       return;
   14861              :     }
   14862              : 
   14863            0 :   parser->objc_pq_context = false;
   14864            0 :   if (objc_start_method_definition (is_class_method, decl, attributes, expr))
   14865              :     {
   14866            0 :       add_stmt (c_parser_compound_statement (parser));
   14867            0 :       objc_finish_method_definition (current_function_decl);
   14868              :     }
   14869              :   else
   14870              :     {
   14871              :       /* This code is executed when we find a method definition
   14872              :          outside of an @implementation context (or invalid for other
   14873              :          reasons).  Parse the method (to keep going) but do not emit
   14874              :          any code.
   14875              :       */
   14876            0 :       c_parser_compound_statement (parser);
   14877              :     }
   14878              : }
   14879              : 
   14880              : /* Parse an objc-methodprotolist.
   14881              : 
   14882              :    objc-methodprotolist:
   14883              :      empty
   14884              :      objc-methodprotolist objc-methodproto
   14885              :      objc-methodprotolist declaration
   14886              :      objc-methodprotolist ;
   14887              :      @optional
   14888              :      @required
   14889              : 
   14890              :    The declaration is a data definition, which may be missing
   14891              :    declaration specifiers under the same rules and diagnostics as
   14892              :    other data definitions outside functions, and the stray semicolon
   14893              :    is diagnosed the same way as a stray semicolon outside a
   14894              :    function.  */
   14895              : 
   14896              : static void
   14897            0 : c_parser_objc_methodprotolist (c_parser *parser)
   14898              : {
   14899            0 :   while (true)
   14900              :     {
   14901              :       /* The list is terminated by @end.  */
   14902            0 :       switch (c_parser_peek_token (parser)->type)
   14903              :         {
   14904            0 :         case CPP_SEMICOLON:
   14905            0 :           pedwarn (c_parser_peek_token (parser)->location, OPT_Wpedantic,
   14906              :                    "ISO C does not allow extra %<;%> outside of a function");
   14907            0 :           c_parser_consume_token (parser);
   14908            0 :           break;
   14909            0 :         case CPP_PLUS:
   14910            0 :         case CPP_MINUS:
   14911            0 :           c_parser_objc_methodproto (parser);
   14912            0 :           break;
   14913            0 :         case CPP_PRAGMA:
   14914            0 :           c_parser_pragma (parser, pragma_external, NULL, NULL_TREE);
   14915            0 :           break;
   14916              :         case CPP_EOF:
   14917              :           return;
   14918            0 :         default:
   14919            0 :           if (c_parser_next_token_is_keyword (parser, RID_AT_END))
   14920              :             return;
   14921            0 :           else if (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY))
   14922            0 :             c_parser_objc_at_property_declaration (parser);
   14923            0 :           else if (c_parser_next_token_is_keyword (parser, RID_AT_OPTIONAL))
   14924              :             {
   14925            0 :               objc_set_method_opt (true);
   14926            0 :               c_parser_consume_token (parser);
   14927              :             }
   14928            0 :           else if (c_parser_next_token_is_keyword (parser, RID_AT_REQUIRED))
   14929              :             {
   14930            0 :               objc_set_method_opt (false);
   14931            0 :               c_parser_consume_token (parser);
   14932              :             }
   14933              :           else
   14934            0 :             c_parser_declaration_or_fndef (parser, false, false, true,
   14935              :                                            false, true, false);
   14936              :           break;
   14937              :         }
   14938              :     }
   14939              : }
   14940              : 
   14941              : /* Parse an objc-methodproto.
   14942              : 
   14943              :    objc-methodproto:
   14944              :      objc-method-type objc-method-decl ;
   14945              : */
   14946              : 
   14947              : static void
   14948            0 : c_parser_objc_methodproto (c_parser *parser)
   14949              : {
   14950            0 :   bool is_class_method = c_parser_objc_method_type (parser);
   14951            0 :   tree decl, attributes = NULL_TREE;
   14952              : 
   14953              :   /* Remember protocol qualifiers in prototypes.  */
   14954            0 :   parser->objc_pq_context = true;
   14955            0 :   decl = c_parser_objc_method_decl (parser, is_class_method, &attributes,
   14956              :                                     NULL);
   14957              :   /* Forget protocol qualifiers now.  */
   14958            0 :   parser->objc_pq_context = false;
   14959              : 
   14960              :   /* Do not allow the presence of attributes to hide an erroneous
   14961              :      method implementation in the interface section.  */
   14962            0 :   if (!c_parser_next_token_is (parser, CPP_SEMICOLON))
   14963              :     {
   14964            0 :       c_parser_error (parser, "expected %<;%>");
   14965            0 :       return;
   14966              :     }
   14967              : 
   14968            0 :   if (decl != error_mark_node)
   14969            0 :     objc_add_method_declaration (is_class_method, decl, attributes);
   14970              : 
   14971            0 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   14972              : }
   14973              : 
   14974              : /* If we are at a position that method attributes may be present, check that
   14975              :    there are not any parsed already (a syntax error) and then collect any
   14976              :    specified at the current location.  Finally, if new attributes were present,
   14977              :    check that the next token is legal ( ';' for decls and '{' for defs).  */
   14978              : 
   14979              : static bool
   14980            0 : c_parser_objc_maybe_method_attributes (c_parser* parser, tree* attributes)
   14981              : {
   14982            0 :   bool bad = false;
   14983            0 :   if (*attributes)
   14984              :     {
   14985            0 :       c_parser_error (parser,
   14986              :                     "method attributes must be specified at the end only");
   14987            0 :       *attributes = NULL_TREE;
   14988            0 :       bad = true;
   14989              :     }
   14990              : 
   14991            0 :   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
   14992            0 :     *attributes = c_parser_gnu_attributes (parser);
   14993              : 
   14994              :   /* If there were no attributes here, just report any earlier error.  */
   14995            0 :   if (*attributes == NULL_TREE || bad)
   14996              :     return bad;
   14997              : 
   14998              :   /* If the attributes are followed by a ; or {, then just report any earlier
   14999              :      error.  */
   15000            0 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON)
   15001            0 :       || c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   15002            0 :     return bad;
   15003              : 
   15004              :   /* We've got attributes, but not at the end.  */
   15005            0 :   c_parser_error (parser,
   15006              :                   "expected %<;%> or %<{%> after method attribute definition");
   15007            0 :   return true;
   15008              : }
   15009              : 
   15010              : /* Parse an objc-method-decl.
   15011              : 
   15012              :    objc-method-decl:
   15013              :      ( objc-type-name ) objc-selector
   15014              :      objc-selector
   15015              :      ( objc-type-name ) objc-keyword-selector objc-optparmlist
   15016              :      objc-keyword-selector objc-optparmlist
   15017              :      gnu-attributes
   15018              : 
   15019              :    objc-keyword-selector:
   15020              :      objc-keyword-decl
   15021              :      objc-keyword-selector objc-keyword-decl
   15022              : 
   15023              :    objc-keyword-decl:
   15024              :      objc-selector : ( objc-type-name ) identifier
   15025              :      objc-selector : identifier
   15026              :      : ( objc-type-name ) identifier
   15027              :      : identifier
   15028              : 
   15029              :    objc-optparmlist:
   15030              :      objc-optparms objc-optellipsis
   15031              : 
   15032              :    objc-optparms:
   15033              :      empty
   15034              :      objc-opt-parms , parameter-declaration
   15035              : 
   15036              :    objc-optellipsis:
   15037              :      empty
   15038              :      , ...
   15039              : */
   15040              : 
   15041              : static tree
   15042            0 : c_parser_objc_method_decl (c_parser *parser, bool is_class_method,
   15043              :                            tree *attributes, tree *expr)
   15044              : {
   15045            0 :   tree type = NULL_TREE;
   15046            0 :   tree sel;
   15047            0 :   tree parms = NULL_TREE;
   15048            0 :   bool ellipsis = false;
   15049            0 :   bool attr_err = false;
   15050              : 
   15051            0 :   *attributes = NULL_TREE;
   15052            0 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   15053              :     {
   15054            0 :       matching_parens parens;
   15055            0 :       parens.consume_open (parser);
   15056            0 :       type = c_parser_objc_type_name (parser);
   15057            0 :       parens.skip_until_found_close (parser);
   15058              :     }
   15059            0 :   sel = c_parser_objc_selector (parser);
   15060              :   /* If there is no selector, or a colon follows, we have an
   15061              :      objc-keyword-selector.  If there is a selector, and a colon does
   15062              :      not follow, that selector ends the objc-method-decl.  */
   15063            0 :   if (!sel || c_parser_next_token_is (parser, CPP_COLON))
   15064              :     {
   15065              :       tree tsel = sel;
   15066              :       tree list = NULL_TREE;
   15067            0 :       while (true)
   15068              :         {
   15069            0 :           tree atype = NULL_TREE, id, keyworddecl;
   15070            0 :           tree param_attr = NULL_TREE;
   15071            0 :           if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   15072              :             break;
   15073            0 :           if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   15074              :             {
   15075            0 :               c_parser_consume_token (parser);
   15076            0 :               atype = c_parser_objc_type_name (parser);
   15077            0 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   15078              :                                          "expected %<)%>");
   15079              :             }
   15080              :           /* New ObjC allows attributes on method parameters.  */
   15081            0 :           if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
   15082            0 :             param_attr = c_parser_gnu_attributes (parser);
   15083            0 :           if (c_parser_next_token_is_not (parser, CPP_NAME))
   15084              :             {
   15085            0 :               c_parser_error (parser, "expected identifier");
   15086            0 :               return error_mark_node;
   15087              :             }
   15088            0 :           id = c_parser_peek_token (parser)->value;
   15089            0 :           c_parser_consume_token (parser);
   15090            0 :           keyworddecl = objc_build_keyword_decl (tsel, atype, id, param_attr);
   15091            0 :           list = chainon (list, keyworddecl);
   15092            0 :           tsel = c_parser_objc_selector (parser);
   15093            0 :           if (!tsel && c_parser_next_token_is_not (parser, CPP_COLON))
   15094              :             break;
   15095              :         }
   15096              : 
   15097            0 :       attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
   15098              : 
   15099              :       /* Parse the optional parameter list.  Optional Objective-C
   15100              :          method parameters follow the C syntax, and may include '...'
   15101              :          to denote a variable number of arguments.  */
   15102            0 :       parms = make_node (TREE_LIST);
   15103            0 :       while (c_parser_next_token_is (parser, CPP_COMMA))
   15104              :         {
   15105            0 :           struct c_parm *parm;
   15106            0 :           c_parser_consume_token (parser);
   15107            0 :           if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
   15108              :             {
   15109            0 :               ellipsis = true;
   15110            0 :               c_parser_consume_token (parser);
   15111            0 :               attr_err |= c_parser_objc_maybe_method_attributes
   15112            0 :                                                 (parser, attributes) ;
   15113            0 :               break;
   15114              :             }
   15115            0 :           parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
   15116            0 :           if (parm == NULL)
   15117              :             break;
   15118            0 :           parms = chainon (parms,
   15119              :                            build_tree_list (NULL_TREE, grokparm (parm, expr)));
   15120              :         }
   15121              :       sel = list;
   15122              :     }
   15123              :   else
   15124            0 :     attr_err |= c_parser_objc_maybe_method_attributes (parser, attributes) ;
   15125              : 
   15126            0 :   if (sel == NULL)
   15127              :     {
   15128            0 :       c_parser_error (parser, "objective-c method declaration is expected");
   15129            0 :       return error_mark_node;
   15130              :     }
   15131              : 
   15132            0 :   if (attr_err)
   15133            0 :     return error_mark_node;
   15134              : 
   15135            0 :   return objc_build_method_signature (is_class_method, type, sel, parms, ellipsis);
   15136              : }
   15137              : 
   15138              : /* Parse an objc-type-name.
   15139              : 
   15140              :    objc-type-name:
   15141              :      objc-type-qualifiers[opt] type-name
   15142              :      objc-type-qualifiers[opt]
   15143              : 
   15144              :    objc-type-qualifiers:
   15145              :      objc-type-qualifier
   15146              :      objc-type-qualifiers objc-type-qualifier
   15147              : 
   15148              :    objc-type-qualifier: one of
   15149              :      in out inout bycopy byref oneway
   15150              : */
   15151              : 
   15152              : static tree
   15153            0 : c_parser_objc_type_name (c_parser *parser)
   15154              : {
   15155            0 :   tree quals = NULL_TREE;
   15156            0 :   struct c_type_name *type_name = NULL;
   15157            0 :   tree type = NULL_TREE;
   15158            0 :   while (true)
   15159              :     {
   15160            0 :       c_token *token = c_parser_peek_token (parser);
   15161            0 :       if (token->type == CPP_KEYWORD
   15162            0 :           && (token->keyword == RID_IN
   15163              :               || token->keyword == RID_OUT
   15164              :               || token->keyword == RID_INOUT
   15165              :               || token->keyword == RID_BYCOPY
   15166              :               || token->keyword == RID_BYREF
   15167            0 :               || token->keyword == RID_ONEWAY))
   15168              :         {
   15169            0 :           quals = chainon (build_tree_list (NULL_TREE, token->value), quals);
   15170            0 :           c_parser_consume_token (parser);
   15171              :         }
   15172              :       else
   15173              :         break;
   15174            0 :     }
   15175            0 :   if (c_parser_next_tokens_start_typename (parser, cla_prefer_type))
   15176            0 :     type_name = c_parser_type_name (parser);
   15177            0 :   if (type_name)
   15178            0 :     type = groktypename (type_name, NULL, NULL);
   15179              : 
   15180              :   /* If the type is unknown, and error has already been produced and
   15181              :      we need to recover from the error.  In that case, use NULL_TREE
   15182              :      for the type, as if no type had been specified; this will use the
   15183              :      default type ('id') which is good for error recovery.  */
   15184            0 :   if (type == error_mark_node)
   15185            0 :     type = NULL_TREE;
   15186              : 
   15187            0 :   return build_tree_list (quals, type);
   15188              : }
   15189              : 
   15190              : /* Parse objc-protocol-refs.
   15191              : 
   15192              :    objc-protocol-refs:
   15193              :      < identifier-list >
   15194              : */
   15195              : 
   15196              : static tree
   15197            0 : c_parser_objc_protocol_refs (c_parser *parser)
   15198              : {
   15199            0 :   tree list = NULL_TREE;
   15200            0 :   gcc_assert (c_parser_next_token_is (parser, CPP_LESS));
   15201            0 :   c_parser_consume_token (parser);
   15202              :   /* Any identifiers, including those declared as type names, are OK
   15203              :      here.  */
   15204            0 :   while (true)
   15205              :     {
   15206            0 :       tree id;
   15207            0 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   15208              :         {
   15209            0 :           c_parser_error (parser, "expected identifier");
   15210            0 :           break;
   15211              :         }
   15212            0 :       id = c_parser_peek_token (parser)->value;
   15213            0 :       list = chainon (list, build_tree_list (NULL_TREE, id));
   15214            0 :       c_parser_consume_token (parser);
   15215            0 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   15216            0 :         c_parser_consume_token (parser);
   15217              :       else
   15218              :         break;
   15219            0 :     }
   15220            0 :   c_parser_require (parser, CPP_GREATER, "expected %<>%>");
   15221            0 :   return list;
   15222              : }
   15223              : 
   15224              : /* Parse an objc-try-catch-finally-statement.
   15225              : 
   15226              :    objc-try-catch-finally-statement:
   15227              :      @try compound-statement objc-catch-list[opt]
   15228              :      @try compound-statement objc-catch-list[opt] @finally compound-statement
   15229              : 
   15230              :    objc-catch-list:
   15231              :      @catch ( objc-catch-parameter-declaration ) compound-statement
   15232              :      objc-catch-list @catch ( objc-catch-parameter-declaration ) compound-statement
   15233              : 
   15234              :    objc-catch-parameter-declaration:
   15235              :      parameter-declaration
   15236              :      '...'
   15237              : 
   15238              :    where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.
   15239              : 
   15240              :    PS: This function is identical to cp_parser_objc_try_catch_finally_statement
   15241              :    for C++.  Keep them in sync.  */
   15242              : 
   15243              : static void
   15244            0 : c_parser_objc_try_catch_finally_statement (c_parser *parser)
   15245              : {
   15246            0 :   location_t location;
   15247            0 :   tree stmt;
   15248              : 
   15249            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_TRY));
   15250            0 :   c_parser_consume_token (parser);
   15251            0 :   location = c_parser_peek_token (parser)->location;
   15252            0 :   objc_maybe_warn_exceptions (location);
   15253            0 :   stmt = c_parser_compound_statement (parser);
   15254            0 :   objc_begin_try_stmt (location, stmt);
   15255              : 
   15256            0 :   while (c_parser_next_token_is_keyword (parser, RID_AT_CATCH))
   15257              :     {
   15258            0 :       struct c_parm *parm;
   15259            0 :       tree parameter_declaration = error_mark_node;
   15260            0 :       bool seen_open_paren = false;
   15261              : 
   15262            0 :       c_parser_consume_token (parser);
   15263            0 :       matching_parens parens;
   15264            0 :       if (!parens.require_open (parser))
   15265            0 :         seen_open_paren = true;
   15266            0 :       if (c_parser_next_token_is (parser, CPP_ELLIPSIS))
   15267              :         {
   15268              :           /* We have "@catch (...)" (where the '...' are literally
   15269              :              what is in the code).  Skip the '...'.
   15270              :              parameter_declaration is set to NULL_TREE, and
   15271              :              objc_being_catch_clauses() knows that that means
   15272              :              '...'.  */
   15273            0 :           c_parser_consume_token (parser);
   15274            0 :           parameter_declaration = NULL_TREE;
   15275              :         }
   15276              :       else
   15277              :         {
   15278              :           /* We have "@catch (NSException *exception)" or something
   15279              :              like that.  Parse the parameter declaration.  */
   15280            0 :           parm = c_parser_parameter_declaration (parser, NULL_TREE, false);
   15281            0 :           if (parm == NULL)
   15282            0 :             parameter_declaration = error_mark_node;
   15283              :           else
   15284            0 :             parameter_declaration = grokparm (parm, NULL);
   15285              :         }
   15286            0 :       if (seen_open_paren)
   15287            0 :         parens.require_close (parser);
   15288              :       else
   15289              :         {
   15290              :           /* If there was no open parenthesis, we are recovering from
   15291              :              an error, and we are trying to figure out what mistake
   15292              :              the user has made.  */
   15293              : 
   15294              :           /* If there is an immediate closing parenthesis, the user
   15295              :              probably forgot the opening one (ie, they typed "@catch
   15296              :              NSException *e)".  Parse the closing parenthesis and keep
   15297              :              going.  */
   15298            0 :           if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   15299            0 :             c_parser_consume_token (parser);
   15300              : 
   15301              :           /* If these is no immediate closing parenthesis, the user
   15302              :              probably doesn't know that parenthesis are required at
   15303              :              all (ie, they typed "@catch NSException *e").  So, just
   15304              :              forget about the closing parenthesis and keep going.  */
   15305              :         }
   15306            0 :       objc_begin_catch_clause (parameter_declaration);
   15307            0 :       if (c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   15308            0 :         c_parser_compound_statement_nostart (parser);
   15309            0 :       objc_finish_catch_clause ();
   15310              :     }
   15311            0 :   if (c_parser_next_token_is_keyword (parser, RID_AT_FINALLY))
   15312              :     {
   15313            0 :       c_parser_consume_token (parser);
   15314            0 :       location = c_parser_peek_token (parser)->location;
   15315            0 :       stmt = c_parser_compound_statement (parser);
   15316            0 :       objc_build_finally_clause (location, stmt);
   15317              :     }
   15318            0 :   objc_finish_try_stmt ();
   15319            0 : }
   15320              : 
   15321              : /* Parse an objc-synchronized-statement.
   15322              : 
   15323              :    objc-synchronized-statement:
   15324              :      @synchronized ( expression ) compound-statement
   15325              : */
   15326              : 
   15327              : static void
   15328            0 : c_parser_objc_synchronized_statement (c_parser *parser)
   15329              : {
   15330            0 :   location_t loc;
   15331            0 :   tree expr, stmt;
   15332            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNCHRONIZED));
   15333            0 :   c_parser_consume_token (parser);
   15334            0 :   loc = c_parser_peek_token (parser)->location;
   15335            0 :   objc_maybe_warn_exceptions (loc);
   15336            0 :   matching_parens parens;
   15337            0 :   if (parens.require_open (parser))
   15338              :     {
   15339            0 :       struct c_expr ce = c_parser_expression (parser);
   15340            0 :       ce = convert_lvalue_to_rvalue (loc, ce, false, false);
   15341            0 :       expr = ce.value;
   15342            0 :       expr = c_fully_fold (expr, false, NULL);
   15343            0 :       parens.skip_until_found_close (parser);
   15344              :     }
   15345              :   else
   15346            0 :     expr = error_mark_node;
   15347            0 :   stmt = c_parser_compound_statement (parser);
   15348            0 :   objc_build_synchronized (loc, expr, stmt);
   15349            0 : }
   15350              : 
   15351              : /* Parse an objc-selector; return NULL_TREE without an error if the
   15352              :    next token is not an objc-selector.
   15353              : 
   15354              :    objc-selector:
   15355              :      identifier
   15356              :      one of
   15357              :        enum struct union if else while do for switch case default
   15358              :        break continue return goto asm sizeof typeof typeof_unqual __alignof
   15359              :        unsigned long const short volatile signed restrict _Complex
   15360              :        in out inout bycopy byref oneway int char float double void _Bool
   15361              :        _Atomic
   15362              : 
   15363              :    ??? Why this selection of keywords but not, for example, storage
   15364              :    class specifiers?  */
   15365              : 
   15366              : static tree
   15367            0 : c_parser_objc_selector (c_parser *parser)
   15368              : {
   15369            0 :   c_token *token = c_parser_peek_token (parser);
   15370            0 :   tree value = token->value;
   15371            0 :   if (token->type == CPP_NAME)
   15372              :     {
   15373            0 :       c_parser_consume_token (parser);
   15374            0 :       return value;
   15375              :     }
   15376            0 :   if (token->type != CPP_KEYWORD)
   15377              :     return NULL_TREE;
   15378            0 :   switch (token->keyword)
   15379              :     {
   15380            0 :     case RID_ENUM:
   15381            0 :     case RID_STRUCT:
   15382            0 :     case RID_UNION:
   15383            0 :     case RID_IF:
   15384            0 :     case RID_ELSE:
   15385            0 :     case RID_WHILE:
   15386            0 :     case RID_DO:
   15387            0 :     case RID_FOR:
   15388            0 :     case RID_SWITCH:
   15389            0 :     case RID_CASE:
   15390            0 :     case RID_DEFAULT:
   15391            0 :     case RID_BREAK:
   15392            0 :     case RID_CONTINUE:
   15393            0 :     case RID_RETURN:
   15394            0 :     case RID_GOTO:
   15395            0 :     case RID_ASM:
   15396            0 :     case RID_SIZEOF:
   15397            0 :     case RID_TYPEOF:
   15398            0 :     case RID_TYPEOF_UNQUAL:
   15399            0 :     case RID_ALIGNOF:
   15400            0 :     case RID_UNSIGNED:
   15401            0 :     case RID_LONG:
   15402            0 :     case RID_CONST:
   15403            0 :     case RID_SHORT:
   15404            0 :     case RID_VOLATILE:
   15405            0 :     case RID_SIGNED:
   15406            0 :     case RID_RESTRICT:
   15407            0 :     case RID_COMPLEX:
   15408            0 :     case RID_IN:
   15409            0 :     case RID_OUT:
   15410            0 :     case RID_INOUT:
   15411            0 :     case RID_BYCOPY:
   15412            0 :     case RID_BYREF:
   15413            0 :     case RID_ONEWAY:
   15414            0 :     case RID_INT:
   15415            0 :     case RID_CHAR:
   15416            0 :     case RID_FLOAT:
   15417            0 :     case RID_DOUBLE:
   15418            0 :     CASE_RID_FLOATN_NX:
   15419            0 :     case RID_VOID:
   15420            0 :     case RID_BOOL:
   15421            0 :     case RID_ATOMIC:
   15422            0 :     case RID_AUTO_TYPE:
   15423            0 :     case RID_INT_N_0:
   15424            0 :     case RID_INT_N_1:
   15425            0 :     case RID_INT_N_2:
   15426            0 :     case RID_INT_N_3:
   15427            0 :       c_parser_consume_token (parser);
   15428            0 :       return value;
   15429              :     default:
   15430              :       return NULL_TREE;
   15431              :     }
   15432              : }
   15433              : 
   15434              : /* Parse an objc-selector-arg.
   15435              : 
   15436              :    objc-selector-arg:
   15437              :      objc-selector
   15438              :      objc-keywordname-list
   15439              : 
   15440              :    objc-keywordname-list:
   15441              :      objc-keywordname
   15442              :      objc-keywordname-list objc-keywordname
   15443              : 
   15444              :    objc-keywordname:
   15445              :      objc-selector :
   15446              :      :
   15447              : */
   15448              : 
   15449              : static tree
   15450            0 : c_parser_objc_selector_arg (c_parser *parser)
   15451              : {
   15452            0 :   tree sel = c_parser_objc_selector (parser);
   15453            0 :   tree list = NULL_TREE;
   15454            0 :   if (sel
   15455            0 :       && c_parser_next_token_is_not (parser, CPP_COLON)
   15456            0 :       && c_parser_next_token_is_not (parser, CPP_SCOPE))
   15457              :     return sel;
   15458            0 :   while (true)
   15459              :     {
   15460            0 :       if (c_parser_next_token_is (parser, CPP_SCOPE))
   15461              :         {
   15462            0 :           c_parser_consume_token (parser);
   15463            0 :           list = chainon (list, build_tree_list (sel, NULL_TREE));
   15464            0 :           list = chainon (list, build_tree_list (NULL_TREE, NULL_TREE));
   15465              :         }
   15466              :       else
   15467              :         {
   15468            0 :           if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   15469              :             return list;
   15470            0 :           list = chainon (list, build_tree_list (sel, NULL_TREE));
   15471              :         }
   15472            0 :       sel = c_parser_objc_selector (parser);
   15473            0 :       if (!sel
   15474            0 :           && c_parser_next_token_is_not (parser, CPP_COLON)
   15475            0 :           && c_parser_next_token_is_not (parser, CPP_SCOPE))
   15476              :         break;
   15477              :     }
   15478              :   return list;
   15479              : }
   15480              : 
   15481              : /* Parse an objc-receiver.
   15482              : 
   15483              :    objc-receiver:
   15484              :      expression
   15485              :      class-name
   15486              :      type-name
   15487              : */
   15488              : 
   15489              : static tree
   15490            0 : c_parser_objc_receiver (c_parser *parser)
   15491              : {
   15492            0 :   location_t loc = c_parser_peek_token (parser)->location;
   15493              : 
   15494            0 :   if (c_parser_peek_token (parser)->type == CPP_NAME
   15495            0 :       && (c_parser_peek_token (parser)->id_kind == C_ID_TYPENAME
   15496            0 :           || c_parser_peek_token (parser)->id_kind == C_ID_CLASSNAME))
   15497              :     {
   15498            0 :       tree id = c_parser_peek_token (parser)->value;
   15499            0 :       c_parser_consume_token (parser);
   15500            0 :       return objc_get_class_reference (id);
   15501              :     }
   15502            0 :   struct c_expr ce = c_parser_expression (parser);
   15503            0 :   ce = convert_lvalue_to_rvalue (loc, ce, false, false);
   15504            0 :   return c_fully_fold (ce.value, false, NULL);
   15505              : }
   15506              : 
   15507              : /* Parse objc-message-args.
   15508              : 
   15509              :    objc-message-args:
   15510              :      objc-selector
   15511              :      objc-keywordarg-list
   15512              : 
   15513              :    objc-keywordarg-list:
   15514              :      objc-keywordarg
   15515              :      objc-keywordarg-list objc-keywordarg
   15516              : 
   15517              :    objc-keywordarg:
   15518              :      objc-selector : objc-keywordexpr
   15519              :      : objc-keywordexpr
   15520              : */
   15521              : 
   15522              : static tree
   15523            0 : c_parser_objc_message_args (c_parser *parser)
   15524              : {
   15525            0 :   tree sel = c_parser_objc_selector (parser);
   15526            0 :   tree list = NULL_TREE;
   15527            0 :   if (sel && c_parser_next_token_is_not (parser, CPP_COLON))
   15528              :     return sel;
   15529            0 :   while (true)
   15530              :     {
   15531            0 :       tree keywordexpr;
   15532            0 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   15533            0 :         return error_mark_node;
   15534            0 :       keywordexpr = c_parser_objc_keywordexpr (parser);
   15535            0 :       list = chainon (list, build_tree_list (sel, keywordexpr));
   15536            0 :       sel = c_parser_objc_selector (parser);
   15537            0 :       if (!sel && c_parser_next_token_is_not (parser, CPP_COLON))
   15538              :         break;
   15539              :     }
   15540              :   return list;
   15541              : }
   15542              : 
   15543              : /* Parse an objc-keywordexpr.
   15544              : 
   15545              :    objc-keywordexpr:
   15546              :      nonempty-expr-list
   15547              : */
   15548              : 
   15549              : static tree
   15550            0 : c_parser_objc_keywordexpr (c_parser *parser)
   15551              : {
   15552            0 :   tree ret;
   15553            0 :   vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true,
   15554              :                                                 NULL, NULL, NULL, NULL);
   15555            0 :   if (vec_safe_length (expr_list) == 1)
   15556              :     {
   15557              :       /* Just return the expression, remove a level of
   15558              :          indirection.  */
   15559            0 :       ret = (*expr_list)[0];
   15560              :     }
   15561              :   else
   15562              :     {
   15563              :       /* We have a comma expression, we will collapse later.  */
   15564            0 :       ret = build_tree_list_vec (expr_list);
   15565              :     }
   15566            0 :   release_tree_vector (expr_list);
   15567            0 :   return ret;
   15568              : }
   15569              : 
   15570              : /* A check, needed in several places, that ObjC interface, implementation or
   15571              :    method definitions are not prefixed by incorrect items.  */
   15572              : static bool
   15573            0 : c_parser_objc_diagnose_bad_element_prefix (c_parser *parser,
   15574              :                                            struct c_declspecs *specs)
   15575              : {
   15576            0 :   if (!specs->declspecs_seen_p || specs->non_sc_seen_p
   15577            0 :       || specs->typespec_kind != ctsk_none)
   15578              :     {
   15579            0 :       c_parser_error (parser,
   15580              :                       "no type or storage class may be specified here,");
   15581            0 :       c_parser_skip_to_end_of_block_or_statement (parser);
   15582            0 :       return true;
   15583              :     }
   15584              :   return false;
   15585              : }
   15586              : 
   15587              : /* Parse an Objective-C @property declaration.  The syntax is:
   15588              : 
   15589              :    objc-property-declaration:
   15590              :      '@property' objc-property-attributes[opt] struct-declaration ;
   15591              : 
   15592              :    objc-property-attributes:
   15593              :     '(' objc-property-attribute-list ')'
   15594              : 
   15595              :    objc-property-attribute-list:
   15596              :      objc-property-attribute
   15597              :      objc-property-attribute-list, objc-property-attribute
   15598              : 
   15599              :    objc-property-attribute
   15600              :      'getter' = identifier
   15601              :      'setter' = identifier
   15602              :      'readonly'
   15603              :      'readwrite'
   15604              :      'assign'
   15605              :      'retain'
   15606              :      'copy'
   15607              :      'nonatomic'
   15608              : 
   15609              :   For example:
   15610              :     @property NSString *name;
   15611              :     @property (readonly) id object;
   15612              :     @property (retain, nonatomic, getter=getTheName) id name;
   15613              :     @property int a, b, c;
   15614              : 
   15615              :   PS: This function is identical to cp_parser_objc_at_propery_declaration
   15616              :   for C++.  Keep them in sync.  */
   15617              : static void
   15618            0 : c_parser_objc_at_property_declaration (c_parser *parser)
   15619              : {
   15620            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_PROPERTY));
   15621            0 :   location_t loc = c_parser_peek_token (parser)->location;
   15622            0 :   c_parser_consume_token (parser);  /* Eat '@property'.  */
   15623              : 
   15624              :   /* Parse the optional attribute list.
   15625              : 
   15626              :      A list of parsed, but not verified, attributes.  */
   15627            0 :   vec<property_attribute_info *> prop_attr_list = vNULL;
   15628              : 
   15629            0 :   bool syntax_error = false;
   15630            0 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   15631              :     {
   15632            0 :       matching_parens parens;
   15633              : 
   15634            0 :       location_t attr_start = c_parser_peek_token (parser)->location;
   15635              :       /* Eat the '(' */
   15636            0 :       parens.consume_open (parser);
   15637              : 
   15638              :       /* Property attribute keywords are valid now.  */
   15639            0 :       parser->objc_property_attr_context = true;
   15640              : 
   15641              :       /* Allow @property (), with a warning.  */
   15642            0 :       location_t attr_end = c_parser_peek_token (parser)->location;
   15643              : 
   15644            0 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   15645              :         {
   15646            0 :           location_t attr_comb = make_location (attr_end, attr_start, attr_end);
   15647            0 :           warning_at (attr_comb, OPT_Wattributes,
   15648              :                       "empty property attribute list");
   15649              :         }
   15650              :       else
   15651            0 :         while (true)
   15652              :           {
   15653            0 :             c_token *token = c_parser_peek_token (parser);
   15654            0 :             attr_start = token->location;
   15655            0 :             attr_end = get_finish (token->location);
   15656            0 :             location_t attr_comb = make_location (attr_start, attr_start,
   15657              :                                                   attr_end);
   15658              : 
   15659            0 :             if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
   15660              :               {
   15661            0 :                 warning_at (attr_comb, OPT_Wattributes,
   15662              :                             "missing property attribute");
   15663            0 :                 if (token->type == CPP_CLOSE_PAREN)
   15664              :                   break;
   15665            0 :                 c_parser_consume_token (parser);
   15666            0 :                 continue;
   15667              :               }
   15668              : 
   15669            0 :             tree attr_name = NULL_TREE;
   15670            0 :             enum rid keyword = RID_MAX; /* Not a valid property attribute.  */
   15671            0 :             bool add_at = false;
   15672            0 :             if (token->type == CPP_KEYWORD)
   15673              :               {
   15674            0 :                 keyword = token->keyword;
   15675            0 :                 if (OBJC_IS_AT_KEYWORD (keyword))
   15676              :                   {
   15677              :                     /* For '@' keywords the token value has the keyword,
   15678              :                        prepend the '@' for diagnostics.  */
   15679            0 :                     attr_name = token->value;
   15680            0 :                     add_at = true;
   15681              :                   }
   15682              :                 else
   15683            0 :                   attr_name = ridpointers[(int)keyword];
   15684              :               }
   15685            0 :             else if (token->type == CPP_NAME)
   15686            0 :               attr_name = token->value;
   15687            0 :             c_parser_consume_token (parser);
   15688              : 
   15689            0 :             enum objc_property_attribute_kind prop_kind
   15690            0 :               = objc_prop_attr_kind_for_rid (keyword);
   15691            0 :             property_attribute_info *prop
   15692            0 :               = new property_attribute_info (attr_name, attr_comb, prop_kind);
   15693            0 :             prop_attr_list.safe_push (prop);
   15694              : 
   15695            0 :             tree meth_name;
   15696            0 :             switch (prop->prop_kind)
   15697              :               {
   15698              :               default: break;
   15699            0 :               case OBJC_PROPERTY_ATTR_UNKNOWN:
   15700            0 :                 if (attr_name)
   15701            0 :                   error_at (attr_comb, "unknown property attribute %<%s%s%>",
   15702            0 :                             add_at ? "@" : "", IDENTIFIER_POINTER (attr_name));
   15703              :                 else
   15704            0 :                   error_at (attr_comb, "unknown property attribute");
   15705            0 :                 prop->parse_error = syntax_error = true;
   15706            0 :                 break;
   15707              : 
   15708            0 :               case OBJC_PROPERTY_ATTR_GETTER:
   15709            0 :               case OBJC_PROPERTY_ATTR_SETTER:
   15710            0 :                 if (c_parser_next_token_is_not (parser, CPP_EQ))
   15711              :                   {
   15712            0 :                     attr_comb = make_location (attr_end, attr_start, attr_end);
   15713            0 :                     error_at (attr_comb, "expected %<=%> after Objective-C %qE",
   15714              :                               attr_name);
   15715            0 :                     prop->parse_error = syntax_error = true;
   15716            0 :                     break;
   15717              :                   }
   15718            0 :                 token = c_parser_peek_token (parser);
   15719            0 :                 attr_end = token->location;
   15720            0 :                 c_parser_consume_token (parser); /* eat the = */
   15721            0 :                 if (c_parser_next_token_is_not (parser, CPP_NAME))
   15722              :                   {
   15723            0 :                     attr_comb = make_location (attr_end, attr_start, attr_end);
   15724            0 :                     error_at (attr_comb, "expected %qE selector name",
   15725              :                               attr_name);
   15726            0 :                     prop->parse_error = syntax_error = true;
   15727            0 :                     break;
   15728              :                   }
   15729              :                 /* Get the end of the method name, and consume the name.  */
   15730            0 :                 token = c_parser_peek_token (parser);
   15731            0 :                 attr_end = get_finish (token->location);
   15732            0 :                 meth_name = token->value;
   15733            0 :                 c_parser_consume_token (parser);
   15734            0 :                 if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
   15735              :                   {
   15736            0 :                     if (c_parser_next_token_is_not (parser, CPP_COLON))
   15737              :                       {
   15738            0 :                         attr_comb = make_location (attr_end, attr_start,
   15739              :                                                    attr_end);
   15740            0 :                         error_at (attr_comb, "setter method names must"
   15741              :                                   " terminate with %<:%>");
   15742            0 :                         prop->parse_error = syntax_error = true;
   15743              :                       }
   15744              :                     else
   15745              :                       {
   15746            0 :                         attr_end = get_finish (c_parser_peek_token
   15747            0 :                                                (parser)->location);
   15748            0 :                         c_parser_consume_token (parser);
   15749              :                       }
   15750            0 :                     attr_comb = make_location (attr_start, attr_start,
   15751              :                                                attr_end);
   15752              :                   }
   15753              :                 else
   15754            0 :                   attr_comb = make_location (attr_start, attr_start,
   15755              :                                                attr_end);
   15756            0 :                 prop->ident = meth_name;
   15757              :                 /* Updated location including all that was successfully
   15758              :                    parsed.  */
   15759            0 :                 prop->prop_loc = attr_comb;
   15760            0 :                 break;
   15761              :             }
   15762              : 
   15763              :           /* If we see a comma here, then keep going - even if we already
   15764              :              saw a syntax error.  For simple mistakes e.g. (asign, getter=x)
   15765              :              this makes a more useful output and avoid spurious warnings about
   15766              :              missing attributes that are, in fact, specified after the one with
   15767              :              the syntax error.  */
   15768            0 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   15769            0 :             c_parser_consume_token (parser);
   15770              :           else
   15771              :             break;
   15772              :         }
   15773            0 :       parser->objc_property_attr_context = false;
   15774              : 
   15775            0 :       if (syntax_error && c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
   15776              :         /* We don't really want to chew the whole of the file looking for a
   15777              :            matching closing parenthesis, so we will try to read the decl and
   15778              :            let the error handling for that close out the statement.  */
   15779              :         ;
   15780              :       else
   15781            0 :         syntax_error = false, parens.skip_until_found_close (parser);
   15782              :     }
   15783              : 
   15784              :   /* 'properties' is the list of properties that we read.  Usually a
   15785              :      single one, but maybe more (eg, in "@property int a, b, c;" there
   15786              :      are three).  */
   15787            0 :   tree properties = c_parser_struct_declaration (parser, NULL);
   15788              : 
   15789            0 :   if (properties == error_mark_node)
   15790            0 :     c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   15791              :   else
   15792              :     {
   15793            0 :       if (properties == NULL_TREE)
   15794            0 :         c_parser_error (parser, "expected identifier");
   15795              :       else
   15796              :         {
   15797              :           /* Comma-separated properties are chained together in reverse order;
   15798              :              add them one by one.  */
   15799            0 :           properties = nreverse (properties);
   15800            0 :           for (; properties; properties = TREE_CHAIN (properties))
   15801            0 :             objc_add_property_declaration (loc, copy_node (properties),
   15802              :                                             prop_attr_list);
   15803              :         }
   15804            0 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   15805              :     }
   15806              : 
   15807            0 :   while (!prop_attr_list.is_empty())
   15808            0 :     delete prop_attr_list.pop ();
   15809            0 :   prop_attr_list.release ();
   15810            0 :   parser->error = false;
   15811            0 : }
   15812              : 
   15813              : /* Parse an Objective-C @synthesize declaration.  The syntax is:
   15814              : 
   15815              :    objc-synthesize-declaration:
   15816              :      @synthesize objc-synthesize-identifier-list ;
   15817              : 
   15818              :    objc-synthesize-identifier-list:
   15819              :      objc-synthesize-identifier
   15820              :      objc-synthesize-identifier-list, objc-synthesize-identifier
   15821              : 
   15822              :    objc-synthesize-identifier
   15823              :      identifier
   15824              :      identifier = identifier
   15825              : 
   15826              :   For example:
   15827              :     @synthesize MyProperty;
   15828              :     @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;
   15829              : 
   15830              :   PS: This function is identical to cp_parser_objc_at_synthesize_declaration
   15831              :   for C++.  Keep them in sync.
   15832              : */
   15833              : static void
   15834            0 : c_parser_objc_at_synthesize_declaration (c_parser *parser)
   15835              : {
   15836            0 :   tree list = NULL_TREE;
   15837            0 :   location_t loc;
   15838            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_SYNTHESIZE));
   15839            0 :   loc = c_parser_peek_token (parser)->location;
   15840              : 
   15841            0 :   c_parser_consume_token (parser);
   15842            0 :   while (true)
   15843              :     {
   15844            0 :       tree property, ivar;
   15845            0 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   15846              :         {
   15847            0 :           c_parser_error (parser, "expected identifier");
   15848            0 :           c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   15849              :           /* Once we find the semicolon, we can resume normal parsing.
   15850              :              We have to reset parser->error manually because
   15851              :              c_parser_skip_until_found() won't reset it for us if the
   15852              :              next token is precisely a semicolon.  */
   15853            0 :           parser->error = false;
   15854            0 :           return;
   15855              :         }
   15856            0 :       property = c_parser_peek_token (parser)->value;
   15857            0 :       c_parser_consume_token (parser);
   15858            0 :       if (c_parser_next_token_is (parser, CPP_EQ))
   15859              :         {
   15860            0 :           c_parser_consume_token (parser);
   15861            0 :           if (c_parser_next_token_is_not (parser, CPP_NAME))
   15862              :             {
   15863            0 :               c_parser_error (parser, "expected identifier");
   15864            0 :               c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   15865            0 :               parser->error = false;
   15866            0 :               return;
   15867              :             }
   15868            0 :           ivar = c_parser_peek_token (parser)->value;
   15869            0 :           c_parser_consume_token (parser);
   15870              :         }
   15871              :       else
   15872              :         ivar = NULL_TREE;
   15873            0 :       list = chainon (list, build_tree_list (ivar, property));
   15874            0 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   15875            0 :         c_parser_consume_token (parser);
   15876              :       else
   15877              :         break;
   15878            0 :     }
   15879            0 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   15880            0 :   objc_add_synthesize_declaration (loc, list);
   15881              : }
   15882              : 
   15883              : /* Parse an Objective-C @dynamic declaration.  The syntax is:
   15884              : 
   15885              :    objc-dynamic-declaration:
   15886              :      @dynamic identifier-list ;
   15887              : 
   15888              :    For example:
   15889              :      @dynamic MyProperty;
   15890              :      @dynamic MyProperty, AnotherProperty;
   15891              : 
   15892              :   PS: This function is identical to cp_parser_objc_at_dynamic_declaration
   15893              :   for C++.  Keep them in sync.
   15894              : */
   15895              : static void
   15896            0 : c_parser_objc_at_dynamic_declaration (c_parser *parser)
   15897              : {
   15898            0 :   tree list = NULL_TREE;
   15899            0 :   location_t loc;
   15900            0 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_AT_DYNAMIC));
   15901            0 :   loc = c_parser_peek_token (parser)->location;
   15902              : 
   15903            0 :   c_parser_consume_token (parser);
   15904            0 :   while (true)
   15905              :     {
   15906            0 :       tree property;
   15907            0 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   15908              :         {
   15909            0 :           c_parser_error (parser, "expected identifier");
   15910            0 :           c_parser_skip_until_found (parser, CPP_SEMICOLON, NULL);
   15911            0 :           parser->error = false;
   15912            0 :           return;
   15913              :         }
   15914            0 :       property = c_parser_peek_token (parser)->value;
   15915            0 :       list = chainon (list, build_tree_list (NULL_TREE, property));
   15916            0 :       c_parser_consume_token (parser);
   15917            0 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   15918            0 :         c_parser_consume_token (parser);
   15919              :       else
   15920              :         break;
   15921            0 :     }
   15922            0 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   15923            0 :   objc_add_dynamic_declaration (loc, list);
   15924              : }
   15925              : 
   15926              : 
   15927              : /* Parse a pragma GCC ivdep.  */
   15928              : 
   15929              : static bool
   15930          128 : c_parse_pragma_ivdep (c_parser *parser)
   15931              : {
   15932            0 :   c_parser_consume_pragma (parser);
   15933            0 :   c_parser_skip_to_pragma_eol (parser);
   15934          128 :   return true;
   15935              : }
   15936              : 
   15937              : /* Parse a pragma GCC novector.  */
   15938              : 
   15939              : static bool
   15940         2911 : c_parse_pragma_novector (c_parser *parser)
   15941              : {
   15942            0 :   c_parser_consume_pragma (parser);
   15943            0 :   c_parser_skip_to_pragma_eol (parser);
   15944         2911 :   return true;
   15945              : }
   15946              : 
   15947              : /* Parse a pragma GCC unroll.  */
   15948              : 
   15949              : static unsigned short
   15950          288 : c_parser_pragma_unroll (c_parser *parser)
   15951              : {
   15952          288 :   unsigned short unroll;
   15953          288 :   c_parser_consume_pragma (parser);
   15954          288 :   location_t location = c_parser_peek_token (parser)->location;
   15955          288 :   tree expr = c_parser_expr_no_commas (parser, NULL).value;
   15956          288 :   mark_exp_read (expr);
   15957          288 :   expr = c_fully_fold (expr, false, NULL);
   15958          288 :   HOST_WIDE_INT lunroll = 0;
   15959          576 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
   15960          287 :       || TREE_CODE (expr) != INTEGER_CST
   15961          286 :       || (lunroll = tree_to_shwi (expr)) < 0
   15962          573 :       || lunroll >= USHRT_MAX)
   15963              :     {
   15964            4 :       error_at (location, "%<#pragma GCC unroll%> requires an"
   15965              :                 " assignment-expression that evaluates to a non-negative"
   15966              :                 " integral constant less than %u", USHRT_MAX);
   15967            4 :       unroll = 0;
   15968              :     }
   15969              :   else
   15970              :     {
   15971          284 :       unroll = (unsigned short)lunroll;
   15972          284 :       if (unroll == 0)
   15973              :         unroll = 1;
   15974              :     }
   15975              : 
   15976          288 :   c_parser_skip_to_pragma_eol (parser);
   15977          288 :   return unroll;
   15978              : }
   15979              : 
   15980              : /* Handle pragmas.  Some OpenMP pragmas are associated with, and therefore
   15981              :    should be considered, statements.  ALLOW_STMT is true if we're within
   15982              :    the context of a function and such pragmas are to be allowed.  Returns
   15983              :    true if we actually parsed such a pragma.  BEFORE_LABELS is last statement
   15984              :    before possible labels, see get_before_labels description for details.  */
   15985              : 
   15986              : static bool
   15987      1927292 : c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p,
   15988              :                  tree before_labels)
   15989              : {
   15990      1927292 :   unsigned int id;
   15991      1927292 :   const char *construct = NULL;
   15992              : 
   15993      1927292 :   input_location = c_parser_peek_token (parser)->location;
   15994      1927292 :   id = c_parser_peek_token (parser)->pragma_kind;
   15995      1927292 :   gcc_assert (id != PRAGMA_NONE);
   15996      1927292 :   if (parser->omp_for_parse_state
   15997           16 :       && parser->omp_for_parse_state->in_intervening_code
   15998           13 :       && id >= PRAGMA_OMP__START_ && id <= PRAGMA_OMP__LAST_
   15999              :       /* Allow a safe subset of non-executable directives. See classification in
   16000              :          array c_omp_directives.  */
   16001            7 :       && id != PRAGMA_OMP_METADIRECTIVE && id != PRAGMA_OMP_NOTHING
   16002            5 :       && id != PRAGMA_OMP_ASSUME && id != PRAGMA_OMP_ERROR)
   16003              :     {
   16004            2 :       error_at (
   16005              :         input_location,
   16006              :         "intervening code must not contain executable OpenMP directives");
   16007            2 :       parser->omp_for_parse_state->fail = true;
   16008            2 :       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16009            2 :       return false;
   16010              :     }
   16011              : 
   16012      1927290 :   switch (id)
   16013              :     {
   16014          144 :     case PRAGMA_OACC_DECLARE:
   16015          144 :       c_parser_oacc_declare (parser);
   16016          144 :       return false;
   16017              : 
   16018          136 :     case PRAGMA_OACC_ENTER_DATA:
   16019          136 :       if (context != pragma_compound)
   16020              :         {
   16021              :           construct = "acc enter data";
   16022           62 :         in_compound:
   16023           62 :           if (context == pragma_stmt)
   16024              :             {
   16025           59 :               error_at (c_parser_peek_token (parser)->location,
   16026              :                         "%<#pragma %s%> may only be used in compound "
   16027              :                         "statements", construct);
   16028           59 :               c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16029           59 :               return true;
   16030              :             }
   16031            3 :           goto bad_stmt;
   16032              :         }
   16033          133 :       c_parser_oacc_enter_exit_data (parser, true);
   16034          133 :       return false;
   16035              : 
   16036          131 :     case PRAGMA_OACC_EXIT_DATA:
   16037          131 :       if (context != pragma_compound)
   16038              :         {
   16039            3 :           construct = "acc exit data";
   16040            3 :           goto in_compound;
   16041              :         }
   16042          128 :       c_parser_oacc_enter_exit_data (parser, false);
   16043          128 :       return false;
   16044              : 
   16045          350 :     case PRAGMA_OACC_ROUTINE:
   16046          350 :       if (context != pragma_external)
   16047              :         {
   16048            5 :           error_at (c_parser_peek_token (parser)->location,
   16049              :                     "%<#pragma acc routine%> must be at file scope");
   16050            5 :           c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16051            5 :           return false;
   16052              :         }
   16053          345 :       c_parser_oacc_routine (parser, context);
   16054          345 :       return false;
   16055              : 
   16056          100 :     case PRAGMA_OACC_UPDATE:
   16057          100 :       if (context != pragma_compound)
   16058              :         {
   16059            8 :           construct = "acc update";
   16060            8 :           goto in_compound;
   16061              :         }
   16062           92 :       c_parser_oacc_update (parser);
   16063           92 :       return false;
   16064              : 
   16065          357 :     case PRAGMA_OMP_BARRIER:
   16066          357 :       if (context != pragma_compound)
   16067              :         {
   16068           11 :           construct = "omp barrier";
   16069           11 :           goto in_compound;
   16070              :         }
   16071          346 :       c_parser_omp_barrier (parser);
   16072          346 :       return false;
   16073              : 
   16074           76 :     case PRAGMA_OMP_DEPOBJ:
   16075           76 :       if (context != pragma_compound)
   16076              :         {
   16077            1 :           construct = "omp depobj";
   16078            1 :           goto in_compound;
   16079              :         }
   16080           75 :       c_parser_omp_depobj (parser);
   16081           75 :       return false;
   16082              : 
   16083           68 :     case PRAGMA_OMP_FLUSH:
   16084           68 :       if (context != pragma_compound)
   16085              :         {
   16086            9 :           construct = "omp flush";
   16087            9 :           goto in_compound;
   16088              :         }
   16089           59 :       c_parser_omp_flush (parser);
   16090           59 :       return false;
   16091              : 
   16092          183 :     case PRAGMA_OMP_INTEROP:
   16093          183 :       if (context != pragma_compound)
   16094              :         {
   16095            0 :           construct = "omp interop";
   16096            0 :           goto in_compound;
   16097              :         }
   16098          183 :       c_parser_omp_interop (parser);
   16099          183 :       return false;
   16100              : 
   16101          101 :     case PRAGMA_OMP_TASKWAIT:
   16102          101 :       if (context != pragma_compound)
   16103              :         {
   16104            8 :           construct = "omp taskwait";
   16105            8 :           goto in_compound;
   16106              :         }
   16107           93 :       c_parser_omp_taskwait (parser);
   16108           93 :       return false;
   16109              : 
   16110           14 :     case PRAGMA_OMP_TASKYIELD:
   16111           14 :       if (context != pragma_compound)
   16112              :         {
   16113            8 :           construct = "omp taskyield";
   16114            8 :           goto in_compound;
   16115              :         }
   16116            6 :       c_parser_omp_taskyield (parser);
   16117            6 :       return false;
   16118              : 
   16119          221 :     case PRAGMA_OMP_CANCEL:
   16120          221 :       if (context != pragma_compound)
   16121              :         {
   16122            8 :           construct = "omp cancel";
   16123            8 :           goto in_compound;
   16124              :         }
   16125          213 :       c_parser_omp_cancel (parser);
   16126          213 :       return false;
   16127              : 
   16128          179 :     case PRAGMA_OMP_CANCELLATION_POINT:
   16129          179 :       return c_parser_omp_cancellation_point (parser, context);
   16130              : 
   16131            9 :     case PRAGMA_OMP_GROUPPRIVATE:
   16132            9 :       c_parser_omp_groupprivate (parser);
   16133            9 :       return false;
   16134              : 
   16135           78 :     case PRAGMA_OMP_THREADPRIVATE:
   16136           78 :       c_parser_omp_threadprivate (parser);
   16137           78 :       return false;
   16138              : 
   16139         7549 :     case PRAGMA_OMP_TARGET:
   16140         7549 :       return c_parser_omp_target (parser, context, if_p);
   16141              : 
   16142          128 :     case PRAGMA_OMP_BEGIN:
   16143          128 :       c_parser_omp_begin (parser);
   16144          128 :       return false;
   16145              : 
   16146          222 :     case PRAGMA_OMP_END:
   16147          222 :       c_parser_omp_end (parser);
   16148          222 :       return false;
   16149              : 
   16150           22 :     case PRAGMA_OMP_SCAN:
   16151           22 :       error_at (c_parser_peek_token (parser)->location,
   16152              :                 "%<#pragma omp scan%> may only be used in "
   16153              :                 "a loop construct with %<inscan%> %<reduction%> clause");
   16154           22 :       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16155           22 :       return false;
   16156              : 
   16157            5 :     case PRAGMA_OMP_SECTION:
   16158            5 :       error_at (c_parser_peek_token (parser)->location,
   16159              :                 "%<#pragma omp section%> may only be used in "
   16160              :                 "%<#pragma omp sections%> construct");
   16161            5 :       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16162            5 :       return false;
   16163              : 
   16164         1280 :     case PRAGMA_OMP_DECLARE:
   16165         1280 :       return c_parser_omp_declare (parser, context);
   16166              : 
   16167           67 :     case PRAGMA_OMP_REQUIRES:
   16168           67 :       if (context != pragma_external)
   16169              :         {
   16170            8 :           error_at (c_parser_peek_token (parser)->location,
   16171              :                     "%<#pragma %s%> may only be used at file scope",
   16172              :                     "omp requires");
   16173            8 :           c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16174            8 :           return false;
   16175              :         }
   16176           59 :       c_parser_omp_requires (parser);
   16177           59 :       return false;
   16178              : 
   16179           71 :     case PRAGMA_OMP_ALLOCATE:
   16180           71 :       c_parser_omp_allocate (parser);
   16181           71 :       return false;
   16182              : 
   16183           39 :     case PRAGMA_OMP_ASSUMES:
   16184           39 :       if (context != pragma_external)
   16185              :         {
   16186            1 :           error_at (c_parser_peek_token (parser)->location,
   16187              :                     "%<#pragma %s%> may only be used at file scope",
   16188              :                     "omp assumes");
   16189            1 :           c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16190            1 :           return false;
   16191              :         }
   16192           38 :       c_parser_omp_assumes (parser);
   16193           38 :       return false;
   16194              : 
   16195           79 :     case PRAGMA_OMP_NOTHING:
   16196           79 :       c_parser_omp_nothing (parser);
   16197           79 :       return false;
   16198              : 
   16199          110 :     case PRAGMA_OMP_METADIRECTIVE:
   16200          110 :       c_parser_omp_metadirective (parser, if_p);
   16201          110 :       return true;
   16202              : 
   16203          126 :     case PRAGMA_OMP_ERROR:
   16204          126 :       return c_parser_omp_error (parser, context);
   16205              : 
   16206          545 :     case PRAGMA_OMP_ORDERED:
   16207          545 :       return c_parser_omp_ordered (parser, context, if_p);
   16208              : 
   16209         3311 :     case PRAGMA_NOVECTOR:
   16210         3311 :     case PRAGMA_UNROLL:
   16211         3311 :     case PRAGMA_IVDEP:
   16212         3311 :       {
   16213         3311 :         bool novector = false;
   16214         3311 :         unsigned short unroll = 0;
   16215         3311 :         bool ivdep = false;
   16216              : 
   16217         3311 :         switch (id)
   16218              :           {
   16219         2907 :           case PRAGMA_NOVECTOR:
   16220         2907 :             novector = c_parse_pragma_novector (parser);
   16221         2907 :             break;
   16222          279 :           case PRAGMA_UNROLL:
   16223          279 :             unroll = c_parser_pragma_unroll (parser);
   16224          279 :             break;
   16225          125 :           case PRAGMA_IVDEP:
   16226          125 :             ivdep = c_parse_pragma_ivdep (parser);
   16227          125 :             break;
   16228              :           default:
   16229              :             gcc_unreachable ();
   16230              :           }
   16231              : 
   16232         3311 :         c_token *tok = c_parser_peek_token (parser);
   16233         3311 :         bool has_more = tok->type == CPP_PRAGMA;
   16234         3327 :         while (has_more)
   16235              :           {
   16236           16 :             switch (tok->pragma_kind)
   16237              :               {
   16238            3 :               case PRAGMA_IVDEP:
   16239            3 :                 ivdep = c_parse_pragma_ivdep (parser);
   16240            3 :                 break;
   16241            9 :               case PRAGMA_UNROLL:
   16242            9 :                 unroll = c_parser_pragma_unroll (parser);
   16243            9 :                 break;
   16244            4 :               case PRAGMA_NOVECTOR:
   16245            4 :                 novector = c_parse_pragma_novector (parser);
   16246            4 :                 break;
   16247              :               default:
   16248              :                 has_more = false;
   16249              :                 break;
   16250              :               }
   16251           16 :             tok = c_parser_peek_token (parser);
   16252           16 :             has_more = has_more && tok->type == CPP_PRAGMA;
   16253              :           }
   16254         3311 :         if (!c_parser_next_token_is_keyword (parser, RID_FOR)
   16255           74 :             && !c_parser_next_token_is_keyword (parser, RID_WHILE)
   16256         3370 :             && !c_parser_next_token_is_keyword (parser, RID_DO))
   16257              :           {
   16258            0 :             c_parser_error (parser, "for, while or do statement expected");
   16259            0 :             return false;
   16260              :           }
   16261         3311 :         if (c_parser_next_token_is_keyword (parser, RID_FOR))
   16262         3237 :           c_parser_for_statement (parser, ivdep, unroll, novector, if_p,
   16263              :                                   before_labels);
   16264           74 :         else if (c_parser_next_token_is_keyword (parser, RID_WHILE))
   16265           15 :           c_parser_while_statement (parser, ivdep, unroll, novector, if_p,
   16266              :                                     before_labels);
   16267              :         else
   16268           59 :           c_parser_do_statement (parser, ivdep, unroll, novector,
   16269              :                                  before_labels);
   16270              :       }
   16271              :       return true;
   16272              : 
   16273            1 :     case PRAGMA_GCC_PCH_PREPROCESS:
   16274            1 :       c_parser_error (parser, "%<#pragma GCC pch_preprocess%> must be first");
   16275            1 :       c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16276            1 :       return false;
   16277              : 
   16278           89 :     case PRAGMA_OACC_WAIT:
   16279           89 :       if (context != pragma_compound)
   16280              :         {
   16281            3 :           construct = "acc wait";
   16282            3 :           goto in_compound;
   16283              :         }
   16284              :         /* FALL THROUGH.  */
   16285              : 
   16286      1911585 :     default:
   16287      1911585 :       if (id < PRAGMA_FIRST_EXTERNAL)
   16288              :         {
   16289        17273 :           if (context != pragma_stmt && context != pragma_compound)
   16290              :             {
   16291            2 :             bad_stmt:
   16292            5 :               c_parser_error (parser, "expected declaration specifiers");
   16293            5 :               c_parser_skip_until_found (parser, CPP_PRAGMA_EOL, NULL);
   16294            5 :               return false;
   16295              :             }
   16296        17271 :           c_parser_omp_construct (parser, if_p);
   16297        17271 :           return true;
   16298              :         }
   16299      1894312 :       break;
   16300              :     }
   16301              : 
   16302      1894312 :   c_parser_consume_pragma (parser);
   16303      1894312 :   c_invoke_pragma_handler (id);
   16304              : 
   16305              :   /* Skip to EOL, but suppress any error message.  Those will have been
   16306              :      generated by the handler routine through calling error, as opposed
   16307              :      to calling c_parser_error.  */
   16308      1894312 :   parser->error = true;
   16309      1894312 :   c_parser_skip_to_pragma_eol (parser);
   16310              : 
   16311      1894312 :   return false;
   16312              : }
   16313              : 
   16314              : /* The interface the pragma parsers have to the lexer.  */
   16315              : 
   16316              : enum cpp_ttype
   16317      3578951 : pragma_lex (tree *value, location_t *loc)
   16318              : {
   16319      3578951 :   c_token *tok = c_parser_peek_token (the_parser);
   16320      3578951 :   enum cpp_ttype ret = tok->type;
   16321              : 
   16322      3578951 :   *value = tok->value;
   16323      3578951 :   if (loc)
   16324      1498581 :     *loc = tok->location;
   16325              : 
   16326      3578951 :   if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
   16327              :     ret = CPP_EOF;
   16328      2021917 :   else if (ret == CPP_STRING)
   16329       634208 :     *value = c_parser_string_literal (the_parser, false, false).value;
   16330              :   else
   16331              :     {
   16332      1387709 :       if (ret == CPP_KEYWORD)
   16333          344 :         ret = CPP_NAME;
   16334      1387709 :       c_parser_consume_token (the_parser);
   16335              :     }
   16336              : 
   16337      3578951 :   return ret;
   16338              : }
   16339              : 
   16340              : void
   16341         9232 : pragma_lex_discard_to_eol ()
   16342              : {
   16343         9232 :   cpp_ttype type;
   16344         9232 :   do
   16345              :     {
   16346         9232 :       type = c_parser_peek_token (the_parser)->type;
   16347         9232 :       gcc_assert (type != CPP_EOF);
   16348         9232 :       c_parser_consume_token (the_parser);
   16349         9232 :     } while (type != CPP_PRAGMA_EOL);
   16350         9232 : }
   16351              : 
   16352              : static void
   16353           12 : c_parser_pragma_pch_preprocess (c_parser *parser)
   16354              : {
   16355           12 :   tree name = NULL;
   16356              : 
   16357           12 :   parser->lex_joined_string = true;
   16358           12 :   c_parser_consume_pragma (parser);
   16359           12 :   if (c_parser_next_token_is (parser, CPP_STRING))
   16360              :     {
   16361           12 :       name = c_parser_peek_token (parser)->value;
   16362           12 :       c_parser_consume_token (parser);
   16363              :     }
   16364              :   else
   16365            0 :     c_parser_error (parser, "expected string literal");
   16366           12 :   c_parser_skip_to_pragma_eol (parser);
   16367           12 :   parser->lex_joined_string = false;
   16368              : 
   16369           12 :   if (name)
   16370           12 :     c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
   16371           12 : }
   16372              : 
   16373              : /* OpenACC and OpenMP parsing routines.  */
   16374              : 
   16375              : /* Returns name of the next clause.
   16376              :    If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
   16377              :    the token is not consumed.  Otherwise appropriate pragma_omp_clause is
   16378              :    returned and the token is consumed.  */
   16379              : 
   16380              : static pragma_omp_clause
   16381        34334 : c_parser_omp_clause_name (c_parser *parser)
   16382              : {
   16383        34334 :   pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;
   16384              : 
   16385        34334 :   if (c_parser_next_token_is_keyword (parser, RID_AUTO))
   16386              :     result = PRAGMA_OACC_CLAUSE_AUTO;
   16387        34209 :   else if (c_parser_next_token_is_keyword (parser, RID_IF))
   16388              :     result = PRAGMA_OMP_CLAUSE_IF;
   16389        33325 :   else if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
   16390              :     result = PRAGMA_OMP_CLAUSE_DEFAULT;
   16391        32596 :   else if (c_parser_next_token_is_keyword (parser, RID_FOR))
   16392              :     result = PRAGMA_OMP_CLAUSE_FOR;
   16393        32512 :   else if (c_parser_next_token_is (parser, CPP_NAME))
   16394              :     {
   16395        32426 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   16396              : 
   16397        32426 :       switch (p[0])
   16398              :         {
   16399         1123 :         case 'a':
   16400         1123 :           if (!strcmp ("affinity", p))
   16401              :             result = PRAGMA_OMP_CLAUSE_AFFINITY;
   16402          977 :           else if (!strcmp ("aligned", p))
   16403              :             result = PRAGMA_OMP_CLAUSE_ALIGNED;
   16404          749 :           else if (!strcmp ("allocate", p))
   16405              :             result = PRAGMA_OMP_CLAUSE_ALLOCATE;
   16406          270 :           else if (!strcmp ("async", p))
   16407              :             result = PRAGMA_OACC_CLAUSE_ASYNC;
   16408           30 :           else if (!strcmp ("attach", p))
   16409        34334 :             result = PRAGMA_OACC_CLAUSE_ATTACH;
   16410              :           break;
   16411          118 :         case 'b':
   16412          118 :           if (!strcmp ("bind", p))
   16413        34334 :             result = PRAGMA_OMP_CLAUSE_BIND;
   16414              :           break;
   16415         4592 :         case 'c':
   16416         4592 :           if (!strcmp ("collapse", p))
   16417              :             result = PRAGMA_OMP_CLAUSE_COLLAPSE;
   16418         1638 :           else if (!strcmp ("copy", p))
   16419              :             result = PRAGMA_OACC_CLAUSE_COPY;
   16420          854 :           else if (!strcmp ("copyin", p))
   16421              :             result = PRAGMA_OMP_CLAUSE_COPYIN;
   16422          419 :           else if (!strcmp ("copyout", p))
   16423              :             result = PRAGMA_OACC_CLAUSE_COPYOUT;
   16424           96 :           else if (!strcmp ("copyprivate", p))
   16425              :             result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
   16426           75 :           else if (!strcmp ("create", p))
   16427        34334 :             result = PRAGMA_OACC_CLAUSE_CREATE;
   16428              :           break;
   16429         3536 :         case 'd':
   16430         3536 :           if (!strcmp ("defaultmap", p))
   16431              :             result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
   16432         3298 :           else if (!strcmp ("delete", p))
   16433              :             result = PRAGMA_OACC_CLAUSE_DELETE;
   16434         3230 :           else if (!strcmp ("depend", p))
   16435              :             result = PRAGMA_OMP_CLAUSE_DEPEND;
   16436         2373 :           else if (!strcmp ("destroy", p))
   16437              :             result = PRAGMA_OMP_CLAUSE_DESTROY;
   16438         2332 :           else if (!strcmp ("detach", p))
   16439              :             result = PRAGMA_OACC_CLAUSE_DETACH;
   16440         2278 :           else if (!strcmp ("device", p))
   16441              :             result = PRAGMA_OMP_CLAUSE_DEVICE;
   16442         1873 :           else if (!strcmp ("deviceptr", p))
   16443              :             result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
   16444         1816 :           else if (!strcmp ("device_resident", p))
   16445              :             result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
   16446         1800 :           else if (!strcmp ("device_type", p))
   16447              :             result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
   16448         1749 :           else if (!strcmp ("dist_schedule", p))
   16449              :             result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
   16450          167 :           else if (!strcmp ("doacross", p))
   16451              :             result = PRAGMA_OMP_CLAUSE_DOACROSS;
   16452           22 :           else if (!strcmp ("dyn_groupprivate", p))
   16453        34334 :             result = PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE;
   16454              :           break;
   16455           46 :         case 'e':
   16456           46 :           if (!strcmp ("enter", p))
   16457        34334 :             result = PRAGMA_OMP_CLAUSE_ENTER;
   16458              :           break;
   16459         3488 :         case 'f':
   16460         3488 :           if (!strcmp ("filter", p))
   16461              :             result = PRAGMA_OMP_CLAUSE_FILTER;
   16462         3425 :           else if (!strcmp ("final", p))
   16463              :             result = PRAGMA_OMP_CLAUSE_FINAL;
   16464         3326 :           else if (!strcmp ("finalize", p))
   16465              :             result = PRAGMA_OACC_CLAUSE_FINALIZE;
   16466         3314 :           else if (!strcmp ("firstprivate", p))
   16467              :             result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
   16468         2523 :           else if (!strcmp ("from", p))
   16469              :             result = PRAGMA_OMP_CLAUSE_FROM;
   16470           73 :           else if (!strcmp ("full", p))
   16471        34334 :             result = PRAGMA_OMP_CLAUSE_FULL;
   16472              :           break;
   16473          651 :         case 'g':
   16474          651 :           if (!strcmp ("gang", p))
   16475              :             result = PRAGMA_OACC_CLAUSE_GANG;
   16476           62 :           else if (!strcmp ("grainsize", p))
   16477        34334 :             result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
   16478              :           break;
   16479          158 :         case 'h':
   16480          158 :           if (!strcmp ("has_device_addr", p))
   16481              :             result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
   16482           70 :           else if (!strcmp ("hint", p))
   16483              :             result = PRAGMA_OMP_CLAUSE_HINT;
   16484           41 :           else if (!strcmp ("host", p))
   16485        34334 :             result = PRAGMA_OACC_CLAUSE_HOST;
   16486              :           break;
   16487          805 :         case 'i':
   16488          805 :           if (!strcmp ("if_present", p))
   16489              :             result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
   16490          786 :           else if (!strcmp ("in_reduction", p))
   16491              :             result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
   16492          465 :           else if (!strcmp ("inbranch", p))
   16493              :             result = PRAGMA_OMP_CLAUSE_INBRANCH;
   16494          396 :           else if (!strcmp ("independent", p))
   16495              :             result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
   16496          351 :           else if (!strcmp ("indirect", p))
   16497              :             result = PRAGMA_OMP_CLAUSE_INDIRECT;
   16498          325 :           else if (!strcmp ("init", p))
   16499              :             result = PRAGMA_OMP_CLAUSE_INIT;
   16500          158 :           else if (!strcmp ("is_device_ptr", p))
   16501              :             result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
   16502           43 :           else if (!strcmp ("interop", p))
   16503        34334 :             result = PRAGMA_OMP_CLAUSE_INTEROP;
   16504              :           break;
   16505         1251 :         case 'l':
   16506         1251 :           if (!strcmp ("lastprivate", p))
   16507              :             result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
   16508          519 :           else if (!strcmp ("linear", p))
   16509              :             result = PRAGMA_OMP_CLAUSE_LINEAR;
   16510           43 :           else if (!strcmp ("link", p))
   16511        34334 :             result = PRAGMA_OMP_CLAUSE_LINK;
   16512              :           break;
   16513         1896 :         case 'm':
   16514         1896 :           if (!strcmp ("map", p))
   16515              :             result = PRAGMA_OMP_CLAUSE_MAP;
   16516           79 :           else if (!strcmp ("mergeable", p))
   16517        34334 :             result = PRAGMA_OMP_CLAUSE_MERGEABLE;
   16518              :           break;
   16519         1923 :         case 'n':
   16520         1923 :           if (!strcmp ("no_create", p))
   16521              :             result = PRAGMA_OACC_CLAUSE_NO_CREATE;
   16522         1913 :           else if (!strcmp ("nocontext", p))
   16523              :             result = PRAGMA_OMP_CLAUSE_NOCONTEXT;
   16524         1890 :           else if (!strcmp ("nogroup", p))
   16525              :             result = PRAGMA_OMP_CLAUSE_NOGROUP;
   16526         1872 :           else if (!strcmp ("nohost", p))
   16527              :             result = PRAGMA_OACC_CLAUSE_NOHOST;
   16528         1847 :           else if (!strcmp ("nontemporal", p))
   16529              :             result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
   16530         1726 :           else if (!strcmp ("notinbranch", p))
   16531              :             result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
   16532         1590 :           else if (!strcmp ("novariants", p))
   16533              :             result = PRAGMA_OMP_CLAUSE_NOVARIANTS;
   16534         1566 :           else if (!strcmp ("nowait", p))
   16535              :             result = PRAGMA_OMP_CLAUSE_NOWAIT;
   16536         1175 :           else if (!strcmp ("num_gangs", p))
   16537              :             result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
   16538          873 :           else if (!strcmp ("num_tasks", p))
   16539              :             result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
   16540          823 :           else if (!strcmp ("num_teams", p))
   16541              :             result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
   16542          633 :           else if (!strcmp ("num_threads", p))
   16543              :             result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
   16544          207 :           else if (!strcmp ("num_workers", p))
   16545        34334 :             result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
   16546              :           break;
   16547          692 :         case 'o':
   16548          692 :           if (!strcmp ("ordered", p))
   16549              :             result = PRAGMA_OMP_CLAUSE_ORDERED;
   16550          382 :           else if (!strcmp ("order", p))
   16551        34334 :             result = PRAGMA_OMP_CLAUSE_ORDER;
   16552              :           break;
   16553         1646 :         case 'p':
   16554         1646 :           if (!strcmp ("parallel", p))
   16555              :             result = PRAGMA_OMP_CLAUSE_PARALLEL;
   16556         1539 :           else if (!strcmp ("partial", p))
   16557              :             result = PRAGMA_OMP_CLAUSE_PARTIAL;
   16558         1309 :           else if (!strcmp ("present", p))
   16559              :             result = PRAGMA_OACC_CLAUSE_PRESENT;
   16560              :           /* As of OpenACC 2.5, these are now aliases of the non-present_or
   16561              :              clauses.  */
   16562         1181 :           else if (!strcmp ("present_or_copy", p)
   16563         1168 :                    || !strcmp ("pcopy", p))
   16564              :             result = PRAGMA_OACC_CLAUSE_COPY;
   16565         1159 :           else if (!strcmp ("present_or_copyin", p)
   16566         1143 :                    || !strcmp ("pcopyin", p))
   16567              :             result = PRAGMA_OACC_CLAUSE_COPYIN;
   16568         1134 :           else if (!strcmp ("present_or_copyout", p)
   16569         1081 :                    || !strcmp ("pcopyout", p))
   16570              :             result = PRAGMA_OACC_CLAUSE_COPYOUT;
   16571         1067 :           else if (!strcmp ("present_or_create", p)
   16572         1053 :                    || !strcmp ("pcreate", p))
   16573              :             result = PRAGMA_OACC_CLAUSE_CREATE;
   16574         1048 :           else if (!strcmp ("priority", p))
   16575              :             result = PRAGMA_OMP_CLAUSE_PRIORITY;
   16576          950 :           else if (!strcmp ("private", p))
   16577              :             result = PRAGMA_OMP_CLAUSE_PRIVATE;
   16578          205 :           else if (!strcmp ("proc_bind", p))
   16579        34334 :             result = PRAGMA_OMP_CLAUSE_PROC_BIND;
   16580              :           break;
   16581         2686 :         case 'r':
   16582         2686 :           if (!strcmp ("reduction", p))
   16583        34334 :             result = PRAGMA_OMP_CLAUSE_REDUCTION;
   16584              :           break;
   16585         5173 :         case 's':
   16586         5173 :           if (!strcmp ("safelen", p))
   16587              :             result = PRAGMA_OMP_CLAUSE_SAFELEN;
   16588         4946 :           else if (!strcmp ("schedule", p))
   16589              :             result = PRAGMA_OMP_CLAUSE_SCHEDULE;
   16590         1477 :           else if (!strcmp ("sections", p))
   16591              :             result = PRAGMA_OMP_CLAUSE_SECTIONS;
   16592         1399 :           else if (!strcmp ("self", p))
   16593              :             result = PRAGMA_OACC_CLAUSE_SELF;
   16594         1333 :           else if (!strcmp ("seq", p))
   16595              :             result = PRAGMA_OACC_CLAUSE_SEQ;
   16596         1072 :           else if (!strcmp ("shared", p))
   16597              :             result = PRAGMA_OMP_CLAUSE_SHARED;
   16598          381 :           else if (!strcmp ("simd", p))
   16599              :             result = PRAGMA_OMP_CLAUSE_SIMD;
   16600          324 :           else if (!strcmp ("simdlen", p))
   16601        34334 :             result = PRAGMA_OMP_CLAUSE_SIMDLEN;
   16602              :           break;
   16603          999 :         case 't':
   16604          999 :           if (!strcmp ("task_reduction", p))
   16605              :             result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
   16606          913 :           else if (!strcmp ("taskgroup", p))
   16607              :             result = PRAGMA_OMP_CLAUSE_TASKGROUP;
   16608          803 :           else if (!strcmp ("thread_limit", p))
   16609              :             result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
   16610          649 :           else if (!strcmp ("threads", p))
   16611              :             result = PRAGMA_OMP_CLAUSE_THREADS;
   16612          603 :           else if (!strcmp ("tile", p))
   16613              :             result = PRAGMA_OACC_CLAUSE_TILE;
   16614          480 :           else if (!strcmp ("to", p))
   16615        34334 :             result = PRAGMA_OMP_CLAUSE_TO;
   16616              :           break;
   16617          351 :         case 'u':
   16618          351 :           if (!strcmp ("uniform", p))
   16619              :             result = PRAGMA_OMP_CLAUSE_UNIFORM;
   16620          236 :           else if (!strcmp ("untied", p))
   16621              :             result = PRAGMA_OMP_CLAUSE_UNTIED;
   16622          139 :           else if (!strcmp ("use", p))
   16623              :             result = PRAGMA_OMP_CLAUSE_USE;
   16624           96 :           else if (!strcmp ("use_device", p))
   16625              :             result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
   16626           75 :           else if (!strcmp ("use_device_addr", p))
   16627              :             result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
   16628           40 :           else if (!strcmp ("use_device_ptr", p))
   16629              :             result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
   16630           30 :           else if (!strcmp ("uses_allocators", p))
   16631        34334 :             result = PRAGMA_OMP_CLAUSE_USES_ALLOCATORS;
   16632              :           break;
   16633          741 :         case 'v':
   16634          741 :           if (!strcmp ("vector", p))
   16635              :             result = PRAGMA_OACC_CLAUSE_VECTOR;
   16636          223 :           else if (!strcmp ("vector_length", p))
   16637        34334 :             result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
   16638              :           break;
   16639          550 :         case 'w':
   16640          550 :           if (!strcmp ("wait", p))
   16641              :             result = PRAGMA_OACC_CLAUSE_WAIT;
   16642          453 :           else if (!strcmp ("worker", p))
   16643        34334 :             result = PRAGMA_OACC_CLAUSE_WORKER;
   16644              :           break;
   16645              :         }
   16646              :     }
   16647              : 
   16648        34334 :   if (result != PRAGMA_OMP_CLAUSE_NONE)
   16649        34218 :     c_parser_consume_token (parser);
   16650              : 
   16651        34334 :   return result;
   16652              : }
   16653              : 
   16654              : /* Validate that a clause of the given type does not already exist.  */
   16655              : 
   16656              : static void
   16657        17592 : check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
   16658              :                            const char *name)
   16659              : {
   16660        17592 :   if (tree c = omp_find_clause (clauses, code))
   16661          348 :     error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
   16662        17592 : }
   16663              : 
   16664              : /* OpenACC 2.0
   16665              :    Parse wait clause or wait directive parameters.  */
   16666              : 
   16667              : static tree
   16668          131 : c_parser_oacc_wait_list (c_parser *parser, location_t clause_loc, tree list)
   16669              : {
   16670          131 :   vec<tree, va_gc> *args;
   16671          131 :   tree t, args_tree;
   16672              : 
   16673          131 :   matching_parens parens;
   16674          131 :   if (!parens.require_open (parser))
   16675              :     return list;
   16676              : 
   16677          131 :   args = c_parser_expr_list (parser, false, true, NULL, NULL, NULL, NULL);
   16678          131 :   args_tree = build_tree_list_vec (args);
   16679              : 
   16680          305 :   for (t = args_tree; t; t = TREE_CHAIN (t))
   16681              :     {
   16682          174 :       tree targ = TREE_VALUE (t);
   16683              : 
   16684          174 :       if (targ != error_mark_node)
   16685              :         {
   16686          160 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
   16687              :             {
   16688            6 :               c_parser_error (parser, "expression must be integral");
   16689            6 :               targ = error_mark_node;
   16690              :             }
   16691              :           else
   16692              :             {
   16693          154 :               tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
   16694              : 
   16695          154 :               OMP_CLAUSE_DECL (c) = targ;
   16696          154 :               OMP_CLAUSE_CHAIN (c) = list;
   16697          154 :               list = c;
   16698              :             }
   16699              :         }
   16700              :     }
   16701              : 
   16702          131 :   release_tree_vector (args);
   16703          131 :   parens.require_close (parser);
   16704          131 :   return list;
   16705              : }
   16706              : 
   16707              : /* OpenACC 2.0, OpenMP 2.5:
   16708              :    variable-list:
   16709              :      identifier
   16710              :      variable-list , identifier
   16711              : 
   16712              :    If KIND is nonzero, create the appropriate node and install the
   16713              :    decl in OMP_CLAUSE_DECL and add the node to the head of the list.
   16714              :    If KIND is nonzero, CLAUSE_LOC is the location of the clause.
   16715              : 
   16716              :    If KIND is zero (= OMP_CLAUSE_ERROR), create a TREE_LIST with the decl
   16717              :    in TREE_PURPOSE and the location in TREE_VALUE (accessible using
   16718              :    EXPR_LOCATION); return the list created.
   16719              : 
   16720              :    The optional ALLOW_DEREF argument is true if list items can use the deref
   16721              :    (->) operator.  */
   16722              : 
   16723              : struct omp_dim
   16724              : {
   16725              :   tree low_bound, length;
   16726              :   location_t loc;
   16727              :   bool no_colon;
   16728         3314 :   omp_dim (tree lb, tree len, location_t lo, bool nc)
   16729         3314 :   : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
   16730              : };
   16731              : 
   16732              : static tree
   16733        16404 : c_parser_omp_variable_list (c_parser *parser,
   16734              :                             location_t clause_loc,
   16735              :                             enum omp_clause_code kind, tree list,
   16736              :                             bool map_lvalue = false)
   16737              : {
   16738        16404 :   auto_vec<omp_dim> dims;
   16739        16404 :   bool array_section_p;
   16740        16404 :   auto_vec<c_token> tokens;
   16741        16404 :   unsigned int tokens_avail = 0;
   16742        16404 :   c_token *saved_tokens = NULL;
   16743              : 
   16744        19597 :   while (1)
   16745              :     {
   16746        19597 :       tree t = NULL_TREE;
   16747        19597 :       location_t tloc = c_parser_peek_token (parser)->location;
   16748              : 
   16749        19597 :       if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   16750              :         {
   16751          888 :           if (c_parser_next_token_is_not (parser, CPP_NAME)
   16752          888 :               || c_parser_peek_token (parser)->id_kind != C_ID_ID)
   16753              :             {
   16754           29 :               struct c_expr expr;
   16755           29 :               if (kind == OMP_CLAUSE_DEPEND
   16756           27 :                   && c_parser_next_token_is_keyword (parser,
   16757              :                                                      RID_OMP_ALL_MEMORY)
   16758           45 :                   && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
   16759           13 :                       || (c_parser_peek_2nd_token (parser)->type
   16760              :                           == CPP_CLOSE_PAREN)))
   16761              :                 {
   16762           15 :                   expr.value = ridpointers[RID_OMP_ALL_MEMORY];
   16763           15 :                   c_parser_consume_token (parser);
   16764              :                 }
   16765              :               else
   16766           14 :                 expr = c_parser_expr_no_commas (parser, NULL);
   16767           29 :               if (expr.value != error_mark_node)
   16768              :                 {
   16769           27 :                   tree u = build_omp_clause (clause_loc, kind);
   16770           27 :                   OMP_CLAUSE_DECL (u) = expr.value;
   16771           27 :                   OMP_CLAUSE_CHAIN (u) = list;
   16772           27 :                   list = u;
   16773              :                 }
   16774              : 
   16775           29 :               if (c_parser_next_token_is_not (parser, CPP_COMMA))
   16776              :                 break;
   16777              : 
   16778            4 :               c_parser_consume_token (parser);
   16779            4 :               continue;
   16780            4 :             }
   16781              : 
   16782          859 :           tokens.truncate (0);
   16783          859 :           unsigned int nesting_depth = 0;
   16784        11227 :           while (1)
   16785              :             {
   16786         6043 :               c_token *token = c_parser_peek_token (parser);
   16787         6043 :               switch (token->type)
   16788              :                 {
   16789              :                 case CPP_EOF:
   16790              :                 case CPP_PRAGMA_EOL:
   16791              :                   break;
   16792          930 :                 case CPP_OPEN_BRACE:
   16793          930 :                 case CPP_OPEN_PAREN:
   16794          930 :                 case CPP_OPEN_SQUARE:
   16795          930 :                   ++nesting_depth;
   16796          930 :                   goto add;
   16797         1723 :                 case CPP_CLOSE_BRACE:
   16798         1723 :                 case CPP_CLOSE_PAREN:
   16799         1723 :                 case CPP_CLOSE_SQUARE:
   16800         1723 :                   if (nesting_depth-- == 0)
   16801              :                     break;
   16802          930 :                   goto add;
   16803          138 :                 case CPP_COMMA:
   16804          138 :                   if (nesting_depth == 0)
   16805              :                     break;
   16806           72 :                   goto add;
   16807         5184 :                 default:
   16808         5184 :                 add:
   16809         5184 :                   tokens.safe_push (*token);
   16810         5184 :                   c_parser_consume_token (parser);
   16811         5184 :                   continue;
   16812              :                 }
   16813          859 :               break;
   16814         5184 :             }
   16815              : 
   16816              :           /* Make sure nothing tries to read past the end of the tokens.  */
   16817          859 :           c_token eof_token;
   16818          859 :           memset (&eof_token, 0, sizeof (eof_token));
   16819          859 :           eof_token.type = CPP_EOF;
   16820          859 :           tokens.safe_push (eof_token);
   16821          859 :           tokens.safe_push (eof_token);
   16822              : 
   16823          859 :           saved_tokens = parser->tokens;
   16824          859 :           tokens_avail = parser->tokens_avail;
   16825          859 :           parser->tokens = tokens.address ();
   16826         1718 :           parser->tokens_avail = tokens.length ();
   16827              :         }
   16828        18709 :       else if (map_lvalue
   16829         2209 :                && (kind == OMP_CLAUSE_MAP
   16830              :                    || kind == OMP_CLAUSE_TO
   16831         2209 :                    || kind == OMP_CLAUSE_FROM))
   16832              :         {
   16833         2209 :           location_t loc = c_parser_peek_token (parser)->location;
   16834         2209 :           bool save_c_omp_array_section_p = c_omp_array_section_p;
   16835         2209 :           c_omp_array_section_p = true;
   16836         2209 :           c_expr expr = c_parser_expr_no_commas (parser, NULL);
   16837         2209 :           if (expr.value != error_mark_node)
   16838         2195 :             mark_exp_read (expr.value);
   16839         2209 :           c_omp_array_section_p = save_c_omp_array_section_p;
   16840         2209 :           tree decl = expr.value;
   16841              : 
   16842              :          /* This code rewrites a parsed expression containing various tree
   16843              :             codes used to represent array accesses into a more uniform nest of
   16844              :             OMP_ARRAY_SECTION nodes before it is processed by
   16845              :             c-typeck.cc:handle_omp_array_sections_1.  It might be more
   16846              :             efficient to move this logic to that function instead, analysing
   16847              :             the parsed expression directly rather than this preprocessed
   16848              :             form.  (See also equivalent code in cp/parser.cc,
   16849              :             cp/semantics.cc).  */
   16850         2209 :           dims.truncate (0);
   16851         2209 :           if (TREE_CODE (decl) == OMP_ARRAY_SECTION)
   16852              :             {
   16853         1066 :               while (TREE_CODE (decl) == OMP_ARRAY_SECTION)
   16854              :                 {
   16855          563 :                   tree low_bound = TREE_OPERAND (decl, 1);
   16856          563 :                   tree length = TREE_OPERAND (decl, 2);
   16857          563 :                   dims.safe_push (omp_dim (low_bound, length, loc, false));
   16858          563 :                   decl = TREE_OPERAND (decl, 0);
   16859              :                 }
   16860              : 
   16861          536 :               while (TREE_CODE (decl) == ARRAY_REF
   16862              :                      || TREE_CODE (decl) == INDIRECT_REF
   16863          536 :                      || TREE_CODE (decl) == COMPOUND_EXPR)
   16864              :                 {
   16865           33 :                   if (TREE_CODE (decl) == COMPOUND_EXPR)
   16866              :                     {
   16867            2 :                       decl = TREE_OPERAND (decl, 1);
   16868            2 :                       STRIP_NOPS (decl);
   16869              :                     }
   16870           31 :                   else if (TREE_CODE (decl) == INDIRECT_REF)
   16871              :                     {
   16872           46 :                       dims.safe_push (omp_dim (integer_zero_node,
   16873           23 :                                                integer_one_node, loc, true));
   16874           23 :                       decl = TREE_OPERAND (decl, 0);
   16875              :                     }
   16876              :                   else  /* ARRAY_REF. */
   16877              :                     {
   16878            8 :                       tree index = TREE_OPERAND (decl, 1);
   16879           16 :                       dims.safe_push (omp_dim (index, integer_one_node, loc,
   16880            8 :                                                true));
   16881            8 :                       decl = TREE_OPERAND (decl, 0);
   16882              :                     }
   16883              :                 }
   16884              : 
   16885         1600 :               for (int i = dims.length () - 1; i >= 0; i--)
   16886          594 :                 decl = build_omp_array_section (loc,  decl, dims[i].low_bound,
   16887          594 :                                                 dims[i].length);
   16888              :             }
   16889         1706 :           else if (TREE_CODE (decl) == INDIRECT_REF)
   16890              :             {
   16891              :               /* Turn indirection of a pointer "*foo" into "foo[0:1]".  */
   16892           50 :               decl = TREE_OPERAND (decl, 0);
   16893           50 :               STRIP_NOPS (decl);
   16894              : 
   16895           50 :               decl = build_omp_array_section (loc, decl, integer_zero_node,
   16896              :                                               integer_one_node);
   16897              :             }
   16898         1656 :           else if (TREE_CODE (decl) == ARRAY_REF)
   16899              :             {
   16900           12 :               tree idx = TREE_OPERAND (decl, 1);
   16901              : 
   16902           12 :               decl = TREE_OPERAND (decl, 0);
   16903           12 :               STRIP_NOPS (decl);
   16904              : 
   16905           12 :               decl = build_omp_array_section (loc, decl, idx, integer_one_node);
   16906              :             }
   16907         1644 :           else if (TREE_CODE (decl) == NON_LVALUE_EXPR
   16908         1644 :                    || CONVERT_EXPR_P (decl))
   16909            0 :             decl = TREE_OPERAND (decl, 0);
   16910              : 
   16911         2209 :           tree u = build_omp_clause (loc, kind);
   16912         2209 :           OMP_CLAUSE_DECL (u) = decl;
   16913         2209 :           OMP_CLAUSE_CHAIN (u) = list;
   16914         2209 :           list = u;
   16915              : 
   16916         2209 :           goto next_item;
   16917              :         }
   16918              : 
   16919        17359 :       if (c_parser_next_token_is (parser, CPP_NAME)
   16920        17359 :           && c_parser_peek_token (parser)->id_kind == C_ID_ID)
   16921              :         {
   16922        17322 :           t = lookup_name (c_parser_peek_token (parser)->value);
   16923              : 
   16924        17322 :           if (t == NULL_TREE)
   16925              :             {
   16926           14 :               undeclared_variable (c_parser_peek_token (parser)->location,
   16927           14 :               c_parser_peek_token (parser)->value);
   16928           14 :               t = error_mark_node;
   16929              :             }
   16930              : 
   16931        17322 :           c_parser_consume_token (parser);
   16932              :         }
   16933           37 :       else if (c_parser_next_token_is (parser, CPP_KEYWORD)
   16934           37 :                && (c_parser_peek_token (parser)->keyword == RID_FUNCTION_NAME
   16935           15 :                    || (c_parser_peek_token (parser)->keyword
   16936              :                        == RID_PRETTY_FUNCTION_NAME)
   16937            9 :                    || (c_parser_peek_token (parser)->keyword
   16938              :                        == RID_C99_FUNCTION_NAME)))
   16939           20 :         t = c_parser_predefined_identifier (parser).value;
   16940              :       else
   16941              :         {
   16942           17 :           c_parser_error (parser, "expected identifier");
   16943           17 :           break;
   16944              :         }
   16945              : 
   16946        17342 :       if (t == error_mark_node)
   16947              :         ;
   16948        17324 :       else if (kind != 0)  /* kind != OMP_CLAUSE_ERROR */
   16949              :         {
   16950        17092 :           switch (kind)
   16951              :             {
   16952          139 :             case OMP_CLAUSE__CACHE_:
   16953              :               /* The OpenACC cache directive explicitly only allows "array
   16954              :                  elements or subarrays".  */
   16955          139 :               if (c_parser_peek_token (parser)->type != CPP_OPEN_SQUARE)
   16956              :                 {
   16957            3 :                   c_parser_error (parser, "expected %<[%>");
   16958            3 :                   t = error_mark_node;
   16959            3 :                   break;
   16960              :                 }
   16961              :               /* FALLTHROUGH  */
   16962              :             case OMP_CLAUSE_MAP:
   16963              :             case OMP_CLAUSE_FROM:
   16964              :             case OMP_CLAUSE_TO:
   16965          136 :             start_component_ref:
   16966         5963 :               while (c_parser_next_token_is (parser, CPP_DOT)
   16967        11719 :                      || c_parser_next_token_is (parser, CPP_DEREF))
   16968              :                 {
   16969          316 :                   location_t op_loc = c_parser_peek_token (parser)->location;
   16970          316 :                   location_t arrow_loc = UNKNOWN_LOCATION;
   16971          316 :                   if (c_parser_next_token_is (parser, CPP_DEREF))
   16972              :                     {
   16973          109 :                       c_expr t_expr;
   16974          109 :                       t_expr.value = t;
   16975          109 :                       t_expr.original_code = ERROR_MARK;
   16976          109 :                       t_expr.original_type = NULL;
   16977          109 :                       set_c_expr_source_range (&t_expr, op_loc, op_loc);
   16978          109 :                       t_expr.m_decimal = 0;
   16979          109 :                       t_expr = convert_lvalue_to_rvalue (op_loc, t_expr,
   16980              :                                                          true, false);
   16981          109 :                       t = build_indirect_ref (op_loc, t_expr.value, RO_ARROW);
   16982          109 :                       arrow_loc = t_expr.get_location ();
   16983              :                     }
   16984          316 :                   c_parser_consume_token (parser);
   16985          316 :                   if (!c_parser_next_token_is (parser, CPP_NAME))
   16986              :                     {
   16987            0 :                       c_parser_error (parser, "expected identifier");
   16988            0 :                       t = error_mark_node;
   16989            0 :                       break;
   16990              :                     }
   16991              : 
   16992          316 :                   c_token *comp_tok = c_parser_peek_token (parser);
   16993          316 :                   tree ident = comp_tok->value;
   16994          316 :                   location_t comp_loc = comp_tok->location;
   16995          316 :                   c_parser_consume_token (parser);
   16996          316 :                   t = build_component_ref (op_loc, t, ident, comp_loc,
   16997              :                                            arrow_loc);
   16998              :                 }
   16999              :               /* FALLTHROUGH  */
   17000        10297 :             case OMP_CLAUSE_AFFINITY:
   17001        10297 :             case OMP_CLAUSE_DEPEND:
   17002        10297 :             case OMP_CLAUSE_REDUCTION:
   17003        10297 :             case OMP_CLAUSE_IN_REDUCTION:
   17004        10297 :             case OMP_CLAUSE_TASK_REDUCTION:
   17005        10297 :             case OMP_CLAUSE_HAS_DEVICE_ADDR:
   17006        10297 :               array_section_p = false;
   17007        10297 :               dims.truncate (0);
   17008        23314 :               while (c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
   17009              :                 {
   17010         2720 :                   location_t loc = UNKNOWN_LOCATION;
   17011         2720 :                   tree low_bound = NULL_TREE, length = NULL_TREE;
   17012         2720 :                   bool no_colon = false;
   17013              : 
   17014         2720 :                   c_parser_consume_token (parser);
   17015         2720 :                   if (!c_parser_next_token_is (parser, CPP_COLON))
   17016              :                     {
   17017         2300 :                       location_t expr_loc
   17018         2300 :                         = c_parser_peek_token (parser)->location;
   17019         2300 :                       c_expr expr = c_parser_expression (parser);
   17020         2300 :                       expr = convert_lvalue_to_rvalue (expr_loc, expr,
   17021              :                                                        false, true);
   17022         2300 :                       low_bound = expr.value;
   17023         2300 :                       loc = expr_loc;
   17024              :                     }
   17025         2720 :                   if (c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
   17026              :                     {
   17027          432 :                       length = integer_one_node;
   17028          432 :                       no_colon = true;
   17029              :                     }
   17030              :                   else
   17031              :                     {
   17032              :                       /* Look for `:'.  */
   17033         2288 :                       if (!c_parser_require (parser, CPP_COLON,
   17034              :                                              "expected %<:%>"))
   17035              :                         {
   17036            0 :                           t = error_mark_node;
   17037            0 :                           break;
   17038              :                         }
   17039         2288 :                       array_section_p = true;
   17040         2288 :                       if (!c_parser_next_token_is (parser, CPP_CLOSE_SQUARE))
   17041              :                         {
   17042         2103 :                           location_t expr_loc
   17043         2103 :                             = c_parser_peek_token (parser)->location;
   17044         2103 :                           c_expr expr = c_parser_expression (parser);
   17045         2103 :                           expr = convert_lvalue_to_rvalue (expr_loc, expr,
   17046              :                                                            false, true);
   17047         2103 :                           length = expr.value;
   17048              :                         }
   17049              :                     }
   17050              :                   /* Look for the closing `]'.  */
   17051         2720 :                   if (!c_parser_require (parser, CPP_CLOSE_SQUARE,
   17052              :                                          "expected %<]%>"))
   17053              :                     {
   17054            0 :                       t = error_mark_node;
   17055            0 :                       break;
   17056              :                     }
   17057              : 
   17058         2720 :                   dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
   17059              :                 }
   17060              : 
   17061        10297 :               if (t != error_mark_node)
   17062              :                 {
   17063        10297 :                   if ((kind == OMP_CLAUSE_MAP
   17064        10297 :                        || kind == OMP_CLAUSE_FROM
   17065         5193 :                        || kind == OMP_CLAUSE_TO)
   17066         5511 :                       && !array_section_p
   17067        14553 :                       && (c_parser_next_token_is (parser, CPP_DOT)
   17068         4252 :                           || c_parser_next_token_is (parser, CPP_DEREF)))
   17069              :                     {
   17070            8 :                       for (unsigned i = 0; i < dims.length (); i++)
   17071              :                         {
   17072            4 :                           gcc_assert (dims[i].length == integer_one_node);
   17073            4 :                           t = build_array_ref (dims[i].loc,
   17074            4 :                                                t, dims[i].low_bound);
   17075              :                         }
   17076            4 :                       goto start_component_ref;
   17077              :                     }
   17078              :                   else
   17079        13009 :                     for (unsigned i = 0; i < dims.length (); i++)
   17080         5432 :                       t = build_omp_array_section (clause_loc, t,
   17081         2716 :                                                    dims[i].low_bound,
   17082         2716 :                                                    dims[i].length);
   17083              :                 }
   17084              : 
   17085        10293 :               if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   17086          855 :                   && t != error_mark_node
   17087          855 :                   && parser->tokens_avail != 2)
   17088              :                 {
   17089           44 :                   if (array_section_p)
   17090              :                     {
   17091           12 :                       error_at (c_parser_peek_token (parser)->location,
   17092              :                                 "expected %<)%> or %<,%>");
   17093           12 :                       t = error_mark_node;
   17094              :                     }
   17095              :                   else
   17096              :                     {
   17097           32 :                       parser->tokens = tokens.address ();
   17098           32 :                       parser->tokens_avail = tokens.length ();
   17099              : 
   17100           32 :                       t = c_parser_expr_no_commas (parser, NULL).value;
   17101           32 :                       if (t != error_mark_node && parser->tokens_avail != 2)
   17102              :                         {
   17103            0 :                           error_at (c_parser_peek_token (parser)->location,
   17104              :                                     "expected %<)%> or %<,%>");
   17105            0 :                           t = error_mark_node;
   17106              :                         }
   17107              :                     }
   17108              :                 }
   17109              :               break;
   17110              :             default:
   17111              :               break;
   17112              :             }
   17113              : 
   17114        17092 :           if (t != error_mark_node)
   17115              :             {
   17116        17077 :               tree u = build_omp_clause (clause_loc, kind);
   17117        17077 :               OMP_CLAUSE_DECL (u) = t;
   17118        17077 :               OMP_CLAUSE_CHAIN (u) = list;
   17119        17077 :               list = u;
   17120              :             }
   17121              :         }
   17122              :       else  /* kind == OMP_CLAUSE_ERROR */
   17123          232 :         list = tree_cons (t, build_empty_stmt (tloc), list);
   17124              : 
   17125        17342 :       if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
   17126              :         {
   17127          859 :           parser->tokens = saved_tokens;
   17128          859 :           parser->tokens_avail = tokens_avail;
   17129              :         }
   17130              : 
   17131        16483 :     next_item:
   17132        19551 :       if (c_parser_next_token_is_not (parser, CPP_COMMA))
   17133              :         break;
   17134              : 
   17135         3189 :       c_parser_consume_token (parser);
   17136              :     }
   17137              : 
   17138        16404 :   return list;
   17139        16404 : }
   17140              : 
   17141              : /* Similarly, but expect leading and trailing parenthesis.  This is a very
   17142              :    common case for OpenACC and OpenMP clauses.  The optional ALLOW_DEREF
   17143              :    argument is true if list items can use the deref (->) operator.  */
   17144              : 
   17145              : static tree
   17146         3535 : c_parser_omp_var_list_parens (c_parser *parser, enum omp_clause_code kind,
   17147              :                               tree list, bool map_lvalue = false)
   17148              : {
   17149              :   /* The clauses location.  */
   17150         3535 :   location_t loc = c_parser_peek_token (parser)->location;
   17151              : 
   17152         3535 :   if (parser->in_omp_decl_attribute)
   17153              :     {
   17154           42 :       if (kind)
   17155              :         {
   17156           22 :           tree u = build_omp_clause (loc, kind);
   17157           22 :           OMP_CLAUSE_DECL (u) = parser->in_omp_decl_attribute;
   17158           22 :           OMP_CLAUSE_CHAIN (u) = list;
   17159           22 :           return u;
   17160              :         }
   17161              :       else
   17162           20 :         return tree_cons (parser->in_omp_decl_attribute, NULL_TREE, list);
   17163              :     }
   17164              : 
   17165         3493 :   matching_parens parens;
   17166         3493 :   if (parens.require_open (parser))
   17167              :     {
   17168         3489 :       list = c_parser_omp_variable_list (parser, loc, kind, list, map_lvalue);
   17169         3489 :       parens.skip_until_found_close (parser);
   17170              :     }
   17171              :   return list;
   17172              : }
   17173              : 
   17174              : /* OpenACC 2.0:
   17175              :    copy ( variable-list )
   17176              :    copyin ( variable-list )
   17177              :    copyout ( variable-list )
   17178              :    create ( variable-list )
   17179              :    delete ( variable-list )
   17180              :    present ( variable-list )
   17181              : 
   17182              :    OpenACC 2.6:
   17183              :    no_create ( variable-list )
   17184              :    attach ( variable-list )
   17185              :    detach ( variable-list )
   17186              : 
   17187              :    OpenACC 2.7:
   17188              :    copyin (readonly : variable-list )
   17189              :  */
   17190              : 
   17191              : static tree
   17192         2026 : c_parser_oacc_data_clause (c_parser *parser, pragma_omp_clause c_kind,
   17193              :                            tree list)
   17194              : {
   17195         2026 :   enum gomp_map_kind kind;
   17196         2026 :   switch (c_kind)
   17197              :     {
   17198              :     case PRAGMA_OACC_CLAUSE_ATTACH:
   17199              :       kind = GOMP_MAP_ATTACH;
   17200              :       break;
   17201          806 :     case PRAGMA_OACC_CLAUSE_COPY:
   17202          806 :       kind = GOMP_MAP_TOFROM;
   17203          806 :       break;
   17204          359 :     case PRAGMA_OACC_CLAUSE_COPYIN:
   17205          359 :       kind = GOMP_MAP_TO;
   17206          359 :       break;
   17207          390 :     case PRAGMA_OACC_CLAUSE_COPYOUT:
   17208          390 :       kind = GOMP_MAP_FROM;
   17209          390 :       break;
   17210           94 :     case PRAGMA_OACC_CLAUSE_CREATE:
   17211           94 :       kind = GOMP_MAP_ALLOC;
   17212           94 :       break;
   17213           68 :     case PRAGMA_OACC_CLAUSE_DELETE:
   17214           68 :       kind = GOMP_MAP_RELEASE;
   17215           68 :       break;
   17216           20 :     case PRAGMA_OACC_CLAUSE_DETACH:
   17217           20 :       kind = GOMP_MAP_DETACH;
   17218           20 :       break;
   17219           36 :     case PRAGMA_OACC_CLAUSE_DEVICE:
   17220           36 :       kind = GOMP_MAP_FORCE_TO;
   17221           36 :       break;
   17222           16 :     case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
   17223           16 :       kind = GOMP_MAP_DEVICE_RESIDENT;
   17224           16 :       break;
   17225           13 :     case PRAGMA_OACC_CLAUSE_LINK:
   17226           13 :       kind = GOMP_MAP_LINK;
   17227           13 :       break;
   17228           10 :     case PRAGMA_OACC_CLAUSE_NO_CREATE:
   17229           10 :       kind = GOMP_MAP_IF_PRESENT;
   17230           10 :       break;
   17231          128 :     case PRAGMA_OACC_CLAUSE_PRESENT:
   17232          128 :       kind = GOMP_MAP_FORCE_PRESENT;
   17233          128 :       break;
   17234           59 :     case PRAGMA_OACC_CLAUSE_SELF:
   17235              :       /* "The 'host' clause is a synonym for the 'self' clause."  */
   17236           59 :     case PRAGMA_OACC_CLAUSE_HOST:
   17237           59 :       kind = GOMP_MAP_FORCE_FROM;
   17238           59 :       break;
   17239            0 :     default:
   17240            0 :       gcc_unreachable ();
   17241              :     }
   17242              : 
   17243         2026 :   tree nl = list;
   17244         2026 :   bool readonly = false;
   17245         2026 :   location_t open_loc = c_parser_peek_token (parser)->location;
   17246         2026 :   matching_parens parens;
   17247         2026 :   if (parens.require_open (parser))
   17248              :     {
   17249              :       /* Turn on readonly modifier parsing for copyin clause.  */
   17250         2026 :       if (c_kind == PRAGMA_OACC_CLAUSE_COPYIN)
   17251              :         {
   17252          359 :           c_token *token = c_parser_peek_token (parser);
   17253          359 :           if (token->type == CPP_NAME
   17254          359 :               && !strcmp (IDENTIFIER_POINTER (token->value), "readonly")
   17255          366 :               && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   17256              :             {
   17257            7 :               c_parser_consume_token (parser);
   17258            7 :               c_parser_consume_token (parser);
   17259            7 :               readonly = true;
   17260              :             }
   17261              :         }
   17262         2026 :       nl = c_parser_omp_variable_list (parser, open_loc, OMP_CLAUSE_MAP, list,
   17263              :                                        false);
   17264         2026 :       parens.skip_until_found_close (parser);
   17265              :     }
   17266              : 
   17267         4671 :   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   17268              :     {
   17269         2645 :       OMP_CLAUSE_SET_MAP_KIND (c, kind);
   17270         2645 :       if (readonly)
   17271           13 :         OMP_CLAUSE_MAP_READONLY (c) = 1;
   17272              :     }
   17273              : 
   17274         2026 :   return nl;
   17275              : }
   17276              : 
   17277              : /* OpenACC 2.0:
   17278              :    deviceptr ( variable-list ) */
   17279              : 
   17280              : static tree
   17281           57 : c_parser_oacc_data_clause_deviceptr (c_parser *parser, tree list)
   17282              : {
   17283           57 :   tree vars, t;
   17284              : 
   17285              :   /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
   17286              :      c_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
   17287              :      variable-list must only allow for pointer variables.  */
   17288           57 :   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
   17289          118 :   for (t = vars; t && t; t = TREE_CHAIN (t))
   17290              :     {
   17291           61 :       tree v = TREE_PURPOSE (t);
   17292           61 :       location_t loc = EXPR_LOCATION (TREE_VALUE (t));
   17293              : 
   17294           61 :       if (!VAR_P (v) && TREE_CODE (v) != PARM_DECL)
   17295            3 :         error_at (loc, "%qD is not a variable", v);
   17296           58 :       else if (TREE_TYPE (v) == error_mark_node)
   17297              :         ;
   17298           57 :       else if (!POINTER_TYPE_P (TREE_TYPE (v)))
   17299            7 :         error_at (loc, "%qD is not a pointer variable", v);
   17300              : 
   17301           61 :       tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
   17302           61 :       OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
   17303           61 :       OMP_CLAUSE_DECL (u) = v;
   17304           61 :       OMP_CLAUSE_CHAIN (u) = list;
   17305           61 :       list = u;
   17306              :     }
   17307              : 
   17308           57 :   return list;
   17309              : }
   17310              : 
   17311              : /* OpenACC 2.0, OpenMP 3.0:
   17312              :    collapse ( constant-expression ) */
   17313              : 
   17314              : static tree
   17315         2954 : c_parser_omp_clause_collapse (c_parser *parser, tree list)
   17316              : {
   17317         2954 :   tree c, num = error_mark_node;
   17318         2954 :   HOST_WIDE_INT n;
   17319         2954 :   location_t loc;
   17320              : 
   17321         2954 :   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
   17322         2954 :   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
   17323              : 
   17324         2954 :   loc = c_parser_peek_token (parser)->location;
   17325         2954 :   matching_parens parens;
   17326         2954 :   if (parens.require_open (parser))
   17327              :     {
   17328         2954 :       num = c_parser_expr_no_commas (parser, NULL).value;
   17329         2954 :       parens.skip_until_found_close (parser);
   17330              :     }
   17331         2954 :   if (num == error_mark_node)
   17332              :     return list;
   17333         2954 :   mark_exp_read (num);
   17334         2954 :   num = c_fully_fold (num, false, NULL);
   17335         5908 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
   17336         2954 :       || !tree_fits_shwi_p (num)
   17337         2954 :       || (n = tree_to_shwi (num)) <= 0
   17338         5908 :       || (int) n != n)
   17339              :     {
   17340            0 :       error_at (loc,
   17341              :                 "collapse argument needs positive constant integer expression");
   17342            0 :       return list;
   17343              :     }
   17344         2954 :   c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
   17345         2954 :   OMP_CLAUSE_COLLAPSE_EXPR (c) = num;
   17346         2954 :   OMP_CLAUSE_CHAIN (c) = list;
   17347         2954 :   return c;
   17348              : }
   17349              : 
   17350              : /* OpenMP 2.5:
   17351              :    copyin ( variable-list ) */
   17352              : 
   17353              : static tree
   17354          101 : c_parser_omp_clause_copyin (c_parser *parser, tree list)
   17355              : {
   17356            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYIN, list);
   17357              : }
   17358              : 
   17359              : /* OpenMP 2.5:
   17360              :    copyprivate ( variable-list ) */
   17361              : 
   17362              : static tree
   17363           21 : c_parser_omp_clause_copyprivate (c_parser *parser, tree list)
   17364              : {
   17365            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_COPYPRIVATE, list);
   17366              : }
   17367              : 
   17368              : /* OpenMP 2.5:
   17369              :    default ( none | shared )
   17370              : 
   17371              :    OpenMP 5.1:
   17372              :    default ( private | firstprivate )
   17373              : 
   17374              :    OpenACC:
   17375              :    default ( none | present ) */
   17376              : 
   17377              : static tree
   17378          729 : c_parser_omp_clause_default (c_parser *parser, tree list, bool is_oacc)
   17379              : {
   17380          729 :   enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
   17381          729 :   location_t loc = c_parser_peek_token (parser)->location;
   17382          729 :   tree c;
   17383              : 
   17384          729 :   matching_parens parens;
   17385          729 :   if (!parens.require_open (parser))
   17386              :     return list;
   17387          726 :   if (c_parser_next_token_is (parser, CPP_NAME))
   17388              :     {
   17389          714 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   17390              : 
   17391          714 :       switch (p[0])
   17392              :         {
   17393          391 :         case 'n':
   17394          391 :           if (strcmp ("none", p) != 0)
   17395            0 :             goto invalid_kind;
   17396              :           kind = OMP_CLAUSE_DEFAULT_NONE;
   17397              :           break;
   17398              : 
   17399           23 :         case 'p':
   17400           23 :           if (is_oacc)
   17401              :             {
   17402           18 :               if (strcmp ("present", p) != 0)
   17403            3 :                 goto invalid_kind;
   17404              :               kind = OMP_CLAUSE_DEFAULT_PRESENT;
   17405              :             }
   17406              :           else
   17407              :             {
   17408            5 :               if (strcmp ("private", p) != 0)
   17409            0 :                 goto invalid_kind;
   17410              :               kind = OMP_CLAUSE_DEFAULT_PRIVATE;
   17411              :             }
   17412              :           break;
   17413              : 
   17414            9 :         case 'f':
   17415            9 :           if (strcmp ("firstprivate", p) != 0 || is_oacc)
   17416            0 :             goto invalid_kind;
   17417              :           kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
   17418              :           break;
   17419              : 
   17420          287 :         case 's':
   17421          287 :           if (strcmp ("shared", p) != 0 || is_oacc)
   17422            0 :             goto invalid_kind;
   17423              :           kind = OMP_CLAUSE_DEFAULT_SHARED;
   17424              :           break;
   17425              : 
   17426            4 :         default:
   17427            4 :           goto invalid_kind;
   17428              :         }
   17429              : 
   17430          701 :       c_parser_consume_token (parser);
   17431              :     }
   17432              :   else
   17433              :     {
   17434           25 :     invalid_kind:
   17435           25 :       if (is_oacc)
   17436           21 :         c_parser_error (parser, "expected %<none%> or %<present%>");
   17437              :       else
   17438            4 :         c_parser_error (parser, "expected %<none%>, %<shared%>, "
   17439              :                                 "%<private%> or %<firstprivate%>");
   17440              :     }
   17441          726 :   parens.skip_until_found_close (parser);
   17442              : 
   17443          726 :   if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
   17444              :     return list;
   17445              : 
   17446          701 :   check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default");
   17447          701 :   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULT);
   17448          701 :   OMP_CLAUSE_CHAIN (c) = list;
   17449          701 :   OMP_CLAUSE_DEFAULT_KIND (c) = kind;
   17450              : 
   17451          701 :   return c;
   17452              : }
   17453              : 
   17454              : /* OpenMP 2.5:
   17455              :    firstprivate ( variable-list ) */
   17456              : 
   17457              : static tree
   17458          790 : c_parser_omp_clause_firstprivate (c_parser *parser, tree list)
   17459              : {
   17460            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_FIRSTPRIVATE, list);
   17461              : }
   17462              : 
   17463              : /* OpenMP 3.1:
   17464              :    final ( expression ) */
   17465              : 
   17466              : static tree
   17467           99 : c_parser_omp_clause_final (c_parser *parser, tree list)
   17468              : {
   17469           99 :   location_t loc = c_parser_peek_token (parser)->location;
   17470           99 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   17471              :     {
   17472           99 :       matching_parens parens;
   17473           99 :       tree t, c;
   17474           99 :       if (!parens.require_open (parser))
   17475            0 :         t = error_mark_node;
   17476              :       else
   17477              :         {
   17478           99 :           location_t eloc = c_parser_peek_token (parser)->location;
   17479           99 :           c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17480           99 :           t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
   17481           99 :           t = c_objc_common_truthvalue_conversion (eloc, t);
   17482           99 :           t = c_fully_fold (t, false, NULL);
   17483           99 :           parens.skip_until_found_close (parser);
   17484              :         }
   17485              : 
   17486           99 :       check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final");
   17487              : 
   17488           99 :       c = build_omp_clause (loc, OMP_CLAUSE_FINAL);
   17489           99 :       OMP_CLAUSE_FINAL_EXPR (c) = t;
   17490           99 :       OMP_CLAUSE_CHAIN (c) = list;
   17491           99 :       list = c;
   17492              :     }
   17493              :   else
   17494            0 :     c_parser_error (parser, "expected %<(%>");
   17495              : 
   17496           99 :   return list;
   17497              : }
   17498              : 
   17499              : /* OpenMP 5.1:
   17500              :    indirect [( expression )]
   17501              : */
   17502              : 
   17503              : static tree
   17504           26 : c_parser_omp_clause_indirect (c_parser *parser, tree list)
   17505              : {
   17506           26 :   location_t location = c_parser_peek_token (parser)->location;
   17507           26 :   tree t;
   17508              : 
   17509           26 :   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
   17510              :     {
   17511           17 :       matching_parens parens;
   17512           17 :       if (!parens.require_open (parser))
   17513            1 :         return list;
   17514              : 
   17515           17 :       location_t loc = c_parser_peek_token (parser)->location;
   17516           17 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17517           17 :       expr = convert_lvalue_to_rvalue (loc, expr, true, true);
   17518           17 :       t = c_objc_common_truthvalue_conversion (loc, expr.value);
   17519           17 :       t = c_fully_fold (t, false, NULL);
   17520           34 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
   17521           34 :           || TREE_CODE (t) != INTEGER_CST)
   17522              :         {
   17523            1 :           c_parser_error (parser, "expected constant logical expression");
   17524            1 :           return list;
   17525              :         }
   17526           16 :       parens.skip_until_found_close (parser);
   17527              :     }
   17528              :   else
   17529            9 :     t = integer_one_node;
   17530              : 
   17531           25 :   check_no_duplicate_clause (list, OMP_CLAUSE_INDIRECT, "indirect");
   17532              : 
   17533           25 :   tree c = build_omp_clause (location, OMP_CLAUSE_INDIRECT);
   17534           25 :   OMP_CLAUSE_INDIRECT_EXPR (c) = t;
   17535           25 :   OMP_CLAUSE_CHAIN (c) = list;
   17536              : 
   17537           25 :   return c;
   17538              : }
   17539              : 
   17540              : /* OpenACC, OpenMP 2.5:
   17541              :    if ( expression )
   17542              : 
   17543              :    OpenMP 4.5:
   17544              :    if ( directive-name-modifier : expression )
   17545              : 
   17546              :    directive-name-modifier:
   17547              :      parallel | task | taskloop | target data | target | target update
   17548              :      | target enter data | target exit data
   17549              : 
   17550              :    OpenMP 5.0:
   17551              :    directive-name-modifier:
   17552              :      ... | simd | cancel  */
   17553              : 
   17554              : static tree
   17555          884 : c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
   17556              : {
   17557          884 :   location_t location = c_parser_peek_token (parser)->location;
   17558          884 :   enum tree_code if_modifier = ERROR_MARK;
   17559              : 
   17560          884 :   matching_parens parens;
   17561          884 :   if (!parens.require_open (parser))
   17562              :     return list;
   17563              : 
   17564         1663 :   if (is_omp && c_parser_next_token_is (parser, CPP_NAME))
   17565              :     {
   17566          638 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   17567          638 :       int n = 2;
   17568          638 :       if (strcmp (p, "cancel") == 0)
   17569              :         if_modifier = VOID_CST;
   17570          623 :       else if (strcmp (p, "parallel") == 0)
   17571              :         if_modifier = OMP_PARALLEL;
   17572          484 :       else if (strcmp (p, "simd") == 0)
   17573              :         if_modifier = OMP_SIMD;
   17574          378 :       else if (strcmp (p, "task") == 0)
   17575              :         if_modifier = OMP_TASK;
   17576          367 :       else if (strcmp (p, "taskloop") == 0)
   17577              :         if_modifier = OMP_TASKLOOP;
   17578          316 :       else if (strcmp (p, "target") == 0)
   17579              :         {
   17580          102 :           if_modifier = OMP_TARGET;
   17581          102 :           if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   17582              :             {
   17583           37 :               p = IDENTIFIER_POINTER (c_parser_peek_2nd_token (parser)->value);
   17584           37 :               if (strcmp ("data", p) == 0)
   17585              :                 if_modifier = OMP_TARGET_DATA;
   17586           29 :               else if (strcmp ("update", p) == 0)
   17587              :                 if_modifier = OMP_TARGET_UPDATE;
   17588           18 :               else if (strcmp ("enter", p) == 0)
   17589              :                 if_modifier = OMP_TARGET_ENTER_DATA;
   17590           10 :               else if (strcmp ("exit", p) == 0)
   17591              :                 if_modifier = OMP_TARGET_EXIT_DATA;
   17592            0 :               if (if_modifier != OMP_TARGET)
   17593              :                 {
   17594           37 :                   n = 3;
   17595           37 :                   c_parser_consume_token (parser);
   17596              :                 }
   17597              :               else
   17598              :                 {
   17599            0 :                   location_t loc = c_parser_peek_2nd_token (parser)->location;
   17600            0 :                   error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
   17601              :                                  "or %<exit%>");
   17602            0 :                   if_modifier = ERROR_MARK;
   17603              :                 }
   17604            0 :               if (if_modifier == OMP_TARGET_ENTER_DATA
   17605           37 :                   || if_modifier == OMP_TARGET_EXIT_DATA)
   17606              :                 {
   17607           18 :                   if (c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   17608              :                     {
   17609           18 :                       p = IDENTIFIER_POINTER
   17610              :                                 (c_parser_peek_2nd_token (parser)->value);
   17611           18 :                       if (strcmp ("data", p) == 0)
   17612           18 :                         n = 4;
   17613              :                     }
   17614           18 :                   if (n == 4)
   17615           18 :                     c_parser_consume_token (parser);
   17616              :                   else
   17617              :                     {
   17618            0 :                       location_t loc
   17619            0 :                         = c_parser_peek_2nd_token (parser)->location;
   17620            0 :                       error_at (loc, "expected %<data%>");
   17621            0 :                       if_modifier = ERROR_MARK;
   17622              :                     }
   17623              :                 }
   17624              :             }
   17625              :         }
   17626           37 :       if (if_modifier != ERROR_MARK)
   17627              :         {
   17628          424 :           if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   17629              :             {
   17630          423 :               c_parser_consume_token (parser);
   17631          423 :               c_parser_consume_token (parser);
   17632              :             }
   17633              :           else
   17634              :             {
   17635            1 :               if (n > 2)
   17636              :                 {
   17637            0 :                   location_t loc = c_parser_peek_2nd_token (parser)->location;
   17638            0 :                   error_at (loc, "expected %<:%>");
   17639              :                 }
   17640              :               if_modifier = ERROR_MARK;
   17641              :             }
   17642              :         }
   17643              :     }
   17644              : 
   17645          884 :   location_t loc = c_parser_peek_token (parser)->location;
   17646          884 :   c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17647          884 :   expr = convert_lvalue_to_rvalue (loc, expr, true, true);
   17648          884 :   tree t = c_objc_common_truthvalue_conversion (loc, expr.value), c;
   17649          884 :   t = c_fully_fold (t, false, NULL);
   17650          884 :   parens.skip_until_found_close (parser);
   17651              : 
   17652         3988 :   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
   17653         3144 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
   17654              :       {
   17655          174 :         if (if_modifier != ERROR_MARK
   17656          174 :             && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
   17657              :           {
   17658            9 :             const char *p = NULL;
   17659            9 :             switch (if_modifier)
   17660              :               {
   17661              :               case VOID_CST: p = "cancel"; break;
   17662            1 :               case OMP_PARALLEL: p = "parallel"; break;
   17663            0 :               case OMP_SIMD: p = "simd"; break;
   17664            1 :               case OMP_TASK: p = "task"; break;
   17665            1 :               case OMP_TASKLOOP: p = "taskloop"; break;
   17666            1 :               case OMP_TARGET_DATA: p = "target data"; break;
   17667            1 :               case OMP_TARGET: p = "target"; break;
   17668            1 :               case OMP_TARGET_UPDATE: p = "target update"; break;
   17669            1 :               case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
   17670            1 :               case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
   17671            0 :               default: gcc_unreachable ();
   17672              :               }
   17673            9 :             error_at (location, "too many %<if%> clauses with %qs modifier",
   17674              :                       p);
   17675            9 :             return list;
   17676              :           }
   17677          165 :         else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
   17678              :           {
   17679           13 :             if (!is_omp)
   17680            1 :               error_at (location, "too many %<if%> clauses");
   17681              :             else
   17682           12 :               error_at (location, "too many %<if%> clauses without modifier");
   17683           13 :             return list;
   17684              :           }
   17685          152 :         else if (if_modifier == ERROR_MARK
   17686          152 :                  || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
   17687              :           {
   17688           18 :             error_at (location, "if any %<if%> clause has modifier, then all "
   17689              :                                 "%<if%> clauses have to use modifier");
   17690           18 :             return list;
   17691              :           }
   17692              :       }
   17693              : 
   17694          844 :   c = build_omp_clause (location, OMP_CLAUSE_IF);
   17695          844 :   OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
   17696          844 :   OMP_CLAUSE_IF_EXPR (c) = t;
   17697          844 :   OMP_CLAUSE_CHAIN (c) = list;
   17698          844 :   return c;
   17699              : }
   17700              : 
   17701              : /* OpenMP 2.5:
   17702              :    lastprivate ( variable-list )
   17703              : 
   17704              :    OpenMP 5.0:
   17705              :    lastprivate ( [ lastprivate-modifier : ] variable-list ) */
   17706              : 
   17707              : static tree
   17708          732 : c_parser_omp_clause_lastprivate (c_parser *parser, tree list)
   17709              : {
   17710              :   /* The clauses location.  */
   17711          732 :   location_t loc = c_parser_peek_token (parser)->location;
   17712              : 
   17713          732 :   if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   17714              :     {
   17715          732 :       bool conditional = false;
   17716          732 :       if (c_parser_next_token_is (parser, CPP_NAME)
   17717          732 :           && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   17718              :         {
   17719          107 :           const char *p
   17720          107 :             = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   17721          107 :           if (strcmp (p, "conditional") == 0)
   17722              :             {
   17723          107 :               conditional = true;
   17724          107 :               c_parser_consume_token (parser);
   17725          107 :               c_parser_consume_token (parser);
   17726              :             }
   17727              :         }
   17728          732 :       tree nlist = c_parser_omp_variable_list (parser, loc,
   17729              :                                                OMP_CLAUSE_LASTPRIVATE, list);
   17730          732 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
   17731          732 :       if (conditional)
   17732          246 :         for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
   17733          139 :           OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
   17734          732 :       return nlist;
   17735              :     }
   17736              :   return list;
   17737              : }
   17738              : 
   17739              : /* OpenMP 3.1:
   17740              :    mergeable */
   17741              : 
   17742              : static tree
   17743           79 : c_parser_omp_clause_mergeable (c_parser *parser ATTRIBUTE_UNUSED, tree list)
   17744              : {
   17745           79 :   tree c;
   17746              : 
   17747              :   /* FIXME: Should we allow duplicates?  */
   17748           79 :   check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable");
   17749              : 
   17750           79 :   c = build_omp_clause (c_parser_peek_token (parser)->location,
   17751              :                         OMP_CLAUSE_MERGEABLE);
   17752           79 :   OMP_CLAUSE_CHAIN (c) = list;
   17753              : 
   17754           79 :   return c;
   17755              : }
   17756              : 
   17757              : /* OpenMP 2.5:
   17758              :    nowait */
   17759              : 
   17760              : static tree
   17761          391 : c_parser_omp_clause_nowait (c_parser *parser ATTRIBUTE_UNUSED, tree list)
   17762              : {
   17763          391 :   tree c;
   17764          391 :   location_t loc = c_parser_peek_token (parser)->location;
   17765              : 
   17766          391 :   check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait");
   17767              : 
   17768          391 :   c = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
   17769          391 :   OMP_CLAUSE_CHAIN (c) = list;
   17770          391 :   return c;
   17771              : }
   17772              : 
   17773              : /* OpenMP 2.5:
   17774              :    num_threads ( expression ) */
   17775              : 
   17776              : static tree
   17777          426 : c_parser_omp_clause_num_threads (c_parser *parser, tree list)
   17778              : {
   17779          426 :   location_t num_threads_loc = c_parser_peek_token (parser)->location;
   17780          426 :   matching_parens parens;
   17781          426 :   if (parens.require_open (parser))
   17782              :     {
   17783          426 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   17784          426 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17785          426 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   17786          426 :       tree c, t = expr.value;
   17787          426 :       t = c_fully_fold (t, false, NULL);
   17788              : 
   17789          426 :       parens.skip_until_found_close (parser);
   17790              : 
   17791          426 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   17792              :         {
   17793            0 :           c_parser_error (parser, "expected integer expression");
   17794            0 :           return list;
   17795              :         }
   17796              : 
   17797              :       /* Attempt to statically determine when the number isn't positive.  */
   17798          426 :       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
   17799          426 :                        build_int_cst (TREE_TYPE (t), 0));
   17800          426 :       protected_set_expr_location (c, expr_loc);
   17801          426 :       if (c == boolean_true_node)
   17802              :         {
   17803            1 :           warning_at (expr_loc, OPT_Wopenmp,
   17804              :                       "%<num_threads%> value must be positive");
   17805            1 :           t = integer_one_node;
   17806              :         }
   17807              : 
   17808          426 :       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS, "num_threads");
   17809              : 
   17810          426 :       c = build_omp_clause (num_threads_loc, OMP_CLAUSE_NUM_THREADS);
   17811          426 :       OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
   17812          426 :       OMP_CLAUSE_CHAIN (c) = list;
   17813          426 :       list = c;
   17814              :     }
   17815              : 
   17816              :   return list;
   17817              : }
   17818              : 
   17819              : /* OpenMP 4.5:
   17820              :    num_tasks ( expression )
   17821              : 
   17822              :    OpenMP 5.1:
   17823              :    num_tasks ( strict : expression ) */
   17824              : 
   17825              : static tree
   17826           50 : c_parser_omp_clause_num_tasks (c_parser *parser, tree list)
   17827              : {
   17828           50 :   location_t num_tasks_loc = c_parser_peek_token (parser)->location;
   17829           50 :   matching_parens parens;
   17830           50 :   if (parens.require_open (parser))
   17831              :     {
   17832           50 :       bool strict = false;
   17833           50 :       if (c_parser_next_token_is (parser, CPP_NAME)
   17834           40 :           && c_parser_peek_2nd_token (parser)->type == CPP_COLON
   17835           51 :           && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
   17836              :                      "strict") == 0)
   17837              :         {
   17838            1 :           strict = true;
   17839            1 :           c_parser_consume_token (parser);
   17840            1 :           c_parser_consume_token (parser);
   17841              :         }
   17842              : 
   17843           50 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   17844           50 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17845           50 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   17846           50 :       tree c, t = expr.value;
   17847           50 :       t = c_fully_fold (t, false, NULL);
   17848              : 
   17849           50 :       parens.skip_until_found_close (parser);
   17850              : 
   17851           50 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   17852              :         {
   17853            0 :           c_parser_error (parser, "expected integer expression");
   17854            0 :           return list;
   17855              :         }
   17856              : 
   17857              :       /* Attempt to statically determine when the number isn't positive.  */
   17858           50 :       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
   17859           50 :                            build_int_cst (TREE_TYPE (t), 0));
   17860           50 :       if (CAN_HAVE_LOCATION_P (c))
   17861           40 :         SET_EXPR_LOCATION (c, expr_loc);
   17862           50 :       if (c == boolean_true_node)
   17863              :         {
   17864            0 :           warning_at (expr_loc, OPT_Wopenmp,
   17865              :                       "%<num_tasks%> value must be positive");
   17866            0 :           t = integer_one_node;
   17867              :         }
   17868              : 
   17869           50 :       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS, "num_tasks");
   17870              : 
   17871           50 :       c = build_omp_clause (num_tasks_loc, OMP_CLAUSE_NUM_TASKS);
   17872           50 :       OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
   17873           50 :       OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
   17874           50 :       OMP_CLAUSE_CHAIN (c) = list;
   17875           50 :       list = c;
   17876              :     }
   17877              : 
   17878              :   return list;
   17879              : }
   17880              : 
   17881              : /* OpenMP 4.5:
   17882              :    grainsize ( expression )
   17883              : 
   17884              :    OpenMP 5.1:
   17885              :    grainsize ( strict : expression ) */
   17886              : 
   17887              : static tree
   17888           62 : c_parser_omp_clause_grainsize (c_parser *parser, tree list)
   17889              : {
   17890           62 :   location_t grainsize_loc = c_parser_peek_token (parser)->location;
   17891           62 :   matching_parens parens;
   17892           62 :   if (parens.require_open (parser))
   17893              :     {
   17894           62 :       bool strict = false;
   17895           62 :       if (c_parser_next_token_is (parser, CPP_NAME)
   17896           47 :           && c_parser_peek_2nd_token (parser)->type == CPP_COLON
   17897           63 :           && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
   17898              :                      "strict") == 0)
   17899              :         {
   17900            1 :           strict = true;
   17901            1 :           c_parser_consume_token (parser);
   17902            1 :           c_parser_consume_token (parser);
   17903              :         }
   17904              : 
   17905           62 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   17906           62 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17907           62 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   17908           62 :       tree c, t = expr.value;
   17909           62 :       t = c_fully_fold (t, false, NULL);
   17910              : 
   17911           62 :       parens.skip_until_found_close (parser);
   17912              : 
   17913           62 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   17914              :         {
   17915            0 :           c_parser_error (parser, "expected integer expression");
   17916            0 :           return list;
   17917              :         }
   17918              : 
   17919              :       /* Attempt to statically determine when the number isn't positive.  */
   17920           62 :       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
   17921           62 :                            build_int_cst (TREE_TYPE (t), 0));
   17922           62 :       if (CAN_HAVE_LOCATION_P (c))
   17923           47 :         SET_EXPR_LOCATION (c, expr_loc);
   17924           62 :       if (c == boolean_true_node)
   17925              :         {
   17926            0 :           warning_at (expr_loc, OPT_Wopenmp,
   17927              :                       "%<grainsize%> value must be positive");
   17928            0 :           t = integer_one_node;
   17929              :         }
   17930              : 
   17931           62 :       check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE, "grainsize");
   17932              : 
   17933           62 :       c = build_omp_clause (grainsize_loc, OMP_CLAUSE_GRAINSIZE);
   17934           62 :       OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
   17935           62 :       OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
   17936           62 :       OMP_CLAUSE_CHAIN (c) = list;
   17937           62 :       list = c;
   17938              :     }
   17939              : 
   17940              :   return list;
   17941              : }
   17942              : 
   17943              : /* OpenMP 4.5:
   17944              :    priority ( expression ) */
   17945              : 
   17946              : static tree
   17947           98 : c_parser_omp_clause_priority (c_parser *parser, tree list)
   17948              : {
   17949           98 :   location_t priority_loc = c_parser_peek_token (parser)->location;
   17950           98 :   matching_parens parens;
   17951           98 :   if (parens.require_open (parser))
   17952              :     {
   17953           98 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   17954           98 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   17955           98 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   17956           98 :       tree c, t = expr.value;
   17957           98 :       t = c_fully_fold (t, false, NULL);
   17958              : 
   17959           98 :       parens.skip_until_found_close (parser);
   17960              : 
   17961           98 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   17962              :         {
   17963            0 :           c_parser_error (parser, "expected integer expression");
   17964            0 :           return list;
   17965              :         }
   17966              : 
   17967              :       /* Attempt to statically determine when the number isn't
   17968              :          non-negative.  */
   17969           98 :       c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, t,
   17970           98 :                            build_int_cst (TREE_TYPE (t), 0));
   17971           98 :       if (CAN_HAVE_LOCATION_P (c))
   17972           87 :         SET_EXPR_LOCATION (c, expr_loc);
   17973           98 :       if (c == boolean_true_node)
   17974              :         {
   17975            0 :           warning_at (expr_loc, OPT_Wopenmp,
   17976              :                       "%<priority%> value must be non-negative");
   17977            0 :           t = integer_one_node;
   17978              :         }
   17979              : 
   17980           98 :       check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY, "priority");
   17981              : 
   17982           98 :       c = build_omp_clause (priority_loc, OMP_CLAUSE_PRIORITY);
   17983           98 :       OMP_CLAUSE_PRIORITY_EXPR (c) = t;
   17984           98 :       OMP_CLAUSE_CHAIN (c) = list;
   17985           98 :       list = c;
   17986              :     }
   17987              : 
   17988              :   return list;
   17989              : }
   17990              : 
   17991              : /* OpenMP 4.5:
   17992              :    hint ( expression ) */
   17993              : 
   17994              : static tree
   17995           58 : c_parser_omp_clause_hint (c_parser *parser, tree list)
   17996              : {
   17997           58 :   location_t hint_loc = c_parser_peek_token (parser)->location;
   17998           58 :   matching_parens parens;
   17999           58 :   if (parens.require_open (parser))
   18000              :     {
   18001           58 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   18002           58 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   18003           58 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   18004           58 :       tree c, t = expr.value;
   18005           58 :       t = c_fully_fold (t, false, NULL);
   18006          116 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
   18007           57 :           || TREE_CODE (t) != INTEGER_CST
   18008          111 :           || tree_int_cst_sgn (t) == -1)
   18009              :         {
   18010            6 :           c_parser_error (parser, "expected constant integer expression "
   18011              :                                   "with valid sync-hint value");
   18012            6 :           return list;
   18013              :         }
   18014           52 :       parens.skip_until_found_close (parser);
   18015           52 :       check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint");
   18016              : 
   18017           52 :       c = build_omp_clause (hint_loc, OMP_CLAUSE_HINT);
   18018           52 :       OMP_CLAUSE_HINT_EXPR (c) = t;
   18019           52 :       OMP_CLAUSE_CHAIN (c) = list;
   18020           52 :       list = c;
   18021              :     }
   18022              : 
   18023              :   return list;
   18024              : }
   18025              : 
   18026              : /* OpenMP 5.1:
   18027              :    filter ( integer-expression ) */
   18028              : 
   18029              : static tree
   18030           63 : c_parser_omp_clause_filter (c_parser *parser, tree list)
   18031              : {
   18032           63 :   location_t hint_loc = c_parser_peek_token (parser)->location;
   18033           63 :   matching_parens parens;
   18034           63 :   if (parens.require_open (parser))
   18035              :     {
   18036           63 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   18037           63 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   18038           63 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   18039           63 :       tree c, t = expr.value;
   18040           63 :       t = c_fully_fold (t, false, NULL);
   18041           63 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   18042              :         {
   18043            2 :           c_parser_error (parser, "expected integer expression");
   18044            2 :           return list;
   18045              :         }
   18046           61 :       parens.skip_until_found_close (parser);
   18047           61 :       check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter");
   18048              : 
   18049           61 :       c = build_omp_clause (hint_loc, OMP_CLAUSE_FILTER);
   18050           61 :       OMP_CLAUSE_FILTER_EXPR (c) = t;
   18051           61 :       OMP_CLAUSE_CHAIN (c) = list;
   18052           61 :       list = c;
   18053              :     }
   18054              : 
   18055              :   return list;
   18056              : }
   18057              : 
   18058              : /* OpenMP 4.5:
   18059              :    defaultmap ( tofrom : scalar )
   18060              : 
   18061              :    OpenMP 5.0:
   18062              :    defaultmap ( implicit-behavior [ : variable-category ] ) */
   18063              : 
   18064              : static tree
   18065          238 : c_parser_omp_clause_defaultmap (c_parser *parser, tree list)
   18066              : {
   18067          238 :   location_t loc = c_parser_peek_token (parser)->location;
   18068          238 :   tree c;
   18069          238 :   const char *p;
   18070          238 :   enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
   18071          238 :   enum omp_clause_defaultmap_kind category
   18072              :     = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
   18073              : 
   18074          238 :   matching_parens parens;
   18075          238 :   if (!parens.require_open (parser))
   18076              :     return list;
   18077          238 :   if (c_parser_next_token_is_keyword (parser, RID_DEFAULT))
   18078              :     p = "default";
   18079          231 :   else if (!c_parser_next_token_is (parser, CPP_NAME))
   18080              :     {
   18081            2 :     invalid_behavior:
   18082            3 :       c_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
   18083              :                               "%<tofrom%>, %<firstprivate%>, %<none%> "
   18084              :                               "or %<default%>");
   18085            3 :       goto out_err;
   18086              :     }
   18087              :   else
   18088          229 :     p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18089              : 
   18090          236 :   switch (p[0])
   18091              :     {
   18092            7 :     case 'a':
   18093            7 :       if (strcmp ("alloc", p) == 0)
   18094              :         behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
   18095              :       else
   18096            0 :         goto invalid_behavior;
   18097              :       break;
   18098              : 
   18099            7 :     case 'd':
   18100            7 :       if (strcmp ("default", p) == 0)
   18101              :         behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
   18102              :       else
   18103            0 :         goto invalid_behavior;
   18104              :       break;
   18105              : 
   18106           27 :     case 'f':
   18107           27 :       if (strcmp ("firstprivate", p) == 0)
   18108              :         behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
   18109            3 :       else if (strcmp ("from", p) == 0)
   18110              :         behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
   18111              :       else
   18112            0 :         goto invalid_behavior;
   18113              :       break;
   18114              : 
   18115          101 :     case 'n':
   18116          101 :       if (strcmp ("none", p) == 0)
   18117              :         behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
   18118              :       else
   18119            0 :         goto invalid_behavior;
   18120              :       break;
   18121              : 
   18122            4 :     case 'p':
   18123            4 :       if (strcmp ("present", p) == 0)
   18124              :         behavior = OMP_CLAUSE_DEFAULTMAP_PRESENT;
   18125              :       else
   18126            0 :         goto invalid_behavior;
   18127              :       break;
   18128              : 
   18129           89 :     case 't':
   18130           89 :       if (strcmp ("tofrom", p) == 0)
   18131              :         behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
   18132            4 :       else if (strcmp ("to", p) == 0)
   18133              :         behavior = OMP_CLAUSE_DEFAULTMAP_TO;
   18134              :       else
   18135            0 :         goto invalid_behavior;
   18136              :       break;
   18137              : 
   18138            1 :     default:
   18139            1 :       goto invalid_behavior;
   18140              :     }
   18141          235 :   c_parser_consume_token (parser);
   18142              : 
   18143          235 :   if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   18144              :     {
   18145          131 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   18146            3 :         goto out_err;
   18147          128 :       if (!c_parser_next_token_is (parser, CPP_NAME))
   18148              :         {
   18149            1 :         invalid_category:
   18150            2 :           c_parser_error (parser, "expected %<scalar%>, %<aggregate%>, "
   18151              :                                   "%<pointer%> or %<all%>");
   18152            2 :           goto out_err;
   18153              :         }
   18154          127 :       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18155          127 :       switch (p[0])
   18156              :         {
   18157           22 :         case 'a':
   18158           22 :           if (strcmp ("aggregate", p) == 0)
   18159              :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
   18160            8 :           else if (strcmp ("all", p) == 0)
   18161              :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL;
   18162              :           else
   18163            0 :             goto invalid_category;
   18164              :           break;
   18165              : 
   18166           14 :         case 'p':
   18167           14 :           if (strcmp ("pointer", p) == 0)
   18168              :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
   18169              :           else
   18170            0 :             goto invalid_category;
   18171              :           break;
   18172              : 
   18173           90 :         case 's':
   18174           90 :           if (strcmp ("scalar", p) == 0)
   18175              :             category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
   18176              :           else
   18177            0 :             goto invalid_category;
   18178              :           break;
   18179              : 
   18180            1 :         default:
   18181            1 :           goto invalid_category;
   18182              :         }
   18183              : 
   18184          126 :       c_parser_consume_token (parser);
   18185              :     }
   18186          230 :   parens.skip_until_found_close (parser);
   18187              : 
   18188          958 :   for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
   18189          511 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
   18190          511 :         && (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
   18191              :             || category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
   18192           32 :             || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
   18193           31 :             || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
   18194              :                 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
   18195           29 :             || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
   18196              :                 == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL)))
   18197              :       {
   18198           13 :         enum omp_clause_defaultmap_kind cat = category;
   18199           13 :         location_t loc = OMP_CLAUSE_LOCATION (c);
   18200           13 :         if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
   18201           13 :             || (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL
   18202            3 :                 && (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
   18203              :                     != OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
   18204            8 :           cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
   18205           13 :         p = NULL;
   18206           13 :         switch (cat)
   18207              :           {
   18208              :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
   18209              :             p = NULL;
   18210              :             break;
   18211            3 :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_ALL:
   18212            3 :             p = "all";
   18213            3 :             break;
   18214            2 :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
   18215            2 :             p = "aggregate";
   18216            2 :             break;
   18217            3 :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
   18218            3 :             p = "pointer";
   18219            3 :             break;
   18220              :           case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
   18221              :             p = "scalar";
   18222              :             break;
   18223            0 :           default:
   18224            0 :             gcc_unreachable ();
   18225              :           }
   18226            8 :         if (p)
   18227           10 :           error_at (loc, "too many %<defaultmap%> clauses with %qs category",
   18228              :                     p);
   18229              :         else
   18230            3 :           error_at (loc, "too many %<defaultmap%> clauses with unspecified "
   18231              :                          "category");
   18232              :         break;
   18233              :       }
   18234              : 
   18235          230 :   c = build_omp_clause (loc, OMP_CLAUSE_DEFAULTMAP);
   18236          230 :   OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
   18237          230 :   OMP_CLAUSE_CHAIN (c) = list;
   18238          230 :   return c;
   18239              : 
   18240            8 :  out_err:
   18241            8 :   parens.skip_until_found_close (parser);
   18242            8 :   return list;
   18243              : }
   18244              : 
   18245              : /* OpenACC 2.0:
   18246              :    use_device ( variable-list )
   18247              : 
   18248              :    OpenMP 4.5:
   18249              :    use_device_ptr ( variable-list ) */
   18250              : 
   18251              : static tree
   18252           31 : c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
   18253              : {
   18254            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_PTR,
   18255            0 :                                        list);
   18256              : }
   18257              : 
   18258              : /* OpenMP 5.0:
   18259              :    use_device_addr ( variable-list ) */
   18260              : 
   18261              : static tree
   18262           35 : c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
   18263              : {
   18264            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
   18265            0 :                                        list);
   18266              : }
   18267              : 
   18268              : /* OpenMP 5.1:
   18269              :    has_device_addr ( variable-list ) */
   18270              : 
   18271              : static tree
   18272           88 : c_parser_omp_clause_has_device_addr (c_parser *parser, tree list)
   18273              : {
   18274            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
   18275            0 :                                        list);
   18276              : }
   18277              : 
   18278              : /* OpenMP 4.5:
   18279              :    is_device_ptr ( variable-list ) */
   18280              : 
   18281              : static tree
   18282          115 : c_parser_omp_clause_is_device_ptr (c_parser *parser, tree list)
   18283              : {
   18284            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_IS_DEVICE_PTR, list);
   18285              : }
   18286              : 
   18287              : /* OpenACC:
   18288              :    num_gangs ( expression )
   18289              :    num_workers ( expression )
   18290              :    vector_length ( expression )  */
   18291              : 
   18292              : static tree
   18293          732 : c_parser_oacc_single_int_clause (c_parser *parser, omp_clause_code code,
   18294              :                                  tree list)
   18295              : {
   18296          732 :   location_t loc = c_parser_peek_token (parser)->location;
   18297              : 
   18298          732 :   matching_parens parens;
   18299          732 :   if (!parens.require_open (parser))
   18300              :     return list;
   18301              : 
   18302          726 :   location_t expr_loc = c_parser_peek_token (parser)->location;
   18303          726 :   c_expr expr = c_parser_expression (parser);
   18304          726 :   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   18305          726 :   tree c, t = expr.value;
   18306          726 :   t = c_fully_fold (t, false, NULL);
   18307              : 
   18308          726 :   parens.skip_until_found_close (parser);
   18309              : 
   18310          726 :   if (t == error_mark_node)
   18311              :     return list;
   18312          702 :   else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   18313              :     {
   18314           16 :       error_at (expr_loc, "%qs expression must be integral",
   18315           16 :                 omp_clause_code_name[code]);
   18316           16 :       return list;
   18317              :     }
   18318              : 
   18319              :   /* Attempt to statically determine when the number isn't positive.  */
   18320          686 :   c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
   18321          686 :                        build_int_cst (TREE_TYPE (t), 0));
   18322          686 :   protected_set_expr_location (c, expr_loc);
   18323          686 :   if (c == boolean_true_node)
   18324              :     {
   18325           36 :       warning_at (expr_loc, 0,
   18326              :                   "%qs value must be positive",
   18327           18 :                   omp_clause_code_name[code]);
   18328           18 :       t = integer_one_node;
   18329              :     }
   18330              : 
   18331          686 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
   18332              : 
   18333          686 :   c = build_omp_clause (loc, code);
   18334          686 :   OMP_CLAUSE_OPERAND (c, 0) = t;
   18335          686 :   OMP_CLAUSE_CHAIN (c) = list;
   18336          686 :   return c;
   18337              : }
   18338              : 
   18339              : /* OpenACC:
   18340              : 
   18341              :     gang [( gang-arg-list )]
   18342              :     worker [( [num:] int-expr )]
   18343              :     vector [( [length:] int-expr )]
   18344              : 
   18345              :   where gang-arg is one of:
   18346              : 
   18347              :     [num:] int-expr
   18348              :     static: size-expr
   18349              : 
   18350              :   and size-expr may be:
   18351              : 
   18352              :     *
   18353              :     int-expr
   18354              : */
   18355              : 
   18356              : static tree
   18357         1560 : c_parser_oacc_shape_clause (c_parser *parser, location_t loc,
   18358              :                             omp_clause_code kind,
   18359              :                             const char *str, tree list)
   18360              : {
   18361         1560 :   const char *id = "num";
   18362         1560 :   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
   18363              : 
   18364         1560 :   if (kind == OMP_CLAUSE_VECTOR)
   18365          518 :     id = "length";
   18366              : 
   18367         1560 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   18368              :     {
   18369          246 :       c_parser_consume_token (parser);
   18370              : 
   18371          276 :       do
   18372              :         {
   18373          261 :           c_token *next = c_parser_peek_token (parser);
   18374          261 :           int idx = 0;
   18375              : 
   18376              :           /* Gang static argument.  */
   18377          261 :           if (kind == OMP_CLAUSE_GANG
   18378          403 :               && c_parser_next_token_is_keyword (parser, RID_STATIC))
   18379              :             {
   18380           70 :               c_parser_consume_token (parser);
   18381              : 
   18382           70 :               if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   18383           12 :                 goto cleanup_error;
   18384              : 
   18385           70 :               idx = 1;
   18386           70 :               if (ops[idx] != NULL_TREE)
   18387              :                 {
   18388            0 :                   c_parser_error (parser, "too many %<static%> arguments");
   18389            0 :                   goto cleanup_error;
   18390              :                 }
   18391              : 
   18392              :               /* Check for the '*' argument.  */
   18393           70 :               if (c_parser_next_token_is (parser, CPP_MULT)
   18394           70 :                   && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
   18395           30 :                       || c_parser_peek_2nd_token (parser)->type
   18396              :                          == CPP_CLOSE_PAREN))
   18397              :                 {
   18398           29 :                   c_parser_consume_token (parser);
   18399           29 :                   ops[idx] = integer_minus_one_node;
   18400              : 
   18401           29 :                   if (c_parser_next_token_is (parser, CPP_COMMA))
   18402              :                     {
   18403            1 :                       c_parser_consume_token (parser);
   18404            1 :                       continue;
   18405              :                     }
   18406              :                   else
   18407              :                     break;
   18408              :                 }
   18409              :             }
   18410              :           /* Worker num: argument and vector length: arguments.  */
   18411          191 :           else if (c_parser_next_token_is (parser, CPP_NAME)
   18412          149 :                    && strcmp (id, IDENTIFIER_POINTER (next->value)) == 0
   18413          324 :                    && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   18414              :             {
   18415          127 :               c_parser_consume_token (parser);  /* id  */
   18416          127 :               c_parser_consume_token (parser);  /* ':'  */
   18417              :             }
   18418              : 
   18419              :           /* Now collect the actual argument.  */
   18420          232 :           if (ops[idx] != NULL_TREE)
   18421              :             {
   18422            5 :               c_parser_error (parser, "unexpected argument");
   18423            5 :               goto cleanup_error;
   18424              :             }
   18425              : 
   18426          227 :           location_t expr_loc = c_parser_peek_token (parser)->location;
   18427          227 :           c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
   18428          227 :           cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
   18429          227 :           tree expr = cexpr.value;
   18430          227 :           if (expr == error_mark_node)
   18431            7 :             goto cleanup_error;
   18432              : 
   18433          220 :           expr = c_fully_fold (expr, false, NULL);
   18434              : 
   18435              :           /* Attempt to statically determine when the number isn't a
   18436              :              positive integer.  */
   18437              : 
   18438          220 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (expr)))
   18439              :             {
   18440           14 :               c_parser_error (parser, "expected integer expression");
   18441           14 :               return list;
   18442              :             }
   18443              : 
   18444          206 :           tree c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, expr,
   18445          206 :                                     build_int_cst (TREE_TYPE (expr), 0));
   18446          206 :           if (c == boolean_true_node)
   18447              :             {
   18448            1 :               warning_at (loc, 0,
   18449              :                           "%qs value must be positive", str);
   18450            1 :               expr = integer_one_node;
   18451              :             }
   18452              : 
   18453          206 :           ops[idx] = expr;
   18454              : 
   18455          220 :           if (kind == OMP_CLAUSE_GANG
   18456          305 :               && c_parser_next_token_is (parser, CPP_COMMA))
   18457              :             {
   18458           14 :               c_parser_consume_token (parser);
   18459           14 :               continue;
   18460              :             }
   18461              :           break;
   18462           15 :         }
   18463              :       while (1);
   18464              : 
   18465          220 :       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   18466            7 :         goto cleanup_error;
   18467              :     }
   18468              : 
   18469         1527 :   check_no_duplicate_clause (list, kind, str);
   18470              : 
   18471         1527 :   c = build_omp_clause (loc, kind);
   18472              : 
   18473         1527 :   if (ops[1])
   18474           67 :     OMP_CLAUSE_OPERAND (c, 1) = ops[1];
   18475              : 
   18476         1527 :   OMP_CLAUSE_OPERAND (c, 0) = ops[0];
   18477         1527 :   OMP_CLAUSE_CHAIN (c) = list;
   18478              : 
   18479         1527 :   return c;
   18480              : 
   18481           19 :  cleanup_error:
   18482           19 :   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
   18483           19 :   return list;
   18484              : }
   18485              : 
   18486              : /* OpenACC 2.5:
   18487              :    auto
   18488              :    finalize
   18489              :    independent
   18490              :    nohost
   18491              :    seq */
   18492              : 
   18493              : static tree
   18494          487 : c_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
   18495              :                              tree list)
   18496              : {
   18497          487 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
   18498              : 
   18499          487 :   tree c = build_omp_clause (loc, code);
   18500          487 :   OMP_CLAUSE_CHAIN (c) = list;
   18501              : 
   18502          487 :   return c;
   18503              : }
   18504              : 
   18505              : /* OpenACC:
   18506              :    async [( int-expr )] */
   18507              : 
   18508              : static tree
   18509          240 : c_parser_oacc_clause_async (c_parser *parser, tree list)
   18510              : {
   18511          240 :   tree c, t;
   18512          240 :   location_t loc = c_parser_peek_token (parser)->location;
   18513              : 
   18514          240 :   t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
   18515              : 
   18516          240 :   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
   18517              :     {
   18518          187 :       c_parser_consume_token (parser);
   18519              : 
   18520          187 :       t = c_parser_expr_no_commas (parser, NULL).value;
   18521          187 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   18522            9 :         c_parser_error (parser, "expected integer expression");
   18523          178 :       else if (t == error_mark_node
   18524          178 :           || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   18525           14 :         return list;
   18526              :     }
   18527              :   else
   18528           53 :     t = c_fully_fold (t, false, NULL);
   18529              : 
   18530          226 :   check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async");
   18531              : 
   18532          226 :   c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
   18533          226 :   OMP_CLAUSE_ASYNC_EXPR (c) = t;
   18534          226 :   OMP_CLAUSE_CHAIN (c) = list;
   18535          226 :   list = c;
   18536              : 
   18537          226 :   return list;
   18538              : }
   18539              : 
   18540              : /* OpenACC 2.0:
   18541              :    tile ( size-expr-list ) */
   18542              : 
   18543              : static tree
   18544          123 : c_parser_oacc_clause_tile (c_parser *parser, tree list)
   18545              : {
   18546          123 :   tree c, expr = error_mark_node;
   18547          123 :   location_t loc;
   18548          123 :   tree tile = NULL_TREE;
   18549              : 
   18550          123 :   check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile");
   18551          123 :   check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse");
   18552              : 
   18553          123 :   loc = c_parser_peek_token (parser)->location;
   18554          123 :   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   18555              :     return list;
   18556              : 
   18557          163 :   do
   18558              :     {
   18559          163 :       if (tile && !c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
   18560              :         return list;
   18561              : 
   18562          163 :       if (c_parser_next_token_is (parser, CPP_MULT)
   18563          163 :           && (c_parser_peek_2nd_token (parser)->type == CPP_COMMA
   18564           53 :               || c_parser_peek_2nd_token (parser)->type == CPP_CLOSE_PAREN))
   18565              :         {
   18566           60 :           c_parser_consume_token (parser);
   18567           60 :           expr = integer_zero_node;
   18568              :         }
   18569              :       else
   18570              :         {
   18571          103 :           location_t expr_loc = c_parser_peek_token (parser)->location;
   18572          103 :           c_expr cexpr = c_parser_expr_no_commas (parser, NULL);
   18573          103 :           cexpr = convert_lvalue_to_rvalue (expr_loc, cexpr, false, true);
   18574          103 :           expr = cexpr.value;
   18575              : 
   18576          103 :           if (expr == error_mark_node)
   18577              :             {
   18578            7 :               c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   18579              :                                          "expected %<)%>");
   18580            7 :               return list;
   18581              :             }
   18582              : 
   18583           96 :           expr = c_fully_fold (expr, false, NULL);
   18584              : 
   18585          192 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
   18586           95 :               || !tree_fits_shwi_p (expr)
   18587          183 :               || tree_to_shwi (expr) <= 0)
   18588              :             {
   18589           16 :               error_at (expr_loc, "%<tile%> argument needs positive"
   18590              :                         " integral constant");
   18591           16 :               expr = integer_zero_node;
   18592              :             }
   18593              :         }
   18594              : 
   18595          156 :       tile = tree_cons (NULL_TREE, expr, tile);
   18596              :     }
   18597          156 :   while (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN));
   18598              : 
   18599              :   /* Consume the trailing ')'.  */
   18600          111 :   c_parser_consume_token (parser);
   18601              : 
   18602          111 :   c = build_omp_clause (loc, OMP_CLAUSE_TILE);
   18603          111 :   tile = nreverse (tile);
   18604          111 :   OMP_CLAUSE_TILE_LIST (c) = tile;
   18605          111 :   OMP_CLAUSE_CHAIN (c) = list;
   18606          111 :   return c;
   18607              : }
   18608              : 
   18609              : /* OpenACC:
   18610              :    wait [( int-expr-list )] */
   18611              : 
   18612              : static tree
   18613           97 : c_parser_oacc_clause_wait (c_parser *parser, tree list)
   18614              : {
   18615           97 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   18616              : 
   18617           97 :   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
   18618           82 :     list = c_parser_oacc_wait_list (parser, clause_loc, list);
   18619              :   else
   18620              :     {
   18621           15 :       tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);
   18622              : 
   18623           15 :       OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
   18624           15 :       OMP_CLAUSE_CHAIN (c) = list;
   18625           15 :       list = c;
   18626              :     }
   18627              : 
   18628           97 :   return list;
   18629              : }
   18630              : 
   18631              : /* OpenACC 2.7:
   18632              :    self [( expression )] */
   18633              : 
   18634              : static tree
   18635           48 : c_parser_oacc_compute_clause_self (c_parser *parser, tree list)
   18636              : {
   18637           48 :   tree t;
   18638           48 :   location_t location = c_parser_peek_token (parser)->location;
   18639           48 :   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
   18640              :     {
   18641           42 :       matching_parens parens;
   18642           42 :       parens.consume_open (parser);
   18643              : 
   18644           42 :       location_t loc = c_parser_peek_token (parser)->location;
   18645           42 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   18646           42 :       expr = convert_lvalue_to_rvalue (loc, expr, true, true);
   18647           42 :       t = c_objc_common_truthvalue_conversion (loc, expr.value);
   18648           42 :       t = c_fully_fold (t, false, NULL);
   18649           42 :       parens.skip_until_found_close (parser);
   18650              :     }
   18651              :   else
   18652            6 :     t = truthvalue_true_node;
   18653              : 
   18654           78 :   for (tree c = list; c; c = OMP_CLAUSE_CHAIN (c))
   18655           36 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SELF)
   18656              :       {
   18657            6 :         error_at (location, "too many %<self%> clauses");
   18658            6 :         return list;
   18659              :       }
   18660              : 
   18661           42 :   tree c = build_omp_clause (location, OMP_CLAUSE_SELF);
   18662           42 :   OMP_CLAUSE_SELF_EXPR (c) = t;
   18663           42 :   OMP_CLAUSE_CHAIN (c) = list;
   18664           42 :   return c;
   18665              : }
   18666              : 
   18667              : /* OpenMP 5.0:
   18668              :    order ( concurrent )
   18669              : 
   18670              :    OpenMP 5.1:
   18671              :    order ( order-modifier : concurrent )
   18672              : 
   18673              :    order-modifier:
   18674              :      reproducible
   18675              :      unconstrained  */
   18676              : 
   18677              : static tree
   18678          376 : c_parser_omp_clause_order (c_parser *parser, tree list)
   18679              : {
   18680          376 :   location_t loc = c_parser_peek_token (parser)->location;
   18681          376 :   tree c;
   18682          376 :   const char *p;
   18683          376 :   bool unconstrained = false;
   18684          376 :   bool reproducible = false;
   18685              : 
   18686          376 :   matching_parens parens;
   18687          376 :   if (!parens.require_open (parser))
   18688              :     return list;
   18689          374 :   if (c_parser_next_token_is (parser, CPP_NAME)
   18690          374 :       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   18691              :     {
   18692          107 :       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18693          107 :       if (strcmp (p, "unconstrained") == 0)
   18694              :         unconstrained = true;
   18695           56 :       else if (strcmp (p, "reproducible") == 0)
   18696              :         reproducible = true;
   18697              :       else
   18698              :         {
   18699            1 :           c_parser_error (parser, "expected %<reproducible%> or "
   18700              :                                   "%<unconstrained%>");
   18701            1 :           goto out_err;
   18702              :         }
   18703          106 :       c_parser_consume_token (parser);
   18704          106 :       c_parser_consume_token (parser);
   18705              :     }
   18706          373 :   if (!c_parser_next_token_is (parser, CPP_NAME))
   18707              :     {
   18708            0 :       c_parser_error (parser, "expected %<concurrent%>");
   18709            0 :       goto out_err;
   18710              :     }
   18711          373 :   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18712          373 :   if (strcmp (p, "concurrent") != 0)
   18713              :     {
   18714            1 :       c_parser_error (parser, "expected %<concurrent%>");
   18715            1 :       goto out_err;
   18716              :     }
   18717          372 :   c_parser_consume_token (parser);
   18718          372 :   parens.skip_until_found_close (parser);
   18719          372 :   check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order");
   18720          372 :   c = build_omp_clause (loc, OMP_CLAUSE_ORDER);
   18721          372 :   OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
   18722          372 :   OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
   18723          372 :   OMP_CLAUSE_CHAIN (c) = list;
   18724          372 :   return c;
   18725              : 
   18726            2 :  out_err:
   18727            2 :   parens.skip_until_found_close (parser);
   18728            2 :   return list;
   18729              : }
   18730              : 
   18731              : 
   18732              : /* OpenMP 5.0:
   18733              :    bind ( teams | parallel | thread ) */
   18734              : 
   18735              : static tree
   18736          116 : c_parser_omp_clause_bind (c_parser *parser, tree list)
   18737              : {
   18738          116 :   location_t loc = c_parser_peek_token (parser)->location;
   18739          116 :   tree c;
   18740          116 :   const char *p;
   18741          116 :   enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;
   18742              : 
   18743          116 :   matching_parens parens;
   18744          116 :   if (!parens.require_open (parser))
   18745              :     return list;
   18746          114 :   if (!c_parser_next_token_is (parser, CPP_NAME))
   18747              :     {
   18748            3 :      invalid:
   18749            4 :       c_parser_error (parser,
   18750              :                       "expected %<teams%>, %<parallel%> or %<thread%>");
   18751            4 :       parens.skip_until_found_close (parser);
   18752            4 :       return list;
   18753              :     }
   18754          111 :   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18755          111 :   if (strcmp (p, "teams") == 0)
   18756              :     kind = OMP_CLAUSE_BIND_TEAMS;
   18757           72 :   else if (strcmp (p, "parallel") == 0)
   18758              :     kind = OMP_CLAUSE_BIND_PARALLEL;
   18759           35 :   else if (strcmp (p, "thread") != 0)
   18760            1 :     goto invalid;
   18761          110 :   c_parser_consume_token (parser);
   18762          110 :   parens.skip_until_found_close (parser);
   18763              :   /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind"); */
   18764          110 :   c = build_omp_clause (loc, OMP_CLAUSE_BIND);
   18765          110 :   OMP_CLAUSE_BIND_KIND (c) = kind;
   18766          110 :   OMP_CLAUSE_CHAIN (c) = list;
   18767          110 :   return c;
   18768              : }
   18769              : 
   18770              : 
   18771              : /* OpenMP 2.5:
   18772              :    ordered
   18773              : 
   18774              :    OpenMP 4.5:
   18775              :    ordered ( constant-expression ) */
   18776              : 
   18777              : static tree
   18778          310 : c_parser_omp_clause_ordered (c_parser *parser, tree list)
   18779              : {
   18780          310 :   check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED, "ordered");
   18781              : 
   18782          310 :   tree c, num = NULL_TREE;
   18783          310 :   HOST_WIDE_INT n;
   18784          310 :   location_t loc = c_parser_peek_token (parser)->location;
   18785          310 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   18786              :     {
   18787          169 :       matching_parens parens;
   18788          169 :       parens.consume_open (parser);
   18789          169 :       num = c_parser_expr_no_commas (parser, NULL).value;
   18790          169 :       parens.skip_until_found_close (parser);
   18791              :     }
   18792          310 :   if (num == error_mark_node)
   18793              :     return list;
   18794          310 :   if (num)
   18795              :     {
   18796          169 :       mark_exp_read (num);
   18797          169 :       num = c_fully_fold (num, false, NULL);
   18798          338 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
   18799          169 :           || !tree_fits_shwi_p (num)
   18800          169 :           || (n = tree_to_shwi (num)) <= 0
   18801          338 :           || (int) n != n)
   18802              :         {
   18803            0 :           error_at (loc, "ordered argument needs positive "
   18804              :                          "constant integer expression");
   18805            0 :           return list;
   18806              :         }
   18807              :     }
   18808          310 :   c = build_omp_clause (loc, OMP_CLAUSE_ORDERED);
   18809          310 :   OMP_CLAUSE_ORDERED_EXPR (c) = num;
   18810          310 :   OMP_CLAUSE_CHAIN (c) = list;
   18811          310 :   return c;
   18812              : }
   18813              : 
   18814              : /* OpenMP 2.5:
   18815              :    private ( variable-list ) */
   18816              : 
   18817              : static tree
   18818          745 : c_parser_omp_clause_private (c_parser *parser, tree list)
   18819              : {
   18820            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_PRIVATE, list);
   18821              : }
   18822              : 
   18823              : /* OpenMP 2.5:
   18824              :    reduction ( reduction-operator : variable-list )
   18825              : 
   18826              :    reduction-operator:
   18827              :      One of: + * - & ^ | && ||
   18828              : 
   18829              :    OpenMP 3.1:
   18830              : 
   18831              :    reduction-operator:
   18832              :      One of: + * - & ^ | && || max min
   18833              : 
   18834              :    OpenMP 4.0:
   18835              : 
   18836              :    reduction-operator:
   18837              :      One of: + * - & ^ | && ||
   18838              :      identifier
   18839              : 
   18840              :    OpenMP 5.0:
   18841              :    reduction ( reduction-modifier, reduction-operator : variable-list )
   18842              :    in_reduction ( reduction-operator : variable-list )
   18843              :    task_reduction ( reduction-operator : variable-list )  */
   18844              : 
   18845              : static tree
   18846         3093 : c_parser_omp_clause_reduction (c_parser *parser, enum omp_clause_code kind,
   18847              :                                bool is_omp, tree list)
   18848              : {
   18849         3093 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   18850         3093 :   matching_parens parens;
   18851         3093 :   if (parens.require_open (parser))
   18852              :     {
   18853         3093 :       bool task = false;
   18854         3093 :       bool inscan = false;
   18855         3093 :       enum tree_code code = ERROR_MARK;
   18856         3093 :       tree reduc_id = NULL_TREE;
   18857              : 
   18858         3093 :       if (kind == OMP_CLAUSE_REDUCTION && is_omp)
   18859              :         {
   18860         1781 :           if (c_parser_next_token_is_keyword (parser, RID_DEFAULT)
   18861         1781 :               && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
   18862              :             {
   18863           87 :               c_parser_consume_token (parser);
   18864           87 :               c_parser_consume_token (parser);
   18865              :             }
   18866         1694 :           else if (c_parser_next_token_is (parser, CPP_NAME)
   18867         1694 :                    && c_parser_peek_2nd_token (parser)->type == CPP_COMMA)
   18868              :             {
   18869          465 :               const char *p
   18870          465 :                 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18871          465 :               if (strcmp (p, "task") == 0)
   18872              :                 task = true;
   18873          285 :               else if (strcmp (p, "inscan") == 0)
   18874              :                 inscan = true;
   18875              :               if (task || inscan)
   18876              :                 {
   18877          465 :                   c_parser_consume_token (parser);
   18878          465 :                   c_parser_consume_token (parser);
   18879              :                 }
   18880              :             }
   18881              :         }
   18882              : 
   18883         3093 :       switch (c_parser_peek_token (parser)->type)
   18884              :         {
   18885              :         case CPP_PLUS:
   18886              :           code = PLUS_EXPR;
   18887              :           break;
   18888          253 :         case CPP_MULT:
   18889          253 :           code = MULT_EXPR;
   18890          253 :           break;
   18891          157 :         case CPP_MINUS:
   18892          157 :           if (is_omp)
   18893              :             {
   18894            4 :               location_t loc = c_parser_peek_token (parser)->location;
   18895            4 :               gcc_rich_location richloc (loc);
   18896            4 :               richloc.add_fixit_replace ("+");
   18897            4 :               warning_at (&richloc, OPT_Wdeprecated_openmp,
   18898              :                           "%<-%> operator for reductions deprecated in "
   18899              :                           "OpenMP 5.2");
   18900            4 :             }
   18901              :           code = MINUS_EXPR;
   18902              :           break;
   18903           27 :         case CPP_AND:
   18904           27 :           code = BIT_AND_EXPR;
   18905           27 :           break;
   18906           14 :         case CPP_XOR:
   18907           14 :           code = BIT_XOR_EXPR;
   18908           14 :           break;
   18909           82 :         case CPP_OR:
   18910           82 :           code = BIT_IOR_EXPR;
   18911           82 :           break;
   18912           67 :         case CPP_AND_AND:
   18913           67 :           code = TRUTH_ANDIF_EXPR;
   18914           67 :           break;
   18915           78 :         case CPP_OR_OR:
   18916           78 :           code = TRUTH_ORIF_EXPR;
   18917           78 :           break;
   18918          253 :         case CPP_NAME:
   18919          253 :           {
   18920          253 :             const char *p
   18921          253 :               = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   18922          253 :             if (strcmp (p, "min") == 0)
   18923              :               {
   18924              :                 code = MIN_EXPR;
   18925              :                 break;
   18926              :               }
   18927          213 :             if (strcmp (p, "max") == 0)
   18928              :               {
   18929              :                 code = MAX_EXPR;
   18930              :                 break;
   18931              :               }
   18932          130 :             reduc_id = c_parser_peek_token (parser)->value;
   18933          130 :             break;
   18934              :           }
   18935            0 :         default:
   18936            0 :           c_parser_error (parser,
   18937              :                           "expected %<+%>, %<*%>, %<-%>, %<&%>, "
   18938              :                           "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
   18939            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
   18940            0 :           return list;
   18941              :         }
   18942         3093 :       c_parser_consume_token (parser);
   18943         3093 :       reduc_id = c_omp_reduction_id (code, reduc_id);
   18944         3093 :       if (c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   18945              :         {
   18946         3093 :           tree nl, c;
   18947              : 
   18948         3093 :           nl = c_parser_omp_variable_list (parser, clause_loc, kind, list);
   18949         6799 :           for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   18950              :             {
   18951         3706 :               tree d = OMP_CLAUSE_DECL (c), type;
   18952         3706 :               if (TREE_CODE (d) != OMP_ARRAY_SECTION)
   18953         3187 :                 type = TREE_TYPE (d);
   18954              :               else
   18955              :                 {
   18956              :                   int cnt = 0;
   18957              :                   tree t;
   18958          636 :                   for (t = d;
   18959         1155 :                       TREE_CODE (t) == OMP_ARRAY_SECTION;
   18960          636 :                       t = TREE_OPERAND (t, 0))
   18961          636 :                     cnt++;
   18962          519 :                   type = TREE_TYPE (t);
   18963         1153 :                   while (cnt > 0)
   18964              :                     {
   18965          636 :                       if (TREE_CODE (type) != POINTER_TYPE
   18966          399 :                           && TREE_CODE (type) != ARRAY_TYPE)
   18967              :                         break;
   18968          634 :                       type = TREE_TYPE (type);
   18969          634 :                       cnt--;
   18970              :                     }
   18971              :                 }
   18972         3799 :               while (TREE_CODE (type) == ARRAY_TYPE)
   18973           93 :                 type = TREE_TYPE (type);
   18974         3706 :               OMP_CLAUSE_REDUCTION_CODE (c) = code;
   18975         3706 :               if (task)
   18976          212 :                 OMP_CLAUSE_REDUCTION_TASK (c) = 1;
   18977         3494 :               else if (inscan)
   18978          400 :                 OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
   18979         3706 :               if (code == ERROR_MARK
   18980          219 :                   || !(INTEGRAL_TYPE_P (type)
   18981         3566 :                        || SCALAR_FLOAT_TYPE_P (type)
   18982              :                        || TREE_CODE (type) == COMPLEX_TYPE))
   18983          273 :                 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c)
   18984          546 :                   = c_omp_reduction_lookup (reduc_id,
   18985          273 :                                             TYPE_MAIN_VARIANT (type));
   18986              :             }
   18987              : 
   18988              :           list = nl;
   18989              :         }
   18990         3093 :       parens.skip_until_found_close (parser);
   18991              :     }
   18992              :   return list;
   18993              : }
   18994              : 
   18995              : /* OpenMP 2.5:
   18996              :    schedule ( schedule-kind )
   18997              :    schedule ( schedule-kind , expression )
   18998              : 
   18999              :    schedule-kind:
   19000              :      static | dynamic | guided | runtime | auto
   19001              : 
   19002              :    OpenMP 4.5:
   19003              :    schedule ( schedule-modifier : schedule-kind )
   19004              :    schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )
   19005              : 
   19006              :    schedule-modifier:
   19007              :      simd
   19008              :      monotonic
   19009              :      nonmonotonic  */
   19010              : 
   19011              : static tree
   19012         3469 : c_parser_omp_clause_schedule (c_parser *parser, tree list)
   19013              : {
   19014         3469 :   tree c, t;
   19015         3469 :   location_t loc = c_parser_peek_token (parser)->location;
   19016         3469 :   int modifiers = 0, nmodifiers = 0;
   19017              : 
   19018         3469 :   matching_parens parens;
   19019         3469 :   if (!parens.require_open (parser))
   19020              :     return list;
   19021              : 
   19022         3467 :   c = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
   19023              : 
   19024         3467 :   location_t comma = UNKNOWN_LOCATION;
   19025         6948 :   while (c_parser_next_token_is (parser, CPP_NAME))
   19026              :     {
   19027         1780 :       tree kind = c_parser_peek_token (parser)->value;
   19028         1780 :       const char *p = IDENTIFIER_POINTER (kind);
   19029         1780 :       if (strcmp ("simd", p) == 0)
   19030           31 :         OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
   19031         1749 :       else if (strcmp ("monotonic", p) == 0)
   19032           74 :         modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
   19033         1675 :       else if (strcmp ("nonmonotonic", p) == 0)
   19034           84 :         modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
   19035              :       else
   19036              :         break;
   19037          189 :       comma = UNKNOWN_LOCATION;
   19038          189 :       c_parser_consume_token (parser);
   19039          189 :       if (nmodifiers++ == 0
   19040          367 :           && c_parser_next_token_is (parser, CPP_COMMA))
   19041              :         {
   19042           14 :           comma = c_parser_peek_token (parser)->location;
   19043           14 :           c_parser_consume_token (parser);
   19044              :         }
   19045              :       else
   19046              :         {
   19047          175 :           c_parser_require (parser, CPP_COLON, "expected %<:%>");
   19048          175 :           break;
   19049              :         }
   19050              :     }
   19051         3467 :   if (comma != UNKNOWN_LOCATION)
   19052            3 :     error_at (comma, "expected %<:%>");
   19053              : 
   19054         3467 :   if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
   19055              :                     | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
   19056              :       == (OMP_CLAUSE_SCHEDULE_MONOTONIC
   19057              :           | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
   19058              :     {
   19059            2 :       error_at (loc, "both %<monotonic%> and %<nonmonotonic%> modifiers "
   19060              :                      "specified");
   19061            2 :       modifiers = 0;
   19062              :     }
   19063              : 
   19064         3467 :   if (c_parser_next_token_is (parser, CPP_NAME))
   19065              :     {
   19066         1708 :       tree kind = c_parser_peek_token (parser)->value;
   19067         1708 :       const char *p = IDENTIFIER_POINTER (kind);
   19068              : 
   19069         1708 :       switch (p[0])
   19070              :         {
   19071          169 :         case 'd':
   19072          169 :           if (strcmp ("dynamic", p) != 0)
   19073            0 :             goto invalid_kind;
   19074          169 :           OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
   19075          169 :           break;
   19076              : 
   19077          761 :         case 'g':
   19078          761 :           if (strcmp ("guided", p) != 0)
   19079            0 :             goto invalid_kind;
   19080          761 :           OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
   19081          761 :           break;
   19082              : 
   19083          777 :         case 'r':
   19084          777 :           if (strcmp ("runtime", p) != 0)
   19085            0 :             goto invalid_kind;
   19086          777 :           OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
   19087          777 :           break;
   19088              : 
   19089            1 :         default:
   19090            1 :           goto invalid_kind;
   19091              :         }
   19092              :     }
   19093         1759 :   else if (c_parser_next_token_is_keyword (parser, RID_STATIC))
   19094         1078 :     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
   19095          681 :   else if (c_parser_next_token_is_keyword (parser, RID_AUTO))
   19096          680 :     OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
   19097              :   else
   19098            1 :     goto invalid_kind;
   19099              : 
   19100         3465 :   c_parser_consume_token (parser);
   19101         3465 :   if (c_parser_next_token_is (parser, CPP_COMMA))
   19102              :     {
   19103         1797 :       location_t here;
   19104         1797 :       c_parser_consume_token (parser);
   19105              : 
   19106         1797 :       here = c_parser_peek_token (parser)->location;
   19107         1797 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19108         1797 :       expr = convert_lvalue_to_rvalue (here, expr, false, true);
   19109         1797 :       t = expr.value;
   19110         1797 :       t = c_fully_fold (t, false, NULL);
   19111              : 
   19112         1797 :       if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
   19113            1 :         error_at (here, "schedule %<runtime%> does not take "
   19114              :                   "a %<chunk_size%> parameter");
   19115         1796 :       else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
   19116            0 :         error_at (here,
   19117              :                   "schedule %<auto%> does not take "
   19118              :                   "a %<chunk_size%> parameter");
   19119         1796 :       else if (TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE
   19120         1796 :                || TREE_CODE (TREE_TYPE (t)) == BITINT_TYPE)
   19121              :         {
   19122              :           /* Attempt to statically determine when the number isn't
   19123              :              positive.  */
   19124         1795 :           tree s = fold_build2_loc (loc, LE_EXPR, boolean_type_node, t,
   19125         1795 :                                     build_int_cst (TREE_TYPE (t), 0));
   19126         1795 :           protected_set_expr_location (s, loc);
   19127         1795 :           if (s == boolean_true_node)
   19128              :             {
   19129            2 :               warning_at (loc, OPT_Wopenmp,
   19130              :                           "chunk size value must be positive");
   19131            2 :               t = integer_one_node;
   19132              :             }
   19133         1795 :           OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;
   19134              :         }
   19135              :       else
   19136            1 :         c_parser_error (parser, "expected integer expression");
   19137              : 
   19138         1797 :       parens.skip_until_found_close (parser);
   19139              :     }
   19140              :   else
   19141         1668 :     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   19142              :                                "expected %<,%> or %<)%>");
   19143              : 
   19144         6930 :   OMP_CLAUSE_SCHEDULE_KIND (c)
   19145         6930 :     = (enum omp_clause_schedule_kind)
   19146         3465 :       (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);
   19147              : 
   19148         3465 :   check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
   19149         3465 :   OMP_CLAUSE_CHAIN (c) = list;
   19150         3465 :   return c;
   19151              : 
   19152            2 :  invalid_kind:
   19153            2 :   c_parser_error (parser, "invalid schedule kind");
   19154            2 :   c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, 0);
   19155            2 :   return list;
   19156              : }
   19157              : 
   19158              : /* OpenMP 2.5:
   19159              :    shared ( variable-list ) */
   19160              : 
   19161              : static tree
   19162          691 : c_parser_omp_clause_shared (c_parser *parser, tree list)
   19163              : {
   19164            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_SHARED, list);
   19165              : }
   19166              : 
   19167              : /* OpenMP 3.0:
   19168              :    untied */
   19169              : 
   19170              : static tree
   19171           97 : c_parser_omp_clause_untied (c_parser *parser ATTRIBUTE_UNUSED, tree list)
   19172              : {
   19173           97 :   tree c;
   19174              : 
   19175              :   /* FIXME: Should we allow duplicates?  */
   19176           97 :   check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied");
   19177              : 
   19178           97 :   c = build_omp_clause (c_parser_peek_token (parser)->location,
   19179              :                         OMP_CLAUSE_UNTIED);
   19180           97 :   OMP_CLAUSE_CHAIN (c) = list;
   19181              : 
   19182           97 :   return c;
   19183              : }
   19184              : 
   19185              : /* OpenMP 4.0:
   19186              :    inbranch
   19187              :    notinbranch */
   19188              : 
   19189              : static tree
   19190          205 : c_parser_omp_clause_branch (c_parser *parser ATTRIBUTE_UNUSED,
   19191              :                             enum omp_clause_code code, tree list)
   19192              : {
   19193          205 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
   19194              : 
   19195          205 :   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
   19196          205 :   OMP_CLAUSE_CHAIN (c) = list;
   19197              : 
   19198          205 :   return c;
   19199              : }
   19200              : 
   19201              : /* OpenMP 4.0:
   19202              :    parallel
   19203              :    for
   19204              :    sections
   19205              :    taskgroup */
   19206              : 
   19207              : static tree
   19208          379 : c_parser_omp_clause_cancelkind (c_parser *parser ATTRIBUTE_UNUSED,
   19209              :                                 enum omp_clause_code code, tree list)
   19210              : {
   19211          379 :   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
   19212          379 :   OMP_CLAUSE_CHAIN (c) = list;
   19213              : 
   19214          379 :   return c;
   19215              : }
   19216              : 
   19217              : /* OpenMP 4.5:
   19218              :    nogroup */
   19219              : 
   19220              : static tree
   19221           18 : c_parser_omp_clause_nogroup (c_parser *parser ATTRIBUTE_UNUSED, tree list)
   19222              : {
   19223           18 :   check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup");
   19224           18 :   tree c = build_omp_clause (c_parser_peek_token (parser)->location,
   19225              :                              OMP_CLAUSE_NOGROUP);
   19226           18 :   OMP_CLAUSE_CHAIN (c) = list;
   19227           18 :   return c;
   19228              : }
   19229              : 
   19230              : /* OpenMP 4.5:
   19231              :    simd
   19232              :    threads */
   19233              : 
   19234              : static tree
   19235          103 : c_parser_omp_clause_orderedkind (c_parser *parser ATTRIBUTE_UNUSED,
   19236              :                                  enum omp_clause_code code, tree list)
   19237              : {
   19238          103 :   check_no_duplicate_clause (list, code, omp_clause_code_name[code]);
   19239          103 :   tree c = build_omp_clause (c_parser_peek_token (parser)->location, code);
   19240          103 :   OMP_CLAUSE_CHAIN (c) = list;
   19241          103 :   return c;
   19242              : }
   19243              : 
   19244              : /* OpenMP 4.0:
   19245              :    num_teams ( expression )
   19246              : 
   19247              :    OpenMP 5.1:
   19248              :    num_teams ( expression : expression ) */
   19249              : 
   19250              : static tree
   19251          190 : c_parser_omp_clause_num_teams (c_parser *parser, tree list)
   19252              : {
   19253          190 :   location_t num_teams_loc = c_parser_peek_token (parser)->location;
   19254          190 :   matching_parens parens;
   19255          190 :   if (parens.require_open (parser))
   19256              :     {
   19257          190 :       location_t upper_loc = c_parser_peek_token (parser)->location;
   19258          190 :       location_t lower_loc = UNKNOWN_LOCATION;
   19259          190 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19260          190 :       expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
   19261          190 :       tree c, upper = expr.value, lower = NULL_TREE;
   19262          190 :       upper = c_fully_fold (upper, false, NULL);
   19263              : 
   19264          190 :       if (c_parser_next_token_is (parser, CPP_COLON))
   19265              :         {
   19266           51 :           c_parser_consume_token (parser);
   19267           51 :           lower_loc = upper_loc;
   19268           51 :           lower = upper;
   19269           51 :           upper_loc = c_parser_peek_token (parser)->location;
   19270           51 :           expr = c_parser_expr_no_commas (parser, NULL);
   19271           51 :           expr = convert_lvalue_to_rvalue (upper_loc, expr, false, true);
   19272           51 :           upper = expr.value;
   19273           51 :           upper = c_fully_fold (upper, false, NULL);
   19274              :         }
   19275              : 
   19276          190 :       parens.skip_until_found_close (parser);
   19277              : 
   19278          380 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (upper))
   19279          380 :           || (lower && !INTEGRAL_TYPE_P (TREE_TYPE (lower))))
   19280              :         {
   19281            0 :           c_parser_error (parser, "expected integer expression");
   19282            0 :           return list;
   19283              :         }
   19284              : 
   19285              :       /* Attempt to statically determine when the number isn't positive.  */
   19286          190 :       c = fold_build2_loc (upper_loc, LE_EXPR, boolean_type_node, upper,
   19287          190 :                            build_int_cst (TREE_TYPE (upper), 0));
   19288          190 :       protected_set_expr_location (c, upper_loc);
   19289          190 :       if (c == boolean_true_node)
   19290              :         {
   19291            4 :           warning_at (upper_loc, OPT_Wopenmp,
   19292              :                       "%<num_teams%> value must be positive");
   19293            4 :           upper = integer_one_node;
   19294              :         }
   19295          190 :       if (lower)
   19296              :         {
   19297           51 :           c = fold_build2_loc (lower_loc, LE_EXPR, boolean_type_node, lower,
   19298           51 :                                build_int_cst (TREE_TYPE (lower), 0));
   19299           51 :           protected_set_expr_location (c, lower_loc);
   19300           51 :           if (c == boolean_true_node)
   19301              :             {
   19302            2 :               warning_at (lower_loc, OPT_Wopenmp,
   19303              :                           "%<num_teams%> value must be positive");
   19304            2 :               lower = NULL_TREE;
   19305              :             }
   19306           49 :           else if (TREE_CODE (lower) == INTEGER_CST
   19307            7 :                    && TREE_CODE (upper) == INTEGER_CST
   19308           54 :                    && tree_int_cst_lt (upper, lower))
   19309              :             {
   19310            2 :               warning_at (lower_loc, OPT_Wopenmp,
   19311              :                           "%<num_teams%> lower bound %qE bigger than upper "
   19312              :                           "bound %qE", lower, upper);
   19313            2 :               lower = NULL_TREE;
   19314              :             }
   19315              :         }
   19316              : 
   19317          190 :       check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS, "num_teams");
   19318              : 
   19319          190 :       c = build_omp_clause (num_teams_loc, OMP_CLAUSE_NUM_TEAMS);
   19320          190 :       OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
   19321          190 :       OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
   19322          190 :       OMP_CLAUSE_CHAIN (c) = list;
   19323          190 :       list = c;
   19324              :     }
   19325              : 
   19326              :   return list;
   19327              : }
   19328              : 
   19329              : /* OpenMP 4.0:
   19330              :    thread_limit ( expression ) */
   19331              : 
   19332              : static tree
   19333          154 : c_parser_omp_clause_thread_limit (c_parser *parser, tree list)
   19334              : {
   19335          154 :   location_t num_thread_limit_loc = c_parser_peek_token (parser)->location;
   19336          154 :   matching_parens parens;
   19337          154 :   if (parens.require_open (parser))
   19338              :     {
   19339          154 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   19340          154 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19341          154 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   19342          154 :       tree c, t = expr.value;
   19343          154 :       t = c_fully_fold (t, false, NULL);
   19344              : 
   19345          154 :       parens.skip_until_found_close (parser);
   19346              : 
   19347          154 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   19348              :         {
   19349            0 :           c_parser_error (parser, "expected integer expression");
   19350            0 :           return list;
   19351              :         }
   19352              : 
   19353              :       /* Attempt to statically determine when the number isn't positive.  */
   19354          154 :       c = fold_build2_loc (expr_loc, LE_EXPR, boolean_type_node, t,
   19355          154 :                            build_int_cst (TREE_TYPE (t), 0));
   19356          154 :       protected_set_expr_location (c, expr_loc);
   19357          154 :       if (c == boolean_true_node)
   19358              :         {
   19359            0 :           warning_at (expr_loc, OPT_Wopenmp,
   19360              :                       "%<thread_limit%> value must be positive");
   19361            0 :           t = integer_one_node;
   19362              :         }
   19363              : 
   19364          154 :       check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
   19365              :                                  "thread_limit");
   19366              : 
   19367          154 :       c = build_omp_clause (num_thread_limit_loc, OMP_CLAUSE_THREAD_LIMIT);
   19368          154 :       OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
   19369          154 :       OMP_CLAUSE_CHAIN (c) = list;
   19370          154 :       list = c;
   19371              :     }
   19372              : 
   19373              :   return list;
   19374              : }
   19375              : 
   19376              : /* OpenMP 4.0:
   19377              :    aligned ( variable-list )
   19378              :    aligned ( variable-list : constant-expression ) */
   19379              : 
   19380              : static tree
   19381          228 : c_parser_omp_clause_aligned (c_parser *parser, tree list)
   19382              : {
   19383          228 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   19384          228 :   tree nl, c;
   19385              : 
   19386          228 :   matching_parens parens;
   19387          228 :   if (!parens.require_open (parser))
   19388              :     return list;
   19389              : 
   19390          228 :   nl = c_parser_omp_variable_list (parser, clause_loc,
   19391              :                                    OMP_CLAUSE_ALIGNED, list);
   19392              : 
   19393          228 :   if (c_parser_next_token_is (parser, CPP_COLON))
   19394              :     {
   19395          212 :       c_parser_consume_token (parser);
   19396          212 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   19397          212 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19398          212 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   19399          212 :       tree alignment = expr.value;
   19400          212 :       alignment = c_fully_fold (alignment, false, NULL);
   19401          212 :       if (TREE_CODE (alignment) != INTEGER_CST
   19402          210 :           || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
   19403          422 :           || tree_int_cst_sgn (alignment) != 1)
   19404              :         {
   19405            4 :           error_at (clause_loc, "%<aligned%> clause alignment expression must "
   19406              :                                 "be positive constant integer expression");
   19407            4 :           alignment = NULL_TREE;
   19408              :         }
   19409              : 
   19410          444 :       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   19411          232 :         OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;
   19412              :     }
   19413              : 
   19414          228 :   parens.skip_until_found_close (parser);
   19415          228 :   return nl;
   19416              : }
   19417              : 
   19418              : /* OpenMP 5.0:
   19419              :    allocate ( variable-list )
   19420              :    allocate ( expression : variable-list )
   19421              : 
   19422              :    OpenMP 5.1:
   19423              :    allocate ( allocator-modifier : variable-list )
   19424              :    allocate ( allocator-modifier , allocator-modifier : variable-list )
   19425              : 
   19426              :    allocator-modifier:
   19427              :    allocator ( expression )
   19428              :    align ( expression )  */
   19429              : 
   19430              : static tree
   19431          479 : c_parser_omp_clause_allocate (c_parser *parser, tree list)
   19432              : {
   19433          479 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   19434          479 :   tree nl, c;
   19435          479 :   tree allocator = NULL_TREE;
   19436          479 :   tree align = NULL_TREE;
   19437              : 
   19438          479 :   matching_parens parens;
   19439          479 :   if (!parens.require_open (parser))
   19440              :     return list;
   19441              : 
   19442          479 :   if ((c_parser_next_token_is_not (parser, CPP_NAME)
   19443            5 :        && c_parser_next_token_is_not (parser, CPP_KEYWORD))
   19444          479 :       || (c_parser_peek_2nd_token (parser)->type != CPP_COMMA
   19445          460 :           && c_parser_peek_2nd_token (parser)->type != CPP_CLOSE_PAREN))
   19446              :     {
   19447          214 :       bool has_modifiers = false;
   19448          214 :       tree orig_type = NULL_TREE;
   19449          214 :       if (c_parser_next_token_is (parser, CPP_NAME)
   19450          214 :           && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
   19451              :         {
   19452           73 :           unsigned int n = 3;
   19453           73 :           const char *p
   19454           73 :             = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   19455           29 :           if ((strcmp (p, "allocator") == 0 || strcmp (p, "align") == 0)
   19456           71 :               && c_parser_check_balanced_raw_token_sequence (parser, &n)
   19457          144 :               && (c_parser_peek_nth_token_raw (parser, n)->type
   19458              :                   == CPP_CLOSE_PAREN))
   19459              :             {
   19460           71 :               if (c_parser_peek_nth_token_raw (parser, n + 1)->type
   19461              :                   == CPP_COLON)
   19462              :                 has_modifiers = true;
   19463           37 :               else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
   19464              :                        == CPP_COMMA
   19465           37 :                        && (c_parser_peek_nth_token_raw (parser, n + 2)->type
   19466              :                            == CPP_NAME)
   19467           74 :                        && (c_parser_peek_nth_token_raw (parser, n + 3)->type
   19468              :                            == CPP_OPEN_PAREN))
   19469              :                 {
   19470           37 :                   c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
   19471           37 :                   const char *q = IDENTIFIER_POINTER (tok->value);
   19472           37 :                   n += 4;
   19473           37 :                   if ((strcmp (q, "allocator") == 0
   19474           24 :                        || strcmp (q, "align") == 0)
   19475           37 :                       && c_parser_check_balanced_raw_token_sequence (parser,
   19476              :                                                                      &n)
   19477           37 :                       && (c_parser_peek_nth_token_raw (parser, n)->type
   19478              :                           == CPP_CLOSE_PAREN)
   19479           74 :                       && (c_parser_peek_nth_token_raw (parser, n + 1)->type
   19480              :                           == CPP_COLON))
   19481              :                     has_modifiers = true;
   19482              :                 }
   19483              :             }
   19484              :           if (has_modifiers)
   19485              :             {
   19486           71 :               c_parser_consume_token (parser);
   19487           71 :               matching_parens parens2;
   19488           71 :               parens2.require_open (parser);
   19489           71 :               location_t expr_loc = c_parser_peek_token (parser)->location;
   19490           71 :               c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19491           71 :               expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   19492           71 :               if (expr.value == error_mark_node)
   19493              :                 ;
   19494           70 :               else if (strcmp (p, "allocator") == 0)
   19495              :                 {
   19496           43 :                   allocator = expr.value;
   19497           43 :                   allocator = c_fully_fold (allocator, false, NULL);
   19498            3 :                   orig_type = expr.original_type
   19499           43 :                               ? expr.original_type : TREE_TYPE (allocator);
   19500           43 :                   orig_type = TYPE_MAIN_VARIANT (orig_type);
   19501              :                 }
   19502              :               else
   19503              :                 {
   19504           27 :                   align = expr.value;
   19505           27 :                   align = c_fully_fold (align, false, NULL);
   19506              :                 }
   19507           71 :               parens2.skip_until_found_close (parser);
   19508           71 :               if (c_parser_next_token_is (parser, CPP_COMMA))
   19509              :                 {
   19510           37 :                   c_parser_consume_token (parser);
   19511           37 :                   c_token *tok = c_parser_peek_token (parser);
   19512           37 :                   const char *q = "";
   19513           37 :                   if (c_parser_next_token_is (parser, CPP_NAME))
   19514           37 :                     q = IDENTIFIER_POINTER (tok->value);
   19515           37 :                   if (strcmp (q, "allocator") != 0 && strcmp (q, "align") != 0)
   19516              :                     {
   19517            0 :                       c_parser_error (parser, "expected %<allocator%> or "
   19518              :                                               "%<align%>");
   19519            0 :                       parens.skip_until_found_close (parser);
   19520            2 :                       return list;
   19521              :                     }
   19522           37 :                   else if (strcmp (p, q) == 0)
   19523              :                     {
   19524            2 :                       error_at (tok->location, "duplicate %qs modifier", p);
   19525            2 :                       parens.skip_until_found_close (parser);
   19526            2 :                       return list;
   19527              :                     }
   19528           35 :                   c_parser_consume_token (parser);
   19529           35 :                   if (!parens2.require_open (parser))
   19530              :                     {
   19531            0 :                       parens.skip_until_found_close (parser);
   19532            0 :                       return list;
   19533              :                     }
   19534           35 :                   expr_loc = c_parser_peek_token (parser)->location;
   19535           35 :                   expr = c_parser_expr_no_commas (parser, NULL);
   19536           35 :                   expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
   19537              :                                                    true);
   19538           35 :                   if (strcmp (q, "allocator") == 0)
   19539              :                     {
   19540           12 :                       allocator = expr.value;
   19541           12 :                       allocator = c_fully_fold (allocator, false, NULL);
   19542            2 :                       orig_type = expr.original_type
   19543           12 :                                   ? expr.original_type : TREE_TYPE (allocator);
   19544           12 :                       orig_type = TYPE_MAIN_VARIANT (orig_type);
   19545              :                     }
   19546              :                   else
   19547              :                     {
   19548           23 :                       align = expr.value;
   19549           23 :                       align = c_fully_fold (align, false, NULL);
   19550              :                     }
   19551           35 :                   parens2.skip_until_found_close (parser);
   19552              :                 }
   19553              :             }
   19554              :         }
   19555           71 :       if (!has_modifiers)
   19556              :         {
   19557          143 :           location_t expr_loc = c_parser_peek_token (parser)->location;
   19558          143 :           c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19559          143 :           expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   19560          143 :           allocator = expr.value;
   19561          143 :           allocator = c_fully_fold (allocator, false, NULL);
   19562            7 :           orig_type = expr.original_type
   19563          143 :                       ? expr.original_type : TREE_TYPE (allocator);
   19564          143 :           orig_type = TYPE_MAIN_VARIANT (orig_type);
   19565              :         }
   19566          212 :       if (allocator
   19567          212 :           && (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
   19568          195 :               || TREE_CODE (orig_type) != ENUMERAL_TYPE
   19569          386 :               || (TYPE_NAME (orig_type)
   19570          193 :                   != get_identifier ("omp_allocator_handle_t"))))
   19571              :         {
   19572            8 :           error_at (clause_loc, "%<allocate%> clause allocator expression "
   19573              :                                 "has type %qT rather than "
   19574              :                                 "%<omp_allocator_handle_t%>",
   19575            4 :                                 TREE_TYPE (allocator));
   19576            4 :           allocator = NULL_TREE;
   19577              :         }
   19578          212 :       if (align
   19579          212 :           && (!INTEGRAL_TYPE_P (TREE_TYPE (align))
   19580           48 :               || !tree_fits_uhwi_p (align)
   19581           47 :               || !integer_pow2p (align)))
   19582              :         {
   19583            4 :           error_at (clause_loc, "%<allocate%> clause %<align%> modifier "
   19584              :                                 "argument needs to be positive constant "
   19585              :                                 "power of two integer expression");
   19586            4 :           align = NULL_TREE;
   19587              :         }
   19588          212 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   19589              :         {
   19590            0 :           parens.skip_until_found_close (parser);
   19591            0 :           return list;
   19592              :         }
   19593              :     }
   19594              : 
   19595          477 :   nl = c_parser_omp_variable_list (parser, clause_loc,
   19596              :                                    OMP_CLAUSE_ALLOCATE, list);
   19597              : 
   19598          477 :   if (allocator || align)
   19599          493 :     for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   19600              :       {
   19601          290 :         OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
   19602          290 :         OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
   19603              :       }
   19604              : 
   19605          477 :   parens.skip_until_found_close (parser);
   19606          477 :   return nl;
   19607              : }
   19608              : 
   19609              : /* OpenMP 5.0:
   19610              :    uses_allocators ( allocator-list )
   19611              : 
   19612              :    allocator-list:
   19613              :    allocator
   19614              :    allocator , allocator-list
   19615              :    allocator ( traits-array )
   19616              :    allocator ( traits-array ) , allocator-list
   19617              : 
   19618              :    Deprecated in 5.2, removed in 6.0: 'allocator(trait-array)' syntax.
   19619              : 
   19620              :    OpenMP 5.2:
   19621              : 
   19622              :    uses_allocators ( modifier : allocator-list )
   19623              :    uses_allocators ( modifier , modifier : allocator-list )
   19624              : 
   19625              :    OpenMP 6.0:
   19626              :    uses_allocators ( [modifier-list :] allocator-list [; ...] )
   19627              : 
   19628              :    modifier:
   19629              :    traits ( traits-array )
   19630              :    memspace ( mem-space-handle )  */
   19631              : 
   19632              : static tree
   19633           30 : c_parser_omp_clause_uses_allocators (c_parser *parser, tree list)
   19634              : {
   19635           30 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   19636           30 :   tree nl = list;
   19637           30 :   matching_parens parens;
   19638           30 :   if (!parens.require_open (parser))
   19639              :     return list;
   19640              : 
   19641           30 : parse_next:
   19642              : 
   19643           34 :   bool has_modifiers = false;
   19644           34 :   bool seen_allocators = false;
   19645           34 :   tree memspace_expr = NULL_TREE;
   19646           34 :   tree traits_var = NULL_TREE;
   19647              : 
   19648           34 :   if (c_parser_next_token_is (parser, CPP_NAME)
   19649           34 :       && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
   19650              :     {
   19651           22 :       unsigned int n = 3;
   19652           22 :       const char *p
   19653           22 :         = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   19654           17 :       if ((strcmp (p, "traits") == 0 || strcmp (p, "memspace") == 0)
   19655           13 :           && c_parser_check_balanced_raw_token_sequence (parser, &n)
   19656           35 :           && (c_parser_peek_nth_token_raw (parser, n)->type
   19657              :               == CPP_CLOSE_PAREN))
   19658              :         {
   19659           13 :           if (c_parser_peek_nth_token_raw (parser, n + 1)->type
   19660              :               == CPP_COLON)
   19661              :             has_modifiers = true;
   19662            2 :           else if (c_parser_peek_nth_token_raw (parser, n + 1)->type
   19663              :                    == CPP_COMMA
   19664            2 :                    && (c_parser_peek_nth_token_raw (parser, n + 2)->type
   19665              :                        == CPP_NAME)
   19666            4 :                    && (c_parser_peek_nth_token_raw (parser, n + 3)->type
   19667              :                        == CPP_OPEN_PAREN))
   19668              :             {
   19669            2 :               c_token *tok = c_parser_peek_nth_token_raw (parser, n + 2);
   19670            2 :               const char *q = IDENTIFIER_POINTER (tok->value);
   19671            2 :               n += 4;
   19672            2 :               if ((strcmp (q, "traits") == 0
   19673            1 :                    || strcmp (q, "memspace") == 0)
   19674            2 :                   && c_parser_check_balanced_raw_token_sequence (parser, &n)
   19675            4 :                   && (c_parser_peek_nth_token_raw (parser, n)->type
   19676              :                       == CPP_CLOSE_PAREN))
   19677              :                 {
   19678            2 :                   if (c_parser_peek_nth_token_raw (parser, n + 1)->type
   19679              :                       == CPP_COLON)
   19680            1 :                     has_modifiers = true;
   19681            2 :                   if ((c_parser_peek_nth_token_raw (parser, n + 1)->type
   19682              :                        == CPP_COMMA)
   19683            2 :                       && (c_parser_peek_nth_token_raw (parser, n + 2)->type
   19684              :                           == CPP_NAME))
   19685              :                     {
   19686            1 :                       c_token *tok
   19687            1 :                         = c_parser_peek_nth_token_raw (parser, n + 2);
   19688            1 :                       const char *m = IDENTIFIER_POINTER (tok->value);
   19689            1 :                       if (strcmp (p, m) == 0 || strcmp (q, m) == 0)
   19690              :                         {
   19691            1 :                           error_at (tok->location, "duplicate %qs modifier", m);
   19692            1 :                           goto end;
   19693              :                         }
   19694              :                     }
   19695              :                 }
   19696              :             }
   19697              :         }
   19698            1 :       if (has_modifiers)
   19699              :         {
   19700           12 :           c_parser_consume_token (parser);
   19701           12 :           matching_parens parens2;
   19702           12 :           parens2.require_open (parser);
   19703           12 :           c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19704           12 :           if (expr.value == error_mark_node)
   19705              :             ;
   19706            9 :           else if (strcmp (p, "traits") == 0)
   19707              :             {
   19708            4 :               traits_var = expr.value;
   19709            4 :               traits_var = c_fully_fold (traits_var, false, NULL);
   19710              :             }
   19711              :           else
   19712              :             {
   19713            5 :               memspace_expr = expr.value;
   19714            5 :               memspace_expr = c_fully_fold (memspace_expr, false, NULL);
   19715              :             }
   19716           12 :           parens2.skip_until_found_close (parser);
   19717           12 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   19718              :             {
   19719            1 :               c_parser_consume_token (parser);
   19720            1 :               c_token *tok = c_parser_peek_token (parser);
   19721            1 :               const char *q = "";
   19722            1 :               if (c_parser_next_token_is (parser, CPP_NAME))
   19723            1 :                 q = IDENTIFIER_POINTER (tok->value);
   19724            1 :               if (strcmp (q, "traits") != 0 && strcmp (q, "memspace") != 0)
   19725              :                 {
   19726            0 :                   c_parser_error (parser, "expected %<traits%> or "
   19727              :                                   "%<memspace%>");
   19728            0 :                   parens.skip_until_found_close (parser);
   19729            0 :                   return list;
   19730              :                 }
   19731            1 :               else if (strcmp (p, q) == 0)
   19732              :                 {
   19733            0 :                   error_at (tok->location, "duplicate %qs modifier", p);
   19734            0 :                   parens.skip_until_found_close (parser);
   19735            0 :                   return list;
   19736              :                 }
   19737            1 :               c_parser_consume_token (parser);
   19738            1 :               if (!parens2.require_open (parser))
   19739              :                 {
   19740            0 :                   parens.skip_until_found_close (parser);
   19741            0 :                   return list;
   19742              :                 }
   19743            1 :               expr = c_parser_expr_no_commas (parser, NULL);
   19744            1 :               if (strcmp (q, "traits") == 0)
   19745              :                 {
   19746            0 :                   traits_var = expr.value;
   19747            0 :                   traits_var = c_fully_fold (traits_var, false, NULL);
   19748              :                 }
   19749              :               else
   19750              :                 {
   19751            1 :                   memspace_expr = expr.value;
   19752            1 :                   memspace_expr = c_fully_fold (memspace_expr, false, NULL);
   19753              :                 }
   19754            1 :               parens2.skip_until_found_close (parser);
   19755              :             }
   19756           12 :           if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   19757            0 :             goto end;
   19758              :         }
   19759              :     }
   19760              : 
   19761           41 :   while (c_parser_next_token_is (parser, CPP_NAME))
   19762              :     {
   19763           41 :       location_t alloc_loc = c_parser_peek_token (parser)->location;
   19764           41 :       c_token *tok = c_parser_peek_token (parser);
   19765           41 :       const char *tok_s = IDENTIFIER_POINTER (tok->value);
   19766           41 :       tree t = lookup_name (tok->value);
   19767           41 :       if (t == NULL_TREE)
   19768              :         {
   19769            3 :           undeclared_variable (tok->location, tok->value);
   19770            3 :           t = error_mark_node;
   19771              :         }
   19772           41 :       c_parser_consume_token (parser);
   19773              : 
   19774              :       /* Legacy traits syntax.  */
   19775           41 :       tree legacy_traits = NULL_TREE;
   19776           41 :       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
   19777           13 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME
   19778           54 :           && c_parser_peek_nth_token_raw (parser, 3)->type == CPP_CLOSE_PAREN)
   19779              :         {
   19780           13 :           matching_parens parens2;
   19781           13 :           parens2.require_open (parser);
   19782           13 :           const char *tok_a
   19783           13 :             = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   19784           13 :           c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19785           13 :           location_t close_loc = c_parser_peek_token (parser)->location;
   19786           13 :           parens2.skip_until_found_close (parser);
   19787              : 
   19788           13 :           if (has_modifiers)
   19789              :             {
   19790            2 :               error_at (make_location (alloc_loc, alloc_loc, close_loc),
   19791              :                         "legacy %<%s(%s)%> traits syntax not allowed in "
   19792              :                         "%<uses_allocators%> clause when using modifiers",
   19793              :                         tok_s, tok_a);
   19794            3 :               goto end;
   19795              :             }
   19796           11 :           legacy_traits = c_fully_fold (expr.value, false, NULL);
   19797           11 :           if (legacy_traits == error_mark_node)
   19798            1 :             goto end;
   19799              : 
   19800           10 :           gcc_rich_location richloc (make_location (alloc_loc, alloc_loc, close_loc));
   19801           10 :           if (nl == list)
   19802              :             {
   19803              :               /* Fixit only works well if it is the only first item.  */
   19804            8 :               richloc.add_fixit_replace (alloc_loc, "traits");
   19805            8 :               richloc.add_fixit_insert_after (close_loc, ": ");
   19806            8 :               richloc.add_fixit_insert_after (close_loc, tok_s);
   19807              :             }
   19808           10 :           warning_at (&richloc, OPT_Wdeprecated_openmp,
   19809              :                       "the specification of arguments to %<uses_allocators%> "
   19810              :                       "where each item is of the form %<allocator(traits)%> is "
   19811              :                       "deprecated since OpenMP 5.2");
   19812           10 :         }
   19813              : 
   19814           38 :       if (seen_allocators && has_modifiers)
   19815              :         {
   19816            2 :           error_at (c_parser_peek_token (parser)->location,
   19817              :                     "%<uses_allocators%> clause only accepts a single "
   19818              :                     "allocator when using modifiers");
   19819            2 :           goto end;
   19820              :         }
   19821           36 :       seen_allocators = true;
   19822              : 
   19823           36 :       tree c = build_omp_clause (clause_loc,
   19824              :                                  OMP_CLAUSE_USES_ALLOCATORS);
   19825           36 :       OMP_CLAUSE_USES_ALLOCATORS_ALLOCATOR (c) = t;
   19826           36 :       OMP_CLAUSE_USES_ALLOCATORS_MEMSPACE (c) = memspace_expr;
   19827           36 :       OMP_CLAUSE_USES_ALLOCATORS_TRAITS (c) = (legacy_traits
   19828           36 :                                                ? legacy_traits : traits_var);
   19829           36 :       OMP_CLAUSE_CHAIN (c) = nl;
   19830           36 :       nl = c;
   19831              : 
   19832           36 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   19833            8 :         c_parser_consume_token (parser);
   19834              :       else
   19835              :         break;
   19836              :     }
   19837              : 
   19838           28 :   if (c_parser_next_token_is (parser, CPP_SEMICOLON))
   19839              :     {
   19840            4 :       c_parser_consume_token (parser);
   19841            4 :       goto parse_next;
   19842              :     }
   19843              : 
   19844           24 :  end:
   19845           30 :   parens.skip_until_found_close (parser);
   19846           30 :   return nl;
   19847              : }
   19848              : 
   19849              : /* OpenMP 4.0:
   19850              :    linear ( variable-list )
   19851              :    linear ( variable-list : expression )
   19852              : 
   19853              :    OpenMP 4.5:
   19854              :    linear ( modifier ( variable-list ) )
   19855              :    linear ( modifier ( variable-list ) : expression )
   19856              : 
   19857              :    modifier:
   19858              :      val
   19859              : 
   19860              :    OpenMP 5.2:
   19861              :    linear ( variable-list : modifiers-list )
   19862              : 
   19863              :    modifiers:
   19864              :      val
   19865              :      step ( expression )  */
   19866              : 
   19867              : static tree
   19868          476 : c_parser_omp_clause_linear (c_parser *parser, tree list)
   19869              : {
   19870          476 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   19871          476 :   location_t rm1_loc = UNKNOWN_LOCATION, rm2_loc = UNKNOWN_LOCATION;
   19872          476 :   location_t after_colon_loc = UNKNOWN_LOCATION;
   19873          476 :   tree nl, c, step;
   19874          476 :   enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
   19875          476 :   bool old_linear_modifier = false;
   19876              : 
   19877          476 :   matching_parens parens;
   19878          476 :   if (!parens.require_open (parser))
   19879              :     return list;
   19880              : 
   19881          476 :   if (c_parser_next_token_is (parser, CPP_NAME))
   19882              :     {
   19883          476 :       c_token *tok = c_parser_peek_token (parser);
   19884          476 :       const char *p = IDENTIFIER_POINTER (tok->value);
   19885          476 :       if (strcmp ("val", p) == 0)
   19886           12 :         kind = OMP_CLAUSE_LINEAR_VAL;
   19887          476 :       if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN)
   19888              :         kind = OMP_CLAUSE_LINEAR_DEFAULT;
   19889           12 :       if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
   19890              :         {
   19891           12 :           old_linear_modifier = true;
   19892           12 :           rm1_loc = make_location (tok->location, tok->location,
   19893           12 :                                    c_parser_peek_2nd_token (parser)->location);
   19894           12 :           c_parser_consume_token (parser);
   19895           12 :           c_parser_consume_token (parser);
   19896              :         }
   19897              :     }
   19898              : 
   19899          476 :   nl = c_parser_omp_variable_list (parser, clause_loc,
   19900              :                                    OMP_CLAUSE_LINEAR, list);
   19901              : 
   19902          476 :   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
   19903              :     {
   19904           12 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   19905           12 :         rm2_loc = c_parser_peek_token (parser)->location;
   19906           12 :       parens.skip_until_found_close (parser);
   19907              :     }
   19908              : 
   19909          476 :   if (c_parser_next_token_is (parser, CPP_COLON))
   19910              :     {
   19911          349 :       c_parser_consume_token (parser);
   19912          349 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   19913          349 :       after_colon_loc = expr_loc;
   19914          349 :       bool has_modifiers = false;
   19915          349 :       if (kind == OMP_CLAUSE_LINEAR_DEFAULT
   19916          687 :           && c_parser_next_token_is (parser, CPP_NAME))
   19917              :         {
   19918           74 :           c_token *tok = c_parser_peek_token (parser);
   19919           74 :           const char *p = IDENTIFIER_POINTER (tok->value);
   19920           74 :           unsigned int pos = 0;
   19921           74 :           if (strcmp ("val", p) == 0)
   19922            9 :             pos = 2;
   19923           65 :           else if (strcmp ("step", p) == 0
   19924           65 :                    && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
   19925              :             {
   19926           13 :               pos = 3;
   19927           13 :               if (c_parser_check_balanced_raw_token_sequence (parser, &pos)
   19928           13 :                   && (c_parser_peek_nth_token_raw (parser, pos)->type
   19929              :                       == CPP_CLOSE_PAREN))
   19930           13 :                 ++pos;
   19931              :               else
   19932            0 :                 pos = 0;
   19933              :             }
   19934           74 :           if (pos)
   19935              :             {
   19936           22 :               tok = c_parser_peek_nth_token_raw (parser, pos);
   19937           22 :               if (tok->type == CPP_COMMA || tok->type == CPP_CLOSE_PAREN)
   19938           19 :                 has_modifiers = true;
   19939              :             }
   19940              :         }
   19941           74 :       if (has_modifiers)
   19942              :         {
   19943              :           step = NULL_TREE;
   19944           29 :           while (c_parser_next_token_is (parser, CPP_NAME))
   19945              :             {
   19946           29 :               c_token *tok = c_parser_peek_token (parser);
   19947           29 :               const char *p = IDENTIFIER_POINTER (tok->value);
   19948           29 :               if (strcmp ("val", p) == 0)
   19949              :                 {
   19950           11 :                   if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
   19951              :                     error_at (tok->location, "multiple linear modifiers");
   19952           11 :                   kind = OMP_CLAUSE_LINEAR_DEFAULT;
   19953           11 :                   c_parser_consume_token (parser);
   19954              :                 }
   19955           18 :               else if (strcmp ("step", p) == 0)
   19956              :                 {
   19957           18 :                   c_parser_consume_token (parser);
   19958           18 :                   matching_parens parens2;
   19959           18 :                   if (parens2.require_open (parser))
   19960              :                     {
   19961           18 :                       if (step)
   19962            0 :                         error_at (tok->location,
   19963              :                                   "multiple %<step%> modifiers");
   19964           18 :                       expr_loc = c_parser_peek_token (parser)->location;
   19965           18 :                       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19966           18 :                       expr = convert_lvalue_to_rvalue (expr_loc, expr, false,
   19967              :                                                        true);
   19968           18 :                       step = c_fully_fold (expr.value, false, NULL);
   19969           18 :                       if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
   19970              :                         {
   19971            0 :                           error_at (clause_loc, "%<linear%> clause step "
   19972              :                                                 "expression must be integral");
   19973            0 :                           step = integer_one_node;
   19974              :                         }
   19975           18 :                       parens2.skip_until_found_close (parser);
   19976              :                     }
   19977              :                   else
   19978              :                     break;
   19979              :                 }
   19980              :               else
   19981              :                 break;
   19982           29 :               if (c_parser_next_token_is (parser, CPP_COMMA))
   19983              :                 {
   19984           10 :                   c_parser_consume_token (parser);
   19985           10 :                   continue;
   19986              :                 }
   19987              :               break;
   19988              :             }
   19989           19 :           if (!step)
   19990            1 :             step = integer_one_node;
   19991              :         }
   19992              :       else
   19993              :         {
   19994          330 :           c_expr expr = c_parser_expr_no_commas (parser, NULL);
   19995          330 :           expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   19996          330 :           step = c_fully_fold (expr.value, false, NULL);
   19997          330 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
   19998              :             {
   19999            2 :               error_at (clause_loc, "%<linear%> clause step expression must "
   20000              :                                     "be integral");
   20001            2 :               step = integer_one_node;
   20002              :             }
   20003              :         }
   20004              : 
   20005              :     }
   20006              :   else
   20007          127 :     step = integer_one_node;
   20008              : 
   20009          961 :   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   20010              :     {
   20011          485 :       OMP_CLAUSE_LINEAR_STEP (c) = step;
   20012          485 :       OMP_CLAUSE_LINEAR_KIND (c) = kind;
   20013          485 :       OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
   20014              :     }
   20015              : 
   20016          476 :   if (old_linear_modifier)
   20017              :     {
   20018           12 :       gcc_rich_location richloc (clause_loc);
   20019           12 :       if (rm2_loc != UNKNOWN_LOCATION)
   20020              :         {
   20021           12 :           richloc.add_fixit_remove (rm1_loc);
   20022           12 :           if (after_colon_loc != UNKNOWN_LOCATION)
   20023              :             {
   20024           11 :               richloc.add_fixit_remove (rm2_loc);
   20025           11 :               richloc.add_fixit_insert_before (after_colon_loc, "val, step (");
   20026           11 :               location_t close_loc = c_parser_peek_token (parser)->location;
   20027           11 :               richloc.add_fixit_insert_before (close_loc, ")");
   20028              :             }
   20029              :           else
   20030            1 :             richloc.add_fixit_replace (rm2_loc, " : val");
   20031              :         }
   20032           12 :       warning_at (&richloc, OPT_Wdeprecated_openmp,
   20033              :                   "specifying the list items as arguments to the "
   20034              :                   "modifiers is deprecated since OpenMP 5.2");
   20035           12 :     }
   20036              : 
   20037          476 :   parens.skip_until_found_close (parser);
   20038          476 :   return nl;
   20039              : }
   20040              : 
   20041              : /* OpenMP 5.0:
   20042              :    nontemporal ( variable-list ) */
   20043              : 
   20044              : static tree
   20045          121 : c_parser_omp_clause_nontemporal (c_parser *parser, tree list)
   20046              : {
   20047            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_NONTEMPORAL, list);
   20048              : }
   20049              : 
   20050              : /* OpenMP 4.0:
   20051              :    safelen ( constant-expression ) */
   20052              : 
   20053              : static tree
   20054          227 : c_parser_omp_clause_safelen (c_parser *parser, tree list)
   20055              : {
   20056          227 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20057          227 :   tree c, t;
   20058              : 
   20059          227 :   matching_parens parens;
   20060          227 :   if (!parens.require_open (parser))
   20061              :     return list;
   20062              : 
   20063          227 :   location_t expr_loc = c_parser_peek_token (parser)->location;
   20064          227 :   c_expr expr = c_parser_expr_no_commas (parser, NULL);
   20065          227 :   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   20066          227 :   t = expr.value;
   20067          227 :   t = c_fully_fold (t, false, NULL);
   20068          227 :   if (TREE_CODE (t) != INTEGER_CST
   20069          225 :       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
   20070          452 :       || tree_int_cst_sgn (t) != 1)
   20071              :     {
   20072            4 :       error_at (clause_loc, "%<safelen%> clause expression must "
   20073              :                             "be positive constant integer expression");
   20074            4 :       t = NULL_TREE;
   20075              :     }
   20076              : 
   20077          227 :   parens.skip_until_found_close (parser);
   20078          227 :   if (t == NULL_TREE || t == error_mark_node)
   20079              :     return list;
   20080              : 
   20081          223 :   check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen");
   20082              : 
   20083          223 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_SAFELEN);
   20084          223 :   OMP_CLAUSE_SAFELEN_EXPR (c) = t;
   20085          223 :   OMP_CLAUSE_CHAIN (c) = list;
   20086          223 :   return c;
   20087              : }
   20088              : 
   20089              : /* OpenMP 4.0:
   20090              :    simdlen ( constant-expression ) */
   20091              : 
   20092              : static tree
   20093          324 : c_parser_omp_clause_simdlen (c_parser *parser, tree list)
   20094              : {
   20095          324 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20096          324 :   tree c, t;
   20097              : 
   20098          324 :   matching_parens parens;
   20099          324 :   if (!parens.require_open (parser))
   20100              :     return list;
   20101              : 
   20102          324 :   location_t expr_loc = c_parser_peek_token (parser)->location;
   20103          324 :   c_expr expr = c_parser_expr_no_commas (parser, NULL);
   20104          324 :   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   20105          324 :   t = expr.value;
   20106          324 :   t = c_fully_fold (t, false, NULL);
   20107          324 :   if (TREE_CODE (t) != INTEGER_CST
   20108          322 :       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
   20109          646 :       || tree_int_cst_sgn (t) != 1)
   20110              :     {
   20111            4 :       error_at (clause_loc, "%<simdlen%> clause expression must "
   20112              :                             "be positive constant integer expression");
   20113            4 :       t = NULL_TREE;
   20114              :     }
   20115              : 
   20116          324 :   parens.skip_until_found_close (parser);
   20117          324 :   if (t == NULL_TREE || t == error_mark_node)
   20118              :     return list;
   20119              : 
   20120          320 :   check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen");
   20121              : 
   20122          320 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_SIMDLEN);
   20123          320 :   OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
   20124          320 :   OMP_CLAUSE_CHAIN (c) = list;
   20125          320 :   return c;
   20126              : }
   20127              : 
   20128              : /* OpenMP 4.5:
   20129              :    vec:
   20130              :      identifier [+/- integer]
   20131              :      vec , identifier [+/- integer]
   20132              : */
   20133              : 
   20134              : static tree
   20135          207 : c_parser_omp_clause_doacross_sink (c_parser *parser, location_t clause_loc,
   20136              :                                    tree list, bool depend_p)
   20137              : {
   20138          207 :   tree vec = NULL;
   20139          207 :   if (c_parser_next_token_is_not (parser, CPP_NAME)
   20140          207 :       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
   20141              :     {
   20142            0 :       c_parser_error (parser, "expected identifier");
   20143            0 :       return list;
   20144              :     }
   20145              : 
   20146          207 :   if (!depend_p)
   20147              :     {
   20148           83 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20149           83 :       if (strcmp (p, "omp_cur_iteration") == 0
   20150           36 :           && c_parser_peek_2nd_token (parser)->type == CPP_MINUS
   20151           34 :           && c_parser_peek_nth_token (parser, 3)->type == CPP_NUMBER
   20152          116 :           && c_parser_peek_nth_token (parser, 4)->type == CPP_CLOSE_PAREN)
   20153              :         {
   20154           33 :           tree val = c_parser_peek_nth_token (parser, 3)->value;
   20155           33 :           if (integer_onep (val))
   20156              :             {
   20157           33 :               c_parser_consume_token (parser);
   20158           33 :               c_parser_consume_token (parser);
   20159           33 :               c_parser_consume_token (parser);
   20160           33 :               tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
   20161           33 :               OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
   20162           33 :               OMP_CLAUSE_CHAIN (u) = list;
   20163           33 :               return u;
   20164              :             }
   20165              :         }
   20166              :     }
   20167              : 
   20168              : 
   20169              : 
   20170         1152 :   while (c_parser_next_token_is (parser, CPP_NAME)
   20171         1152 :          && c_parser_peek_token (parser)->id_kind == C_ID_ID)
   20172              :     {
   20173         1152 :       tree t = lookup_name (c_parser_peek_token (parser)->value);
   20174         1152 :       tree addend = NULL;
   20175              : 
   20176         1152 :       if (t == NULL_TREE)
   20177              :         {
   20178            6 :           undeclared_variable (c_parser_peek_token (parser)->location,
   20179            6 :                                c_parser_peek_token (parser)->value);
   20180            6 :           t = error_mark_node;
   20181              :         }
   20182              : 
   20183         1152 :       c_parser_consume_token (parser);
   20184              : 
   20185         1152 :       bool neg = false;
   20186         1152 :       if (c_parser_next_token_is (parser, CPP_MINUS))
   20187              :         neg = true;
   20188          920 :       else if (!c_parser_next_token_is (parser, CPP_PLUS))
   20189              :         {
   20190          857 :           addend = integer_zero_node;
   20191          857 :           neg = false;
   20192          857 :           goto add_to_vector;
   20193              :         }
   20194          295 :       c_parser_consume_token (parser);
   20195              : 
   20196          295 :       if (c_parser_next_token_is_not (parser, CPP_NUMBER))
   20197              :         {
   20198            1 :           c_parser_error (parser, "expected integer");
   20199            1 :           return list;
   20200              :         }
   20201              : 
   20202          294 :       addend = c_parser_peek_token (parser)->value;
   20203          294 :       if (TREE_CODE (addend) != INTEGER_CST)
   20204              :         {
   20205            0 :           c_parser_error (parser, "expected integer");
   20206            0 :           return list;
   20207              :         }
   20208          294 :       c_parser_consume_token (parser);
   20209              : 
   20210         1151 :     add_to_vector:
   20211         1151 :       if (t != error_mark_node)
   20212              :         {
   20213         1146 :           vec = tree_cons (addend, t, vec);
   20214         1146 :           if (neg)
   20215          229 :             OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
   20216              :         }
   20217              : 
   20218         1151 :       if (c_parser_next_token_is_not (parser, CPP_COMMA)
   20219          979 :           || c_parser_peek_2nd_token (parser)->type != CPP_NAME
   20220         2129 :           || c_parser_peek_2nd_token (parser)->id_kind != C_ID_ID)
   20221              :         break;
   20222              : 
   20223          978 :       c_parser_consume_token (parser);
   20224              :     }
   20225              : 
   20226          173 :   if (vec == NULL_TREE)
   20227              :     return list;
   20228              : 
   20229          169 :   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
   20230          169 :   OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
   20231          169 :   OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
   20232          169 :   OMP_CLAUSE_DECL (u) = nreverse (vec);
   20233          169 :   OMP_CLAUSE_CHAIN (u) = list;
   20234          169 :   return u;
   20235              : }
   20236              : 
   20237              : /* OpenMP 5.0:
   20238              :    iterators ( iterators-definition )
   20239              : 
   20240              :    iterators-definition:
   20241              :      iterator-specifier
   20242              :      iterator-specifier , iterators-definition
   20243              : 
   20244              :    iterator-specifier:
   20245              :      identifier = range-specification
   20246              :      iterator-type identifier = range-specification
   20247              : 
   20248              :    range-specification:
   20249              :      begin : end
   20250              :      begin : end : step  */
   20251              : 
   20252              : static tree
   20253          150 : c_parser_omp_iterators (c_parser *parser)
   20254              : {
   20255          150 :   tree ret = NULL_TREE, *last = &ret;
   20256          150 :   c_parser_consume_token (parser);
   20257              : 
   20258          150 :   push_scope ();
   20259              : 
   20260          150 :   matching_parens parens;
   20261          150 :   if (!parens.require_open (parser))
   20262            1 :     return error_mark_node;
   20263              : 
   20264          215 :   do
   20265              :     {
   20266          182 :       tree iter_type = NULL_TREE, type_expr = NULL_TREE;
   20267          182 :       if (c_parser_next_tokens_start_typename (parser, cla_prefer_id))
   20268              :         {
   20269           50 :           struct c_type_name *type = c_parser_type_name (parser);
   20270           50 :           if (type != NULL)
   20271           50 :             iter_type = groktypename (type, &type_expr, NULL);
   20272              :         }
   20273           50 :       if (iter_type == NULL_TREE)
   20274          132 :         iter_type = integer_type_node;
   20275              : 
   20276          182 :       location_t loc = c_parser_peek_token (parser)->location;
   20277          182 :       if (!c_parser_next_token_is (parser, CPP_NAME))
   20278              :         {
   20279            8 :           c_parser_error (parser, "expected identifier");
   20280            8 :           break;
   20281              :         }
   20282              : 
   20283          174 :       tree id = c_parser_peek_token (parser)->value;
   20284          174 :       c_parser_consume_token (parser);
   20285              : 
   20286          174 :       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   20287              :         break;
   20288              : 
   20289          172 :       location_t eloc = c_parser_peek_token (parser)->location;
   20290          172 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   20291          172 :       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
   20292          172 :       tree begin = expr.value;
   20293              : 
   20294          172 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   20295              :         break;
   20296              : 
   20297          170 :       eloc = c_parser_peek_token (parser)->location;
   20298          170 :       expr = c_parser_expr_no_commas (parser, NULL);
   20299          170 :       expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
   20300          170 :       tree end = expr.value;
   20301              : 
   20302          170 :       tree step = integer_one_node;
   20303          170 :       if (c_parser_next_token_is (parser, CPP_COLON))
   20304              :         {
   20305           58 :           c_parser_consume_token (parser);
   20306           58 :           eloc = c_parser_peek_token (parser)->location;
   20307           58 :           expr = c_parser_expr_no_commas (parser, NULL);
   20308           58 :           expr = convert_lvalue_to_rvalue (eloc, expr, true, false);
   20309           58 :           step = expr.value;
   20310              :         }
   20311              : 
   20312          170 :       tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
   20313          170 :       DECL_ARTIFICIAL (iter_var) = 1;
   20314          170 :       DECL_CONTEXT (iter_var) = current_function_decl;
   20315          170 :       pushdecl (iter_var);
   20316              : 
   20317          170 :       *last = make_tree_vec (6);
   20318          170 :       TREE_VEC_ELT (*last, 0) = iter_var;
   20319          170 :       TREE_VEC_ELT (*last, 1) = begin;
   20320          170 :       TREE_VEC_ELT (*last, 2) = end;
   20321          170 :       TREE_VEC_ELT (*last, 3) = step;
   20322          170 :       last = &TREE_CHAIN (*last);
   20323              : 
   20324          170 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   20325              :         {
   20326           33 :           c_parser_consume_token (parser);
   20327           33 :           continue;
   20328              :         }
   20329              :       break;
   20330              :     }
   20331              :   while (1);
   20332              : 
   20333          149 :   parens.skip_until_found_close (parser);
   20334          149 :   return ret ? ret : error_mark_node;
   20335              : }
   20336              : 
   20337              : /* OpenMP 5.0:
   20338              :    affinity ( [aff-modifier :] variable-list )
   20339              :    aff-modifier:
   20340              :      iterator ( iterators-definition )  */
   20341              : 
   20342              : static tree
   20343          146 : c_parser_omp_clause_affinity (c_parser *parser, tree list)
   20344              : {
   20345          146 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20346          146 :   tree nl, iterators = NULL_TREE;
   20347              : 
   20348          146 :   matching_parens parens;
   20349          146 :   if (!parens.require_open (parser))
   20350              :     return list;
   20351              : 
   20352          146 :   if (c_parser_next_token_is (parser, CPP_NAME))
   20353              :     {
   20354          144 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20355          144 :       bool parse_iter = ((strcmp ("iterator", p) == 0)
   20356          144 :                          && (c_parser_peek_2nd_token (parser)->type
   20357           50 :                              == CPP_OPEN_PAREN));
   20358           50 :       if (parse_iter)
   20359              :         {
   20360           50 :           unsigned n = 3;
   20361           50 :           parse_iter = (c_parser_check_balanced_raw_token_sequence (parser, &n)
   20362           50 :                         && (c_parser_peek_nth_token_raw (parser, n)->type
   20363              :                             == CPP_CLOSE_PAREN)
   20364          100 :                         && (c_parser_peek_nth_token_raw (parser, n + 1)->type
   20365              :                             == CPP_COLON));
   20366              :         }
   20367            3 :       if (parse_iter)
   20368              :         {
   20369           47 :           iterators = c_parser_omp_iterators (parser);
   20370           47 :           if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   20371              :             {
   20372            0 :               if (iterators)
   20373            0 :                 pop_scope ();
   20374            0 :               parens.skip_until_found_close (parser);
   20375            0 :               return list;
   20376              :             }
   20377              :         }
   20378              :     }
   20379          146 :   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_AFFINITY,
   20380              :                                    list);
   20381          146 :   if (iterators)
   20382              :     {
   20383           47 :       tree block = pop_scope ();
   20384           47 :       if (iterators != error_mark_node)
   20385              :         {
   20386           43 :           TREE_VEC_ELT (iterators, 5) = block;
   20387           99 :           for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   20388          112 :             OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
   20389           56 :                                                    OMP_CLAUSE_DECL (c));
   20390              :         }
   20391              :     }
   20392              : 
   20393          146 :   parens.skip_until_found_close (parser);
   20394          146 :   return nl;
   20395              : }
   20396              : 
   20397              : 
   20398              : /* OpenMP 4.0:
   20399              :    depend ( depend-kind: variable-list )
   20400              : 
   20401              :    depend-kind:
   20402              :      in | out | inout
   20403              : 
   20404              :    OpenMP 4.5:
   20405              :    depend ( source )
   20406              : 
   20407              :    depend ( sink  : vec )
   20408              : 
   20409              :    OpenMP 5.0:
   20410              :    depend ( depend-modifier , depend-kind: variable-list )
   20411              : 
   20412              :    depend-kind:
   20413              :      in | out | inout | mutexinoutset | depobj | inoutset
   20414              : 
   20415              :    depend-modifier:
   20416              :      iterator ( iterators-definition )  */
   20417              : 
   20418              : static tree
   20419          895 : c_parser_omp_clause_depend (c_parser *parser, tree list, location_t here)
   20420              : {
   20421          895 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20422          895 :   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
   20423          895 :   enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;
   20424          895 :   tree nl, c, iterators = NULL_TREE;
   20425              : 
   20426          895 :   matching_parens parens;
   20427          895 :   if (!parens.require_open (parser))
   20428              :     return list;
   20429              : 
   20430         1049 :   do
   20431              :     {
   20432          972 :       if (c_parser_next_token_is_not (parser, CPP_NAME))
   20433            0 :         goto invalid_kind;
   20434              : 
   20435          972 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20436          972 :       if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
   20437              :         {
   20438           77 :           iterators = c_parser_omp_iterators (parser);
   20439           77 :           c_parser_require (parser, CPP_COMMA, "expected %<,%>");
   20440           77 :           continue;
   20441              :         }
   20442          895 :       if (strcmp ("in", p) == 0)
   20443              :         kind = OMP_CLAUSE_DEPEND_IN;
   20444          644 :       else if (strcmp ("inout", p) == 0)
   20445              :         kind = OMP_CLAUSE_DEPEND_INOUT;
   20446          425 :       else if (strcmp ("inoutset", p) == 0)
   20447              :         kind = OMP_CLAUSE_DEPEND_INOUTSET;
   20448          410 :       else if (strcmp ("mutexinoutset", p) == 0)
   20449              :         kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
   20450          389 :       else if (strcmp ("out", p) == 0)
   20451              :         kind = OMP_CLAUSE_DEPEND_OUT;
   20452          244 :       else if (strcmp ("depobj", p) == 0)
   20453              :         kind = OMP_CLAUSE_DEPEND_DEPOBJ;
   20454          223 :       else if (strcmp ("sink", p) == 0)
   20455              :         {
   20456          124 :           gcc_rich_location richloc (clause_loc);
   20457          124 :           richloc.add_fixit_replace (here, "doacross");
   20458          124 :           warning_at (&richloc, OPT_Wdeprecated_openmp,
   20459              :                       "%<sink%> modifier with %<depend%> clause deprecated "
   20460              :                       "since OpenMP 5.2, use with %<doacross%>");
   20461          124 :           dkind = OMP_CLAUSE_DOACROSS_SINK;
   20462          124 :         }
   20463           99 :       else if (strcmp ("source", p) == 0)
   20464              :         {
   20465           97 :           gcc_rich_location richloc (clause_loc);
   20466           97 :           richloc.add_fixit_replace (here, "doacross");
   20467           97 :           warning_at (&richloc, OPT_Wdeprecated_openmp,
   20468              :                       "%<source%> modifier with %<depend%> clause deprecated "
   20469              :                       "since OpenMP 5.2, use with %<doacross%>");
   20470           97 :           dkind = OMP_CLAUSE_DOACROSS_SOURCE;
   20471           97 :         }
   20472              :       else
   20473            2 :         goto invalid_kind;
   20474          893 :       break;
   20475           77 :     }
   20476              :   while (1);
   20477              : 
   20478          893 :   c_parser_consume_token (parser);
   20479              : 
   20480          893 :   if (iterators
   20481          893 :       && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
   20482          893 :           || dkind == OMP_CLAUSE_DOACROSS_SINK))
   20483              :     {
   20484            2 :       pop_scope ();
   20485            2 :       error_at (clause_loc, "%<iterator%> modifier incompatible with %qs",
   20486              :                 dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
   20487            2 :       iterators = NULL_TREE;
   20488              :     }
   20489              : 
   20490          893 :   if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
   20491              :     {
   20492           97 :       c = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
   20493           97 :       OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
   20494           97 :       OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
   20495           97 :       OMP_CLAUSE_DECL (c) = NULL_TREE;
   20496           97 :       OMP_CLAUSE_CHAIN (c) = list;
   20497           97 :       parens.skip_until_found_close (parser);
   20498           97 :       return c;
   20499              :     }
   20500              : 
   20501          796 :   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   20502            0 :     goto resync_fail;
   20503              : 
   20504          796 :   if (dkind == OMP_CLAUSE_DOACROSS_SINK)
   20505          124 :     nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, true);
   20506              :   else
   20507              :     {
   20508          672 :       nl = c_parser_omp_variable_list (parser, clause_loc,
   20509              :                                        OMP_CLAUSE_DEPEND, list);
   20510              : 
   20511          672 :       if (iterators)
   20512              :         {
   20513           73 :           tree block = pop_scope ();
   20514           73 :           if (iterators == error_mark_node)
   20515              :             iterators = NULL_TREE;
   20516              :           else
   20517           68 :             TREE_VEC_ELT (iterators, 5) = block;
   20518              :         }
   20519              : 
   20520         1385 :       for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   20521              :         {
   20522          713 :           OMP_CLAUSE_DEPEND_KIND (c) = kind;
   20523          713 :           if (iterators)
   20524          150 :             OMP_CLAUSE_DECL (c)
   20525          150 :               = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
   20526              :         }
   20527              :     }
   20528              : 
   20529          796 :   parens.skip_until_found_close (parser);
   20530          796 :   return nl;
   20531              : 
   20532            2 :  invalid_kind:
   20533            2 :   c_parser_error (parser, "invalid depend kind");
   20534            2 :  resync_fail:
   20535            2 :   parens.skip_until_found_close (parser);
   20536            2 :   if (iterators)
   20537            2 :     pop_scope ();
   20538              :   return list;
   20539              : }
   20540              : 
   20541              : /* OpenMP 5.2:
   20542              :    doacross ( source : )
   20543              :    doacross ( source : omp_cur_iteration )
   20544              : 
   20545              :    doacross ( sink : vec )
   20546              :    doacross ( sink : omp_cur_iteration - logical_iteration )  */
   20547              : 
   20548              : static tree
   20549          145 : c_parser_omp_clause_doacross (c_parser *parser, tree list)
   20550              : {
   20551          145 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20552          145 :   enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;
   20553          145 :   tree nl;
   20554          145 :   const char *p;
   20555              : 
   20556          145 :   matching_parens parens;
   20557          145 :   if (!parens.require_open (parser))
   20558              :     return list;
   20559              : 
   20560          145 :   if (c_parser_next_token_is_not (parser, CPP_NAME))
   20561            0 :     goto invalid_kind;
   20562              : 
   20563          145 :   p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20564          145 :   if (strcmp ("sink", p) == 0)
   20565              :     kind = OMP_CLAUSE_DOACROSS_SINK;
   20566           60 :   else if (strcmp ("source", p) == 0)
   20567              :     kind = OMP_CLAUSE_DOACROSS_SOURCE;
   20568              :   else
   20569            0 :     goto invalid_kind;
   20570              : 
   20571          145 :   c_parser_consume_token (parser);
   20572              : 
   20573          145 :   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   20574            4 :     goto resync_fail;
   20575              : 
   20576          141 :   if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
   20577              :     {
   20578           58 :       if (c_parser_next_token_is (parser, CPP_NAME)
   20579           58 :           && strcmp (IDENTIFIER_POINTER (c_parser_peek_token (parser)->value),
   20580              :                      "omp_cur_iteration") == 0)
   20581           28 :         c_parser_consume_token (parser);
   20582           58 :       nl = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
   20583           58 :       OMP_CLAUSE_DOACROSS_KIND (nl) = OMP_CLAUSE_DOACROSS_SOURCE;
   20584           58 :       OMP_CLAUSE_DECL (nl) = NULL_TREE;
   20585           58 :       OMP_CLAUSE_CHAIN (nl) = list;
   20586              :     }
   20587              :   else
   20588           83 :     nl = c_parser_omp_clause_doacross_sink (parser, clause_loc, list, false);
   20589              : 
   20590          141 :   parens.skip_until_found_close (parser);
   20591          141 :   return nl;
   20592              : 
   20593            0 :  invalid_kind:
   20594            0 :   c_parser_error (parser, "invalid doacross kind");
   20595            4 :  resync_fail:
   20596            4 :   parens.skip_until_found_close (parser);
   20597            4 :   return list;
   20598              : }
   20599              : 
   20600              : /* OpenMP 6.1:
   20601              :    dyn_groupprivate ( [fallback-modifier : ] integer-expression )
   20602              : 
   20603              :    fallback-modifier
   20604              :       fallback( abort | default_mem | null )  */
   20605              : 
   20606              : static tree
   20607           21 : c_parser_omp_clause_dyn_groupprivate (c_parser *parser, tree list)
   20608              : {
   20609           21 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20610           21 :   matching_parens parens;
   20611           21 :   if (!parens.require_open (parser))
   20612              :     return list;
   20613              : 
   20614           21 :   enum omp_clause_fallback_kind kind = OMP_CLAUSE_FALLBACK_UNSPECIFIED;
   20615              : 
   20616           21 :   unsigned n = 3;
   20617           21 :   if (c_parser_next_token_is (parser, CPP_NAME)
   20618           21 :       && (c_parser_peek_2nd_token (parser)->type == CPP_COLON
   20619            9 :           || (c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
   20620            8 :               && c_parser_check_balanced_raw_token_sequence (parser, &n)
   20621            8 :               && (c_parser_peek_nth_token_raw (parser, n)->type
   20622              :                   == CPP_CLOSE_PAREN)
   20623            8 :               && (c_parser_peek_nth_token_raw (parser, n + 1)->type
   20624              :                   == CPP_COLON))))
   20625              :     {
   20626           10 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20627           10 :       if (strcmp (p, "fallback") != 0)
   20628              :         {
   20629            3 :           c_parser_error (parser, "expected %<fallback%> modifier");
   20630            3 :           return list;
   20631              :         }
   20632            7 :       c_parser_consume_token (parser);
   20633            7 :       if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   20634              :         return list;
   20635            6 :       p = "";
   20636            6 :       if (c_parser_next_token_is (parser, CPP_NAME))
   20637            5 :         p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20638            6 :       if (strcmp (p, "abort") == 0)
   20639              :         kind = OMP_CLAUSE_FALLBACK_ABORT;
   20640            5 :       else if (strcmp (p, "default_mem") == 0)
   20641              :         kind = OMP_CLAUSE_FALLBACK_DEFAULT_MEM;
   20642            4 :       else if (strcmp (p, "null") == 0)
   20643              :         kind = OMP_CLAUSE_FALLBACK_NULL;
   20644              :       else
   20645              :         {
   20646            2 :           c_parser_error (parser, "expected %<abort%>, %<default_mem%>, or "
   20647              :                                   "%<null%> as fallback mode");
   20648            2 :           return list;
   20649              :         }
   20650            4 :       c_parser_consume_token (parser);
   20651            4 :       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   20652              :         return list;
   20653            3 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   20654              :         return list;
   20655              :     }
   20656           14 :   location_t expr_loc = c_parser_peek_token (parser)->location;
   20657           14 :   c_expr expr = c_parser_expr_no_commas (parser, NULL);
   20658           14 :   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   20659           14 :   tree size = c_fully_fold (expr.value, false, NULL);
   20660           14 :   parens.skip_until_found_close (parser);
   20661              : 
   20662           14 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (size)))
   20663              :     {
   20664            2 :       error_at (expr_loc, "expected integer expression");
   20665            2 :       return list;
   20666              :     }
   20667              : 
   20668              :   /* Attempt to statically determine when the number is negative.  */
   20669           12 :   tree c = fold_build2_loc (expr_loc, LT_EXPR, boolean_type_node, size,
   20670           12 :                             build_int_cst (TREE_TYPE (size), 0));
   20671           12 :   protected_set_expr_location (c, expr_loc);
   20672           12 :   if (c == boolean_true_node)
   20673              :     {
   20674            3 :       warning_at (expr_loc, OPT_Wopenmp,
   20675              :                   "%<dyn_groupprivate%> value must be non-negative");
   20676            3 :       size = integer_zero_node;
   20677              :     }
   20678           12 :   check_no_duplicate_clause (list, OMP_CLAUSE_DYN_GROUPPRIVATE,
   20679              :                              "dyn_groupprivate");
   20680              : 
   20681           12 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_DYN_GROUPPRIVATE);
   20682           12 :   OMP_CLAUSE_DYN_GROUPPRIVATE_KIND (c) = kind;
   20683           12 :   OMP_CLAUSE_DYN_GROUPPRIVATE_EXPR (c) = size;
   20684           12 :   OMP_CLAUSE_CHAIN (c) = list;
   20685           12 :   list = c;
   20686              : 
   20687           12 :   return list;
   20688              : }
   20689              : 
   20690              : /* OpenMP 4.0:
   20691              :    map ( map-kind: variable-list )
   20692              :    map ( variable-list )
   20693              : 
   20694              :    map-kind:
   20695              :      alloc | to | from | tofrom
   20696              : 
   20697              :    OpenMP 4.5:
   20698              :    map-kind:
   20699              :      alloc | to | from | tofrom | release | delete
   20700              : 
   20701              :    map ( always [,] map-kind: variable-list )
   20702              : 
   20703              :    OpenMP 5.0:
   20704              :    map ( [map-type-modifier[,] ...] map-kind: variable-list )
   20705              : 
   20706              :    map-type-modifier:
   20707              :      always | close | present | iterator (iterators-definition)  */
   20708              : 
   20709              : static tree
   20710         1817 : c_parser_omp_clause_map (c_parser *parser, tree list, bool declare_mapper_p)
   20711              : {
   20712         1817 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   20713         1817 :   tree nl, c;
   20714         1817 :   enum gomp_map_kind kind = declare_mapper_p ? GOMP_MAP_UNSET : GOMP_MAP_TOFROM;
   20715              : 
   20716         1817 :   matching_parens parens;
   20717         1817 :   if (!parens.require_open (parser))
   20718              :     return list;
   20719              : 
   20720              :   int pos = 1;
   20721         2396 :   int map_kind_pos = 0;
   20722              :   int iterator_length = 0;
   20723         2975 :   for (;;)
   20724              :     {
   20725         2396 :       c_token *tok = c_parser_peek_nth_token_raw (parser, pos);
   20726         2396 :       if (tok->type != CPP_NAME)
   20727              :         break;
   20728              : 
   20729         2077 :       const char *p = IDENTIFIER_POINTER (tok->value);
   20730         2077 :       c_token *next_tok = c_parser_peek_nth_token_raw (parser, pos + 1);
   20731         2077 :       if (strcmp (p, "iterator") == 0 && next_tok->type == CPP_OPEN_PAREN)
   20732              :         {
   20733           16 :           unsigned n = pos + 2;
   20734           16 :           if (c_parser_check_balanced_raw_token_sequence (parser, &n)
   20735           16 :               && c_parser_peek_nth_token_raw (parser, n)->type
   20736              :                  == CPP_CLOSE_PAREN)
   20737              :             {
   20738           16 :               iterator_length = n - pos + 1;
   20739           16 :               pos = n;
   20740           16 :               next_tok = c_parser_peek_nth_token_raw (parser, pos + 1);
   20741              :             }
   20742              :         }
   20743              : 
   20744         2077 :       if (next_tok->type == CPP_COLON)
   20745              :         {
   20746              :           map_kind_pos = pos;
   20747              :           break;
   20748              :         }
   20749              : 
   20750          579 :       if (next_tok->type == CPP_COMMA)
   20751          195 :         pos++;
   20752          384 :       else if (c_parser_peek_nth_token_raw (parser, pos + 1)->type
   20753              :                == CPP_OPEN_PAREN)
   20754              :         {
   20755           13 :           unsigned int npos = pos + 2;
   20756           13 :           if (c_parser_check_balanced_raw_token_sequence (parser, &npos)
   20757           13 :               && (c_parser_peek_nth_token_raw (parser, npos)->type
   20758              :                   == CPP_CLOSE_PAREN)
   20759           26 :               && (c_parser_peek_nth_token_raw (parser, npos + 1)->type
   20760              :                   == CPP_COMMA))
   20761           12 :             pos = npos + 1;
   20762              :         }
   20763              : 
   20764          579 :       pos++;
   20765          579 :     }
   20766              : 
   20767         1817 :   int always_modifier = 0;
   20768         1817 :   int close_modifier = 0;
   20769         1817 :   int present_modifier = 0;
   20770         1817 :   int mapper_modifier = 0;
   20771         1817 :   int num_commas = 0;
   20772         1817 :   int num_identifiers = 0;
   20773         1817 :   tree mapper_name = NULL_TREE;
   20774         1817 :   tree iterators = NULL_TREE;
   20775         2196 :   for (int pos = 1; pos < map_kind_pos; ++pos)
   20776              :     {
   20777          397 :       c_token *tok = c_parser_peek_token (parser);
   20778              : 
   20779          397 :       if (tok->type == CPP_COMMA)
   20780              :         {
   20781          166 :           ++num_commas;
   20782          166 :           if (num_commas > num_identifiers)
   20783            0 :             c_parser_error (parser, "illegal comma");
   20784          166 :           c_parser_consume_token (parser);
   20785          166 :           continue;
   20786              :         }
   20787              : 
   20788          231 :       const char *p = IDENTIFIER_POINTER (tok->value);
   20789          231 :       if (strcmp ("always", p) == 0)
   20790              :         {
   20791           78 :           if (always_modifier)
   20792              :             {
   20793            4 :               c_parser_error (parser, "too many %<always%> modifiers");
   20794            4 :               parens.skip_until_found_close (parser);
   20795            4 :               return list;
   20796              :             }
   20797           74 :           always_modifier++;
   20798           74 :           c_parser_consume_token (parser);
   20799              :         }
   20800          153 :       else if (strcmp ("close", p) == 0)
   20801              :         {
   20802           65 :           if (close_modifier)
   20803              :             {
   20804            4 :               c_parser_error (parser, "too many %<close%> modifiers");
   20805            4 :               parens.skip_until_found_close (parser);
   20806            4 :               return list;
   20807              :             }
   20808           61 :           close_modifier++;
   20809           61 :           c_parser_consume_token (parser);
   20810              :         }
   20811           88 :       else if (strcmp ("iterator", p) == 0)
   20812              :         {
   20813           16 :           if (iterators)
   20814              :             {
   20815            1 :               c_parser_error (parser, "too many %<iterator%> modifiers");
   20816            1 :               parens.skip_until_found_close (parser);
   20817            1 :               return list;
   20818              :             }
   20819           15 :           iterators = c_parser_omp_iterators (parser);
   20820           15 :           pos += iterator_length - 1;
   20821              :         }
   20822           72 :       else if (strcmp ("mapper", p) == 0)
   20823              :         {
   20824           12 :           c_parser_consume_token (parser);
   20825              : 
   20826           12 :           matching_parens mparens;
   20827           12 :           if (mparens.require_open (parser))
   20828              :             {
   20829           12 :               if (mapper_modifier)
   20830              :                 {
   20831            0 :                   c_parser_error (parser, "too many %<mapper%> modifiers");
   20832              :                   /* Assume it's a well-formed mapper modifier, even if it
   20833              :                      seems to be in the wrong place.  */
   20834            0 :                   c_parser_consume_token (parser);
   20835            0 :                   mparens.require_close (parser);
   20836            0 :                   parens.skip_until_found_close (parser);
   20837            0 :                   return list;
   20838              :                 }
   20839              : 
   20840           12 :               tok = c_parser_peek_token (parser);
   20841              : 
   20842           12 :               switch (tok->type)
   20843              :                 {
   20844            5 :                 case CPP_NAME:
   20845            5 :                   {
   20846            5 :                     mapper_name = tok->value;
   20847            5 :                     c_parser_consume_token (parser);
   20848            5 :                     if (declare_mapper_p)
   20849              :                       {
   20850            1 :                         error_at (tok->location,
   20851              :                                   "in %<declare mapper%> directives, parameter "
   20852              :                                   "to %<mapper%> modifier must be %<default%>");
   20853              :                       }
   20854              :                   }
   20855              :                   break;
   20856              : 
   20857            7 :                 case CPP_KEYWORD:
   20858            7 :                   if (tok->keyword == RID_DEFAULT)
   20859              :                     {
   20860            7 :                       c_parser_consume_token (parser);
   20861            7 :                       break;
   20862              :                     }
   20863              :                   /* Fallthrough.  */
   20864              : 
   20865            0 :                 default:
   20866            0 :                   error_at (tok->location,
   20867              :                             "expected identifier or %<default%>");
   20868            0 :                   return list;
   20869              :                 }
   20870              : 
   20871           12 :               if (!mparens.require_close (parser))
   20872              :                 {
   20873            0 :                   parens.skip_until_found_close (parser);
   20874            0 :                   return list;
   20875              :                 }
   20876              : 
   20877           12 :               mapper_modifier++;
   20878           12 :               pos += 3;
   20879              :             }
   20880              :         }
   20881           60 :       else if (strcmp ("present", p) == 0)
   20882              :         {
   20883           55 :           if (present_modifier)
   20884              :             {
   20885            4 :               c_parser_error (parser, "too many %<present%> modifiers");
   20886            4 :               parens.skip_until_found_close (parser);
   20887            4 :               return list;
   20888              :             }
   20889           51 :           present_modifier++;
   20890           51 :           c_parser_consume_token (parser);
   20891              :         }
   20892              :       else
   20893              :         {
   20894            5 :           c_parser_error (parser, "%<map%> clause with map-type modifier other "
   20895              :                                   "than %<always%>, %<close%>, %<iterator%>, "
   20896              :                                   "%<mapper%> or %<present%>");
   20897            5 :           parens.skip_until_found_close (parser);
   20898            5 :           return list;
   20899              :         }
   20900          213 :       ++num_identifiers;
   20901          213 :       if (num_identifiers - 1 > num_commas)
   20902              :         {
   20903           30 :           gcc_rich_location richloc (clause_loc);
   20904           30 :           richloc.add_fixit_insert_before (tok->location, ",");
   20905           30 :           warning_at (&richloc, OPT_Wdeprecated_openmp,
   20906              :                       "%<map%> clause modifiers without comma separation is "
   20907              :                       "deprecated since OpenMP 5.2");
   20908           30 :         }
   20909              :       num_commas = num_identifiers - 1;
   20910              :     }
   20911              : 
   20912         1799 :   if (c_parser_next_token_is (parser, CPP_NAME)
   20913         1799 :       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   20914              :     {
   20915         1480 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   20916         1480 :       int always_present_modifier = always_modifier && present_modifier;
   20917              : 
   20918         1480 :       if (strcmp ("alloc", p) == 0)
   20919          128 :         kind = present_modifier ? GOMP_MAP_PRESENT_ALLOC : GOMP_MAP_ALLOC;
   20920         1352 :       else if (strcmp ("to", p) == 0)
   20921          879 :         kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TO
   20922          451 :                 : present_modifier ? GOMP_MAP_PRESENT_TO
   20923          443 :                 : always_modifier ? GOMP_MAP_ALWAYS_TO
   20924              :                 : GOMP_MAP_TO);
   20925          896 :       else if (strcmp ("from", p) == 0)
   20926         1106 :         kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_FROM
   20927          555 :                 : present_modifier ? GOMP_MAP_PRESENT_FROM
   20928          552 :                 : always_modifier ? GOMP_MAP_ALWAYS_FROM
   20929              :                 : GOMP_MAP_FROM);
   20930          336 :       else if (strcmp ("tofrom", p) == 0)
   20931          545 :         kind = (always_present_modifier ? GOMP_MAP_ALWAYS_PRESENT_TOFROM
   20932          280 :                 : present_modifier ? GOMP_MAP_PRESENT_TOFROM
   20933          274 :                 : always_modifier ? GOMP_MAP_ALWAYS_TOFROM
   20934              :                 : GOMP_MAP_TOFROM);
   20935           50 :       else if (strcmp ("release", p) == 0)
   20936              :         kind = GOMP_MAP_RELEASE;
   20937           15 :       else if (strcmp ("delete", p) == 0)
   20938              :         kind = GOMP_MAP_DELETE;
   20939              :       else
   20940              :         {
   20941            0 :           c_parser_error (parser, "invalid map kind");
   20942            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   20943              :                                      "expected %<)%>");
   20944            0 :           return list;
   20945              :         }
   20946         1480 :       c_parser_consume_token (parser);
   20947         1480 :       c_parser_consume_token (parser);
   20948              :     }
   20949              : 
   20950         1799 :   nl = c_parser_omp_variable_list (parser, clause_loc, OMP_CLAUSE_MAP, list,
   20951              :                                    true);
   20952              : 
   20953         1799 :   tree last_new = NULL_TREE;
   20954              : 
   20955         1799 :   if (iterators)
   20956              :     {
   20957           14 :       tree block = pop_scope ();
   20958           14 :       if (iterators == error_mark_node)
   20959              :         iterators = NULL_TREE;
   20960              :       else
   20961           14 :         TREE_VEC_ELT (iterators, 5) = block;
   20962              :     }
   20963              : 
   20964         4008 :   for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   20965              :     {
   20966         2209 :       OMP_CLAUSE_SET_MAP_KIND (c, kind);
   20967         2209 :       OMP_CLAUSE_ITERATORS (c) = iterators;
   20968         2209 :       last_new = c;
   20969              :     }
   20970              : 
   20971         1799 :   if (mapper_name)
   20972              :     {
   20973            5 :       tree name = build_omp_clause (input_location, OMP_CLAUSE_MAP);
   20974            5 :       OMP_CLAUSE_SET_MAP_KIND (name, GOMP_MAP_PUSH_MAPPER_NAME);
   20975            5 :       OMP_CLAUSE_DECL (name) = mapper_name;
   20976            5 :       OMP_CLAUSE_CHAIN (name) = nl;
   20977            5 :       nl = name;
   20978              : 
   20979            5 :       gcc_assert (last_new);
   20980              : 
   20981            5 :       name = build_omp_clause (input_location, OMP_CLAUSE_MAP);
   20982            5 :       OMP_CLAUSE_SET_MAP_KIND (name, GOMP_MAP_POP_MAPPER_NAME);
   20983            5 :       OMP_CLAUSE_DECL (name) = null_pointer_node;
   20984            5 :       OMP_CLAUSE_CHAIN (name) = OMP_CLAUSE_CHAIN (last_new);
   20985            5 :       OMP_CLAUSE_CHAIN (last_new) = name;
   20986              :     }
   20987              : 
   20988         1799 :   parens.skip_until_found_close (parser);
   20989         1799 :   return nl;
   20990              : }
   20991              : 
   20992              : /* OpenMP 4.0:
   20993              :    device ( expression )
   20994              : 
   20995              :    OpenMP 5.0:
   20996              :    device ( [device-modifier :] integer-expression )
   20997              : 
   20998              :    device-modifier:
   20999              :      ancestor | device_num */
   21000              : 
   21001              : static tree
   21002          369 : c_parser_omp_clause_device (c_parser *parser, tree list)
   21003              : {
   21004          369 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   21005          369 :   location_t expr_loc;
   21006          369 :   c_expr expr;
   21007          369 :   tree c, t;
   21008          369 :   bool ancestor = false;
   21009              : 
   21010          369 :   matching_parens parens;
   21011          369 :   if (!parens.require_open (parser))
   21012              :     return list;
   21013              : 
   21014          369 :   if (c_parser_next_token_is (parser, CPP_NAME)
   21015          369 :       && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   21016              :     {
   21017           48 :       c_token *tok = c_parser_peek_token (parser);
   21018           48 :       const char *p = IDENTIFIER_POINTER (tok->value);
   21019           48 :       if (strcmp ("ancestor", p) == 0)
   21020              :         {
   21021              :           /* A requires directive with the reverse_offload clause must be
   21022              :           specified.  */
   21023           25 :           if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
   21024              :             {
   21025            1 :               error_at (tok->location, "%<ancestor%> device modifier not "
   21026              :                                        "preceded by %<requires%> directive "
   21027              :                                        "with %<reverse_offload%> clause");
   21028            1 :               parens.skip_until_found_close (parser);
   21029            1 :               return list;
   21030              :             }
   21031              :           ancestor = true;
   21032              :         }
   21033           23 :       else if (strcmp ("device_num", p) == 0)
   21034              :         ;
   21035              :       else
   21036              :         {
   21037            1 :           error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
   21038            1 :           parens.skip_until_found_close (parser);
   21039            1 :           return list;
   21040              :         }
   21041           46 :       c_parser_consume_token (parser);
   21042           46 :       c_parser_consume_token (parser);
   21043              :     }
   21044              : 
   21045          367 :   expr_loc = c_parser_peek_token (parser)->location;
   21046          367 :   expr = c_parser_expr_no_commas (parser, NULL);
   21047          367 :   expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   21048          367 :   t = expr.value;
   21049          367 :   t = c_fully_fold (t, false, NULL);
   21050              : 
   21051          367 :   parens.skip_until_found_close (parser);
   21052              : 
   21053          367 :   if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   21054              :     {
   21055            2 :       c_parser_error (parser, "expected integer expression");
   21056            2 :       return list;
   21057              :     }
   21058          365 :   if (ancestor && TREE_CODE (t) == INTEGER_CST && !integer_onep (t))
   21059              :     {
   21060            1 :       error_at (expr_loc, "the %<device%> clause expression must evaluate to "
   21061              :                           "%<1%>");
   21062            1 :       return list;
   21063              :     }
   21064              : 
   21065          364 :   check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE, "device");
   21066              : 
   21067          364 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE);
   21068              : 
   21069          364 :   OMP_CLAUSE_DEVICE_ID (c) = t;
   21070          364 :   OMP_CLAUSE_CHAIN (c) = list;
   21071          364 :   OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;
   21072              : 
   21073          364 :   list = c;
   21074          364 :   return list;
   21075              : }
   21076              : 
   21077              : /* OpenMP 4.0:
   21078              :    dist_schedule ( static )
   21079              :    dist_schedule ( static , expression ) */
   21080              : 
   21081              : static tree
   21082         1582 : c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
   21083              : {
   21084         1582 :   tree c, t = NULL_TREE;
   21085         1582 :   location_t loc = c_parser_peek_token (parser)->location;
   21086              : 
   21087         1582 :   matching_parens parens;
   21088         1582 :   if (!parens.require_open (parser))
   21089              :     return list;
   21090              : 
   21091         1582 :   if (!c_parser_next_token_is_keyword (parser, RID_STATIC))
   21092              :     {
   21093            0 :       c_parser_error (parser, "invalid dist_schedule kind");
   21094            0 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   21095              :                                  "expected %<)%>");
   21096            0 :       return list;
   21097              :     }
   21098              : 
   21099         1582 :   c_parser_consume_token (parser);
   21100         1582 :   if (c_parser_next_token_is (parser, CPP_COMMA))
   21101              :     {
   21102         1575 :       c_parser_consume_token (parser);
   21103              : 
   21104         1575 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   21105         1575 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   21106         1575 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   21107         1575 :       t = expr.value;
   21108         1575 :       t = c_fully_fold (t, false, NULL);
   21109         1575 :       parens.skip_until_found_close (parser);
   21110              :     }
   21111              :   else
   21112            7 :     c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   21113              :                                "expected %<,%> or %<)%>");
   21114              : 
   21115              :   /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
   21116              :                                 "dist_schedule"); */
   21117         1582 :   if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
   21118            2 :     warning_at (loc, OPT_Wopenmp, "too many %qs clauses", "dist_schedule");
   21119         1582 :   if (t == error_mark_node)
   21120              :     return list;
   21121              : 
   21122         1582 :   c = build_omp_clause (loc, OMP_CLAUSE_DIST_SCHEDULE);
   21123         1582 :   OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;
   21124         1582 :   OMP_CLAUSE_CHAIN (c) = list;
   21125         1582 :   return c;
   21126              : }
   21127              : 
   21128              : /* OpenMP 4.0:
   21129              :    proc_bind ( proc-bind-kind )
   21130              : 
   21131              :    proc-bind-kind:
   21132              :      primary | master | close | spread
   21133              :    where OpenMP 5.1 added 'primary' and deprecated the alias 'master'.  */
   21134              : 
   21135              : static tree
   21136          195 : c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
   21137              : {
   21138          195 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   21139          195 :   enum omp_clause_proc_bind_kind kind;
   21140          195 :   tree c;
   21141              : 
   21142          195 :   matching_parens parens;
   21143          195 :   if (!parens.require_open (parser))
   21144              :     return list;
   21145              : 
   21146          195 :   if (c_parser_next_token_is (parser, CPP_NAME))
   21147              :     {
   21148          195 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   21149          195 :       if (strcmp ("primary", p) == 0)
   21150              :         kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
   21151          194 :       else if (strcmp ("master", p) == 0)
   21152              :         {
   21153           17 :           gcc_rich_location richloc (clause_loc);
   21154           17 :           richloc.add_fixit_replace (c_parser_peek_token (parser)->location,
   21155              :                                      "primary");
   21156           17 :           warning_at (&richloc, OPT_Wdeprecated_openmp,
   21157              :                       "%<master%> affinity deprecated since OpenMP 5.1, "
   21158              :                       "use %<primary%>");
   21159           17 :           kind = OMP_CLAUSE_PROC_BIND_MASTER;
   21160           17 :         }
   21161          177 :       else if (strcmp ("close", p) == 0)
   21162              :         kind = OMP_CLAUSE_PROC_BIND_CLOSE;
   21163          165 :       else if (strcmp ("spread", p) == 0)
   21164              :         kind = OMP_CLAUSE_PROC_BIND_SPREAD;
   21165              :       else
   21166            0 :         goto invalid_kind;
   21167              :     }
   21168              :   else
   21169            0 :     goto invalid_kind;
   21170              : 
   21171          195 :   check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
   21172          195 :   c_parser_consume_token (parser);
   21173          195 :   parens.skip_until_found_close (parser);
   21174          195 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
   21175          195 :   OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
   21176          195 :   OMP_CLAUSE_CHAIN (c) = list;
   21177          195 :   return c;
   21178              : 
   21179            0 :  invalid_kind:
   21180            0 :   c_parser_error (parser, "invalid proc_bind kind");
   21181            0 :   parens.skip_until_found_close (parser);
   21182            0 :   return list;
   21183              : }
   21184              : 
   21185              : /* OpenMP 5.0:
   21186              :    device_type ( host | nohost | any )  */
   21187              : 
   21188              : static tree
   21189           51 : c_parser_omp_clause_device_type (c_parser *parser, tree list)
   21190              : {
   21191           51 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   21192           51 :   enum omp_clause_device_type_kind kind;
   21193           51 :   tree c;
   21194              : 
   21195           51 :   matching_parens parens;
   21196           51 :   if (!parens.require_open (parser))
   21197              :     return list;
   21198              : 
   21199           51 :   if (c_parser_next_token_is (parser, CPP_NAME))
   21200              :     {
   21201           51 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   21202           51 :       if (strcmp ("host", p) == 0)
   21203              :         kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
   21204           32 :       else if (strcmp ("nohost", p) == 0)
   21205              :         kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
   21206           20 :       else if (strcmp ("any", p) == 0)
   21207              :         kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
   21208              :       else
   21209            0 :         goto invalid_kind;
   21210              :     }
   21211              :   else
   21212            0 :     goto invalid_kind;
   21213              : 
   21214           51 :   check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
   21215              :                              "device_type");
   21216           51 :   c_parser_consume_token (parser);
   21217           51 :   parens.skip_until_found_close (parser);
   21218           51 :   c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
   21219           51 :   OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
   21220           51 :   OMP_CLAUSE_CHAIN (c) = list;
   21221           51 :   return c;
   21222              : 
   21223            0 :  invalid_kind:
   21224            0 :   c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
   21225            0 :   parens.skip_until_found_close (parser);
   21226            0 :   return list;
   21227              : }
   21228              : 
   21229              : /* OpenMP 4.0:
   21230              :    from ( variable-list )
   21231              :    to ( variable-list )
   21232              : 
   21233              :    OpenMP 5.1:
   21234              :    from ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list )
   21235              :    to ( [motion-modifier[,] [motion-modifier[,]...]:] variable-list )
   21236              : 
   21237              :    motion-modifier:
   21238              :      present | iterator (iterators-definition)  */
   21239              : 
   21240              : static tree
   21241         2842 : c_parser_omp_clause_from_to (c_parser *parser, enum omp_clause_code kind,
   21242              :                              tree list)
   21243              : {
   21244         2842 :   location_t loc = c_parser_peek_token (parser)->location;
   21245         2842 :   matching_parens parens;
   21246         2842 :   if (!parens.require_open (parser))
   21247              :     return list;
   21248              : 
   21249         5676 :   int pos = 1, colon_pos = 0;
   21250              :   int iterator_length = 0;
   21251              : 
   21252         5676 :   while (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_NAME)
   21253              :     {
   21254         2850 :       const char *identifier =
   21255         2850 :         IDENTIFIER_POINTER (c_parser_peek_nth_token_raw (parser, pos)->value);
   21256         2850 :       if (c_parser_peek_nth_token_raw (parser, pos + 1)->type
   21257              :           == CPP_OPEN_PAREN)
   21258              :         {
   21259           12 :           unsigned int npos = pos + 2;
   21260           12 :           if (c_parser_check_balanced_raw_token_sequence (parser, &npos)
   21261           12 :               && (c_parser_peek_nth_token_raw (parser, npos)->type
   21262              :                   == CPP_CLOSE_PAREN))
   21263              :             {
   21264           12 :               if (strcmp (identifier, "iterator") == 0)
   21265           12 :                 iterator_length = npos - pos + 1;
   21266           12 :               pos = npos;
   21267              :             }
   21268              :         }
   21269         2850 :       if (c_parser_peek_nth_token_raw (parser, pos + 1)->type == CPP_COMMA)
   21270            8 :         pos += 2;
   21271              :       else
   21272              :         pos++;
   21273         2850 :       if (c_parser_peek_nth_token_raw (parser, pos)->type == CPP_COLON)
   21274              :         {
   21275              :           colon_pos = pos;
   21276              :           break;
   21277              :         }
   21278              :     }
   21279              : 
   21280         2842 :   bool present = false;
   21281         2842 :   tree iterators = NULL_TREE;
   21282              : 
   21283         2862 :   for (int pos = 1; pos < colon_pos; ++pos)
   21284              :     {
   21285           22 :       c_token *token = c_parser_peek_token (parser);
   21286           22 :       if (token->type == CPP_COMMA)
   21287              :         {
   21288            3 :           c_parser_consume_token (parser);
   21289            3 :           continue;
   21290              :         }
   21291           19 :       const char *p = IDENTIFIER_POINTER (token->value);
   21292           19 :       if (strcmp ("present", p) == 0)
   21293              :         {
   21294            6 :           if (present)
   21295              :             {
   21296            0 :               c_parser_error (parser, "too many %<present%> modifiers");
   21297            0 :               parens.skip_until_found_close (parser);
   21298            0 :               return list;
   21299              :             }
   21300            6 :           present = true;
   21301            6 :           c_parser_consume_token (parser);
   21302              :         }
   21303           13 :       else if (strcmp ("iterator", p) == 0)
   21304              :         {
   21305           12 :           if (iterators)
   21306              :             {
   21307            1 :               c_parser_error (parser, "too many %<iterator%> modifiers");
   21308            1 :               parens.skip_until_found_close (parser);
   21309            1 :               return list;
   21310              :             }
   21311           11 :           iterators = c_parser_omp_iterators (parser);
   21312           11 :           pos += iterator_length - 1;
   21313              :         }
   21314              :       else
   21315              :         {
   21316            2 :           error_at (token->location,
   21317              :                     "%qs clause with modifier other than %<iterator%> or "
   21318              :                     "%<present%>",
   21319              :                     kind == OMP_CLAUSE_TO ? "to" : "from");
   21320            1 :           parens.skip_until_found_close (parser);
   21321            1 :           return list;
   21322              :         }
   21323              :     }
   21324              : 
   21325         2840 :   if (colon_pos)
   21326           14 :     c_parser_require (parser, CPP_COLON, "expected %<:%>");
   21327              : 
   21328         2840 :   tree nl = c_parser_omp_variable_list (parser, loc, kind, list);
   21329         2840 :   parens.skip_until_found_close (parser);
   21330              : 
   21331         2840 :   if (present)
   21332           12 :     for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   21333            6 :       OMP_CLAUSE_MOTION_PRESENT (c) = 1;
   21334              : 
   21335         2840 :   if (iterators)
   21336              :     {
   21337            9 :       tree block = pop_scope ();
   21338            9 :       if (iterators == error_mark_node)
   21339              :         iterators = NULL_TREE;
   21340              :       else
   21341            9 :         TREE_VEC_ELT (iterators, 5) = block;
   21342              :     }
   21343              : 
   21344            9 :   if (iterators)
   21345           22 :     for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   21346           13 :       OMP_CLAUSE_ITERATORS (c) = iterators;
   21347              : 
   21348              :   return nl;
   21349              : }
   21350              : 
   21351              : /* OpenMP 4.0:
   21352              :    uniform ( variable-list ) */
   21353              : 
   21354              : static tree
   21355          115 : c_parser_omp_clause_uniform (c_parser *parser, tree list)
   21356              : {
   21357              :   /* The clauses location.  */
   21358          115 :   location_t loc = c_parser_peek_token (parser)->location;
   21359              : 
   21360          115 :   matching_parens parens;
   21361          115 :   if (parens.require_open (parser))
   21362              :     {
   21363          115 :       list = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_UNIFORM,
   21364              :                                          list);
   21365          115 :       parens.skip_until_found_close (parser);
   21366              :     }
   21367          115 :   return list;
   21368              : }
   21369              : 
   21370              : /* OpenMP 5.1
   21371              :    full */
   21372              : 
   21373              : static tree
   21374           69 : c_parser_omp_clause_full (c_parser *parser, tree list)
   21375              : {
   21376           69 :   check_no_duplicate_clause (list, OMP_CLAUSE_FULL, "full");
   21377              : 
   21378           69 :   location_t loc = c_parser_peek_token (parser)->location;
   21379           69 :   tree c = build_omp_clause (loc, OMP_CLAUSE_FULL);
   21380           69 :   OMP_CLAUSE_CHAIN (c) = list;
   21381           69 :   return c;
   21382              : }
   21383              : 
   21384              : /* OpenMP 5.1
   21385              :    partial ( constant-expression ) */
   21386              : 
   21387              : static tree
   21388          230 : c_parser_omp_clause_partial (c_parser *parser, tree list)
   21389              : {
   21390          230 :   tree num = NULL_TREE;
   21391          230 :   location_t loc = c_parser_peek_token (parser)->location;
   21392              : 
   21393          230 :   check_no_duplicate_clause (list, OMP_CLAUSE_PARTIAL, "partial");
   21394              : 
   21395          230 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   21396              :     {
   21397          173 :       matching_parens parens;
   21398          173 :       parens.consume_open (parser);
   21399          173 :       num = c_parser_expr_no_commas (parser, NULL).value;
   21400          173 :       parens.skip_until_found_close (parser);
   21401              : 
   21402          173 :       if (num == error_mark_node)
   21403            7 :         return list;
   21404              : 
   21405          171 :       mark_exp_read (num);
   21406          171 :       num = c_fully_fold (num, false, NULL);
   21407          171 :       HOST_WIDE_INT n;
   21408          342 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (num))
   21409          170 :           || !tree_fits_shwi_p (num)
   21410          168 :           || (n = tree_to_shwi (num)) <= 0
   21411          337 :           || (int) n != n)
   21412              :         {
   21413            5 :           error_at (loc, "%<partial%> argument needs positive constant "
   21414              :                          "integer expression");
   21415            5 :           return list;
   21416              :         }
   21417              :     }
   21418              : 
   21419          223 :   tree c = build_omp_clause (loc, OMP_CLAUSE_PARTIAL);
   21420          223 :   OMP_CLAUSE_PARTIAL_EXPR (c) = num;
   21421          223 :   OMP_CLAUSE_CHAIN (c) = list;
   21422          223 :   return c;
   21423              : }
   21424              : 
   21425              : /* OpenMP 5.1
   21426              :    novariants ( scalar-expression ) */
   21427              : 
   21428              : static tree
   21429           24 : c_parser_omp_clause_novariants (c_parser *parser, tree list)
   21430              : {
   21431           24 :   matching_parens parens;
   21432           24 :   if (!parens.require_open (parser))
   21433              :     return list;
   21434              : 
   21435           24 :   location_t loc = c_parser_peek_token (parser)->location;
   21436           24 :   c_expr expr = c_parser_expr_no_commas (parser, NULL);
   21437           24 :   tree t = convert_lvalue_to_rvalue (loc, expr, true, true).value;
   21438           24 :   t = c_objc_common_truthvalue_conversion (loc, t);
   21439           24 :   t = c_fully_fold (t, false, NULL);
   21440           24 :   parens.skip_until_found_close (parser);
   21441              : 
   21442           24 :   check_no_duplicate_clause (list, OMP_CLAUSE_NOVARIANTS, "novariants");
   21443              : 
   21444           24 :   tree c = build_omp_clause (loc, OMP_CLAUSE_NOVARIANTS);
   21445           24 :   OMP_CLAUSE_NOVARIANTS_EXPR (c) = t;
   21446           24 :   OMP_CLAUSE_CHAIN (c) = list;
   21447           24 :   list = c;
   21448              : 
   21449           24 :   return list;
   21450              : }
   21451              : 
   21452              : /* OpenMP 5.1
   21453              :    nocontext ( scalar-expression ) */
   21454              : 
   21455              : static tree
   21456           23 : c_parser_omp_clause_nocontext (c_parser *parser, tree list)
   21457              : {
   21458           23 :   matching_parens parens;
   21459           23 :   if (!parens.require_open (parser))
   21460              :     return list;
   21461              : 
   21462           23 :   location_t loc = c_parser_peek_token (parser)->location;
   21463           23 :   c_expr expr = c_parser_expr_no_commas (parser, NULL);
   21464           23 :   tree t = convert_lvalue_to_rvalue (loc, expr, true, true).value;
   21465           23 :   t = c_objc_common_truthvalue_conversion (loc, t);
   21466           23 :   t = c_fully_fold (t, false, NULL);
   21467           23 :   parens.skip_until_found_close (parser);
   21468              : 
   21469           23 :   check_no_duplicate_clause (list, OMP_CLAUSE_NOCONTEXT, "nocontext");
   21470              : 
   21471           23 :   tree c = build_omp_clause (loc, OMP_CLAUSE_NOCONTEXT);
   21472           23 :   OMP_CLAUSE_NOCONTEXT_EXPR (c) = t;
   21473           23 :   OMP_CLAUSE_CHAIN (c) = list;
   21474           23 :   list = c;
   21475              : 
   21476           23 :   return list;
   21477              : }
   21478              : 
   21479              : /* OpenMP 5.0:
   21480              :    detach ( event-handle ) */
   21481              : 
   21482              : static tree
   21483           34 : c_parser_omp_clause_detach (c_parser *parser, tree list)
   21484              : {
   21485           34 :   matching_parens parens;
   21486           34 :   location_t clause_loc = c_parser_peek_token (parser)->location;
   21487              : 
   21488           34 :   if (!parens.require_open (parser))
   21489              :     return list;
   21490              : 
   21491           34 :   if (c_parser_next_token_is_not (parser, CPP_NAME)
   21492           34 :       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
   21493              :     {
   21494            1 :       c_parser_error (parser, "expected identifier");
   21495            1 :       parens.skip_until_found_close (parser);
   21496            1 :       return list;
   21497              :     }
   21498              : 
   21499           33 :   tree t = lookup_name (c_parser_peek_token (parser)->value);
   21500           33 :   if (t == NULL_TREE)
   21501              :     {
   21502            0 :       undeclared_variable (c_parser_peek_token (parser)->location,
   21503            0 :                            c_parser_peek_token (parser)->value);
   21504            0 :       parens.skip_until_found_close (parser);
   21505            0 :       return list;
   21506              :     }
   21507           33 :   c_parser_consume_token (parser);
   21508              : 
   21509           33 :   tree type = TYPE_MAIN_VARIANT (TREE_TYPE (t));
   21510           33 :   if (!INTEGRAL_TYPE_P (type)
   21511              :       || TREE_CODE (type) != ENUMERAL_TYPE
   21512           33 :       || TYPE_NAME (type) != get_identifier ("omp_event_handle_t"))
   21513              :     {
   21514            1 :       error_at (clause_loc, "%<detach%> clause event handle "
   21515              :                             "has type %qT rather than "
   21516              :                             "%<omp_event_handle_t%>",
   21517              :                             type);
   21518            1 :       parens.skip_until_found_close (parser);
   21519            1 :       return list;
   21520              :     }
   21521              : 
   21522           32 :   tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DETACH);
   21523           32 :   OMP_CLAUSE_DECL (u) = t;
   21524           32 :   OMP_CLAUSE_CHAIN (u) = list;
   21525           32 :   parens.skip_until_found_close (parser);
   21526           32 :   return u;
   21527              : }
   21528              : 
   21529              : /* OpenMP 5.0:
   21530              :    destroy ( variable-list ) */
   21531              : 
   21532              : static tree
   21533           41 : c_parser_omp_clause_destroy (c_parser *parser, tree list)
   21534              : {
   21535           41 :   tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_DESTROY, list);
   21536           86 :   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   21537           45 :     TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1;
   21538           41 :   return nl;
   21539              : }
   21540              : 
   21541              : /* OpenMP 5.1:
   21542              :      prefer_type ( const-int-expr-or-string-literal-list )
   21543              : 
   21544              :    OpenMP 6.0:
   21545              :      prefer_type ( { preference-selector-list }, { ... } )
   21546              : 
   21547              :    with preference-selector being:
   21548              :      fr ( identifier-or-string-literal-list )
   21549              :      attr ( string-list )
   21550              : 
   21551              :    Data format:
   21552              :     For the foreign runtime identifiers, string values are converted to
   21553              :     their integer value; unknown string or integer values are set to
   21554              :     GOMP_INTEROP_IFR_KNOWN.
   21555              : 
   21556              :     Each item (a) GOMP_INTEROP_IFR_SEPARATOR
   21557              :               (b) for any 'fr', its integer value.
   21558              :                   Note: Spec only permits 1 'fr' entry (6.0; changed after TR13)
   21559              :               (c) GOMP_INTEROP_IFR_SEPARATOR
   21560              :               (d) list of \0-terminated non-empty strings for 'attr'
   21561              :               (e) '\0'
   21562              :     Tailing '\0'.  */
   21563              : 
   21564              : static tree
   21565          125 : c_parser_omp_modifier_prefer_type (c_parser *parser)
   21566              : {
   21567          125 :   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   21568            2 :     return error_mark_node;
   21569              : 
   21570          123 :   std::string str;
   21571              : 
   21572              :   /* Old Format: const-int-expr-or-string-literal-list */
   21573          123 :   if (!c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   21574          240 :     while (true)
   21575              :       {
   21576          150 :         str += (char) GOMP_INTEROP_IFR_SEPARATOR;
   21577          150 :         if (c_parser_next_token_is (parser, CPP_STRING))
   21578              :           {
   21579          117 :             c_expr cval = c_parser_string_literal (parser, false, false);
   21580          117 :             if (cval.value == error_mark_node)
   21581            1 :               return error_mark_node;
   21582          117 :             if ((size_t) TREE_STRING_LENGTH (cval.value)
   21583          117 :                 != strlen (TREE_STRING_POINTER (cval.value)) + 1)
   21584              :               {
   21585            1 :                 error_at (cval.get_location (), "string literal must "
   21586              :                                                 "not contain %<\\0%>");
   21587            1 :                 parser->error = true;
   21588            1 :                 return error_mark_node;
   21589              :               }
   21590              : 
   21591          116 :             char c = omp_get_fr_id_from_name (TREE_STRING_POINTER (cval.value));
   21592          116 :             if (c == GOMP_INTEROP_IFR_UNKNOWN)
   21593            3 :               warning_at (cval.get_location (), OPT_Wopenmp,
   21594              :                           "unknown foreign runtime identifier %qs",
   21595            3 :                           TREE_STRING_POINTER (cval.value));
   21596          116 :             str += c;
   21597              :           }
   21598              :         else
   21599              :           {
   21600           33 :             c_expr cval = c_parser_expr_no_commas (parser, NULL);
   21601           33 :             tree value = c_fully_fold (cval.value, false, NULL);
   21602           64 :             if (INTEGRAL_TYPE_P (TREE_TYPE (value))
   21603           61 :                 && TREE_CODE (value) != INTEGER_CST)
   21604            3 :               value = convert_lvalue_to_rvalue (cval.get_start (), cval,
   21605              :                                                 false, true).value;
   21606           33 :             if (TREE_CODE (value) != INTEGER_CST
   21607           28 :                 || !tree_fits_shwi_p (value))
   21608              :               {
   21609            5 :                 c_parser_error (parser, "expected string literal or constant "
   21610              :                                         "integer expression");
   21611            5 :                 return error_mark_node;
   21612              :               }
   21613           28 :             HOST_WIDE_INT n = tree_to_shwi (value);
   21614           28 :             if (n < 1 || n > GOMP_INTEROP_IFR_LAST)
   21615              :               {
   21616            3 :                 warning_at (cval.get_location (), OPT_Wopenmp,
   21617              :                             "unknown foreign runtime identifier %qwd", n);
   21618            3 :                 n = GOMP_INTEROP_IFR_UNKNOWN;
   21619              :               }
   21620           28 :             str += (char) n;
   21621              :           }
   21622          144 :         str += (char) GOMP_INTEROP_IFR_SEPARATOR;
   21623          144 :         str += '\0';
   21624          144 :         if (c_parser_next_token_is (parser, CPP_COMMA))
   21625              :           {
   21626           90 :             c_parser_consume_token (parser);
   21627           90 :             continue;
   21628              :           }
   21629           54 :         if (!c_parser_require (parser, CPP_CLOSE_PAREN,
   21630              :                                "expected %<,%> or %<)%>"))
   21631            0 :           return error_mark_node;
   21632           54 :         str += '\0';
   21633           54 :         tree res = build_string (str.length (), str.data ());
   21634           54 :         TREE_TYPE (res) = build_array_type_nelts (unsigned_char_type_node,
   21635           54 :                                                   str.length ());
   21636           54 :         return res;
   21637           90 :       }
   21638              : 
   21639              :   /* New format. */
   21640           63 :   std::string str2;
   21641          128 :   while (true)
   21642              :     {
   21643          128 :       if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   21644            1 :         return error_mark_node;
   21645          127 :       str += (char) GOMP_INTEROP_IFR_SEPARATOR;
   21646          127 :       str2.clear ();
   21647          127 :       bool has_fr = false;
   21648          205 :       while (true)
   21649              :         {
   21650          166 :           c_token *tok = c_parser_peek_token (parser);
   21651          166 :           if (tok->type != CPP_NAME
   21652          166 :               || (strcmp("fr", IDENTIFIER_POINTER (tok->value)) != 0
   21653           63 :                   && strcmp("attr", IDENTIFIER_POINTER (tok->value)) != 0))
   21654              :             {
   21655            0 :               c_parser_error (parser, "expected %<fr%> or %<attr%> preference "
   21656              :                                       "selector");
   21657            0 :               return error_mark_node;
   21658              :             }
   21659          166 :           c_parser_consume_token (parser);
   21660          166 :           bool is_fr = IDENTIFIER_POINTER (tok->value)[0] == 'f';
   21661          166 :           if (is_fr && has_fr)
   21662              :             {
   21663            1 :               c_parser_error (parser, "duplicated %<fr%> preference selector");
   21664            1 :               return error_mark_node;
   21665              :             }
   21666          165 :           if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   21667            0 :             return error_mark_node;
   21668          175 :           while (true)
   21669              :             {
   21670          170 :               if (c_parser_next_token_is (parser, CPP_STRING))
   21671              :                 {
   21672          133 :                   c_expr cval = c_parser_string_literal (parser, false, false);
   21673          133 :                   tree value = cval.value;
   21674          133 :                   if (value == error_mark_node)
   21675            6 :                     return error_mark_node;
   21676          133 :                   if ((size_t) TREE_STRING_LENGTH (value)
   21677          133 :                       != strlen (TREE_STRING_POINTER (value)) + 1)
   21678              :                     {
   21679            2 :                       error_at (cval.get_location (), "string literal must "
   21680              :                                                       "not contain %<\\0%>");
   21681            2 :                       parser->error = true;
   21682            2 :                       return error_mark_node;
   21683              :                     }
   21684          131 :                   if (!is_fr)
   21685              :                     {
   21686           67 :                       if (!startswith (TREE_STRING_POINTER (value), "ompx_"))
   21687              :                         {
   21688            1 :                           error_at (cval.get_location (),
   21689              :                                     "%<attr%> string literal must start with "
   21690              :                                     "%<ompx_%>");
   21691            1 :                           parser->error = true;
   21692            1 :                           return error_mark_node;
   21693              :                         }
   21694           66 :                       if (strchr (TREE_STRING_POINTER (value), ','))
   21695              :                         {
   21696            2 :                           error_at (cval.get_location (),
   21697              :                                     "%<attr%> string literal must not contain "
   21698              :                                     "a comma");
   21699            2 :                           parser->error = true;
   21700            2 :                           return error_mark_node;
   21701              :                         }
   21702           64 :                       str2 += TREE_STRING_POINTER (value);
   21703           64 :                       str2 += '\0';
   21704              :                     }
   21705              :                   else
   21706              :                     {
   21707           64 :                       if (*TREE_STRING_POINTER (value) == '\0')
   21708              :                         {
   21709            1 :                           c_parser_error (parser, "non-empty string literal expected");
   21710            1 :                           return error_mark_node;
   21711              :                         }
   21712           63 :                       char c = omp_get_fr_id_from_name (TREE_STRING_POINTER (value));
   21713           63 :                       if (c == GOMP_INTEROP_IFR_UNKNOWN)
   21714            3 :                         warning_at (cval.get_location (), OPT_Wopenmp,
   21715              :                                     "unknown foreign runtime identifier %qs",
   21716            3 :                                     TREE_STRING_POINTER (value));
   21717           63 :                      str += c;
   21718           63 :                      has_fr = true;
   21719              :                     }
   21720              :                 }
   21721           37 :               else if (!is_fr)
   21722              :                 {
   21723            1 :                   c_parser_error (parser, "expected string literal");
   21724            1 :                   return error_mark_node;
   21725              :                 }
   21726              :               else
   21727              :                 {
   21728           36 :                   c_expr cval = c_parser_expr_no_commas (parser, NULL);
   21729           36 :                   tree value = c_fully_fold (cval.value, false, NULL);
   21730           70 :                   if (INTEGRAL_TYPE_P (TREE_TYPE (value))
   21731           68 :                       && TREE_CODE (value) != INTEGER_CST)
   21732            3 :                     value = convert_lvalue_to_rvalue (cval.get_start (), cval,
   21733              :                                                       false, true).value;
   21734              : 
   21735           36 :                   if (TREE_CODE (value) != INTEGER_CST
   21736           32 :                       || !tree_fits_shwi_p (value))
   21737              :                     {
   21738            4 :                       c_parser_error (parser, "expected string literal or "
   21739              :                                               "constant integer expression");
   21740            4 :                       return error_mark_node;
   21741              :                     }
   21742           32 :                   HOST_WIDE_INT n = tree_to_shwi (value);
   21743           32 :                   if (n < 1 || n > GOMP_INTEROP_IFR_LAST)
   21744              :                     {
   21745            0 :                       warning_at (cval.get_location (), OPT_Wopenmp,
   21746              :                                   "unknown foreign runtime identifier %qwd", n);
   21747            0 :                       n = GOMP_INTEROP_IFR_UNKNOWN;
   21748              :                     }
   21749           32 :                   str += (char) n;
   21750           32 :                   has_fr = true;
   21751              :                 }
   21752          164 :               if (!is_fr
   21753          223 :                   && c_parser_next_token_is (parser, CPP_COMMA))
   21754              :                 {
   21755            5 :                   c_parser_consume_token (parser);
   21756            5 :                   continue;
   21757              :                 }
   21758          213 :               if (!c_parser_require (parser, CPP_CLOSE_PAREN,
   21759              :                                      is_fr ? G_("expected %<)%>")
   21760              :                                            : G_("expected %<)%> or %<,%>")))
   21761            4 :                 return error_mark_node;
   21762          150 :               break;
   21763            5 :             }
   21764          150 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   21765              :             {
   21766           39 :               c_parser_consume_token (parser);
   21767           39 :               continue;
   21768              :             }
   21769          111 :           if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   21770              :             break;
   21771            2 :           c_parser_error (parser, "expected %<,%> or %<}%>");
   21772            2 :           return error_mark_node;
   21773           39 :         }
   21774          109 :       str += (char) GOMP_INTEROP_IFR_SEPARATOR;
   21775          109 :       str += str2;
   21776          109 :       str += '\0';
   21777          109 :       c_parser_consume_token (parser);
   21778          109 :       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   21779              :         break;
   21780           66 :       if (!c_parser_require (parser, CPP_COMMA, "expected %<)%> or %<,%>"))
   21781            1 :         return error_mark_node;
   21782              :     }
   21783           43 :   c_parser_consume_token (parser);
   21784           43 :   str += '\0';
   21785           43 :   tree res = build_string (str.length (), str.data ());
   21786           43 :   TREE_TYPE (res) = build_array_type_nelts (unsigned_char_type_node,
   21787           43 :                                                   str.length ());
   21788           43 :   return res;
   21789          186 : }
   21790              : 
   21791              : /* OpenMP 5.1
   21792              :      modifiers of the 'init' clause, used by the 'init' and the
   21793              :      'append_args' clauses.
   21794              : 
   21795              :    Modifiers:
   21796              :      target
   21797              :      targetsync
   21798              :      prefer_type (preference-specification)
   21799              : 
   21800              :   Returns 'false' if an error has been issued.  */
   21801              : 
   21802              : static bool
   21803          234 : c_parser_omp_clause_init_modifiers (c_parser *parser, bool *target,
   21804              :                                     bool *targetsync, tree *prefer_type_tree)
   21805              : {
   21806          234 :   *target = false;
   21807          234 :   *targetsync = false;
   21808          234 :   *prefer_type_tree = NULL_TREE;
   21809              : 
   21810          540 :   do
   21811              :     {
   21812          387 :       c_token *tok = c_parser_peek_token (parser);
   21813          387 :       if (tok->type != CPP_NAME)
   21814            1 :         goto fail;
   21815          386 :       const char *p = IDENTIFIER_POINTER (tok->value);
   21816          386 :       if (strcmp ("targetsync", p) == 0)
   21817              :         {
   21818          105 :           if (*targetsync)
   21819            1 :             error_at (tok->location, "duplicate %<targetsync%> modifier");
   21820          105 :           *targetsync = true;
   21821          105 :           c_parser_consume_token (parser);
   21822              :         }
   21823          281 :       else if (strcmp ("target", p) == 0)
   21824              :         {
   21825          148 :           if (*target)
   21826            3 :             error_at (tok->location, "duplicate %<target%> modifier");
   21827          148 :           *target = true;
   21828          148 :           c_parser_consume_token (parser);
   21829              :         }
   21830          133 :       else if (strcmp ("prefer_type", p) == 0)
   21831              :         {
   21832          125 :           if (*prefer_type_tree != NULL_TREE)
   21833            1 :             error_at (tok->location, "duplicate %<prefer_type%> modifier");
   21834          125 :           c_parser_consume_token (parser);
   21835          125 :           *prefer_type_tree = c_parser_omp_modifier_prefer_type (parser);
   21836          125 :           if (*prefer_type_tree == error_mark_node)
   21837              :             return false;
   21838              :         }
   21839              :       else
   21840            8 :         goto fail;
   21841          350 :       tok = c_parser_peek_token (parser);
   21842          350 :       if (tok->type == CPP_COMMA)
   21843              :         {
   21844          153 :           c_parser_consume_token (parser);
   21845          153 :           continue;
   21846              :         }
   21847              :       /* Unknown token - either done or an error; handle it in the caller.  */
   21848              :       return true;
   21849          153 :     }
   21850              :   while (true);
   21851              : 
   21852            9 : fail:
   21853            9 :   c_parser_error (parser,
   21854              :                   "expected %<prefer_type%>, %<target%>, or %<targetsync%>");
   21855            9 :   return false;
   21856              : }
   21857              : 
   21858              : /* OpenMP 5.1:
   21859              :    init ( [init-modifier-list : ] variable-list )
   21860              : 
   21861              :    Modifiers:
   21862              :      target
   21863              :      targetsync
   21864              :      prefer_type (preference-specification) */
   21865              : 
   21866              : static tree
   21867          167 : c_parser_omp_clause_init (c_parser *parser, tree list)
   21868              : {
   21869          167 :   location_t loc = c_parser_peek_token (parser)->location;
   21870              : 
   21871          167 :   matching_parens parens;
   21872          167 :   if (!parens.require_open (parser))
   21873              :     return list;
   21874              : 
   21875          167 :   bool target = false;
   21876          167 :   bool targetsync = false;
   21877          167 :   tree prefer_type_tree = NULL_TREE;
   21878              : 
   21879          167 :   if (!c_parser_omp_clause_init_modifiers (parser, &target, &targetsync,
   21880              :                                            &prefer_type_tree)
   21881          167 :       || !c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   21882              :     {
   21883           39 :       if (prefer_type_tree != error_mark_node)
   21884           11 :         parens.skip_until_found_close (parser);
   21885           39 :       return list;
   21886              :     }
   21887              : 
   21888          128 :   if (!target && !targetsync)
   21889            2 :     error_at (loc,
   21890              :               "missing required %<target%> and/or %<targetsync%> modifier");
   21891              : 
   21892          128 :   tree nl = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_INIT, list,
   21893              :                                         false);
   21894          128 :   parens.skip_until_found_close (parser);
   21895              : 
   21896          280 :   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   21897              :     {
   21898          152 :       TREE_ADDRESSABLE (OMP_CLAUSE_DECL (c)) = 1;
   21899          152 :       if (target)
   21900           90 :         OMP_CLAUSE_INIT_TARGET (c) = 1;
   21901          152 :       if (targetsync)
   21902           81 :         OMP_CLAUSE_INIT_TARGETSYNC (c) = 1;
   21903          152 :       if (prefer_type_tree)
   21904           73 :         OMP_CLAUSE_INIT_PREFER_TYPE (c) = prefer_type_tree;
   21905              :     }
   21906              :   return nl;
   21907              : }
   21908              : 
   21909              : /* OpenMP 5.0:
   21910              :    use ( variable-list ) */
   21911              : 
   21912              : static tree
   21913           43 : c_parser_omp_clause_use (c_parser *parser, tree list)
   21914              : {
   21915            0 :   return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE, list);
   21916              : }
   21917              : 
   21918              : /* OpenMP 6.0:
   21919              :    interop ( variable-list ) */
   21920              : 
   21921              : static tree
   21922           43 : c_parser_omp_clause_interop (c_parser *parser, tree list)
   21923              : {
   21924           43 :   check_no_duplicate_clause (list, OMP_CLAUSE_INTEROP, "interop");
   21925           43 :   tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_INTEROP, list);
   21926          102 :   for (tree c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
   21927              :     {
   21928           59 :       TREE_USED (OMP_CLAUSE_DECL (c)) = 1;
   21929           59 :       DECL_READ_P (OMP_CLAUSE_DECL (c)) = 1;
   21930              :     }
   21931           43 :   return nl;
   21932              : }
   21933              : 
   21934              : /* Parse all OpenACC clauses.  The set clauses allowed by the directive
   21935              :    is a bitmask in MASK.  Return the list of clauses found.  */
   21936              : 
   21937              : static tree
   21938         5352 : c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
   21939              :                            const char *where, bool finish_p = true,
   21940              :                            bool target_p = false)
   21941              : {
   21942         5352 :   tree clauses = NULL;
   21943         5352 :   bool first = true;
   21944              : 
   21945        12079 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   21946              :     {
   21947         6773 :       location_t here;
   21948         6773 :       pragma_omp_clause c_kind;
   21949         6773 :       const char *c_name;
   21950         6773 :       tree prev = clauses;
   21951              : 
   21952         9391 :       if (!first && c_parser_next_token_is (parser, CPP_COMMA))
   21953           11 :         c_parser_consume_token (parser);
   21954              : 
   21955         6773 :       here = c_parser_peek_token (parser)->location;
   21956         6773 :       c_kind = c_parser_omp_clause_name (parser);
   21957              : 
   21958         6773 :       switch (c_kind)
   21959              :         {
   21960          240 :         case PRAGMA_OACC_CLAUSE_ASYNC:
   21961          240 :           clauses = c_parser_oacc_clause_async (parser, clauses);
   21962          240 :           c_name = "async";
   21963          240 :           break;
   21964          125 :         case PRAGMA_OACC_CLAUSE_AUTO:
   21965          125 :           clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
   21966              :                                                  clauses);
   21967          125 :           c_name = "auto";
   21968          125 :           break;
   21969           27 :         case PRAGMA_OACC_CLAUSE_ATTACH:
   21970           27 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   21971           27 :           c_name = "attach";
   21972           27 :           break;
   21973           59 :         case PRAGMA_OACC_CLAUSE_COLLAPSE:
   21974           59 :           clauses = c_parser_omp_clause_collapse (parser, clauses);
   21975           59 :           c_name = "collapse";
   21976           59 :           break;
   21977          806 :         case PRAGMA_OACC_CLAUSE_COPY:
   21978          806 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   21979          806 :           c_name = "copy";
   21980          806 :           break;
   21981          359 :         case PRAGMA_OACC_CLAUSE_COPYIN:
   21982          359 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   21983          359 :           c_name = "copyin";
   21984          359 :           break;
   21985          390 :         case PRAGMA_OACC_CLAUSE_COPYOUT:
   21986          390 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   21987          390 :           c_name = "copyout";
   21988          390 :           break;
   21989           94 :         case PRAGMA_OACC_CLAUSE_CREATE:
   21990           94 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   21991           94 :           c_name = "create";
   21992           94 :           break;
   21993           68 :         case PRAGMA_OACC_CLAUSE_DELETE:
   21994           68 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   21995           68 :           c_name = "delete";
   21996           68 :           break;
   21997           88 :         case PRAGMA_OMP_CLAUSE_DEFAULT:
   21998           88 :           clauses = c_parser_omp_clause_default (parser, clauses, true);
   21999           88 :           c_name = "default";
   22000           88 :           break;
   22001           20 :         case PRAGMA_OACC_CLAUSE_DETACH:
   22002           20 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22003           20 :           c_name = "detach";
   22004           20 :           break;
   22005           36 :         case PRAGMA_OACC_CLAUSE_DEVICE:
   22006           36 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22007           36 :           c_name = "device";
   22008           36 :           break;
   22009           57 :         case PRAGMA_OACC_CLAUSE_DEVICEPTR:
   22010           57 :           clauses = c_parser_oacc_data_clause_deviceptr (parser, clauses);
   22011           57 :           c_name = "deviceptr";
   22012           57 :           break;
   22013           16 :         case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
   22014           16 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22015           16 :           c_name = "device_resident";
   22016           16 :           break;
   22017           12 :         case PRAGMA_OACC_CLAUSE_FINALIZE:
   22018           12 :           clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
   22019              :                                                  clauses);
   22020           12 :           c_name = "finalize";
   22021           12 :           break;
   22022          113 :         case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
   22023          113 :           clauses = c_parser_omp_clause_firstprivate (parser, clauses);
   22024          113 :           c_name = "firstprivate";
   22025          113 :           break;
   22026          589 :         case PRAGMA_OACC_CLAUSE_GANG:
   22027          589 :           c_name = "gang";
   22028          589 :           clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
   22029              :                                                 c_name, clauses);
   22030          589 :           break;
   22031           41 :         case PRAGMA_OACC_CLAUSE_HOST:
   22032           41 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22033           41 :           c_name = "host";
   22034           41 :           break;
   22035          105 :         case PRAGMA_OACC_CLAUSE_IF:
   22036          105 :           clauses = c_parser_omp_clause_if (parser, clauses, false);
   22037          105 :           c_name = "if";
   22038          105 :           break;
   22039           19 :         case PRAGMA_OACC_CLAUSE_IF_PRESENT:
   22040           19 :           clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
   22041              :                                                  clauses);
   22042           19 :           c_name = "if_present";
   22043           19 :           break;
   22044           45 :         case PRAGMA_OACC_CLAUSE_INDEPENDENT:
   22045           45 :           clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
   22046              :                                                  clauses);
   22047           45 :           c_name = "independent";
   22048           45 :           break;
   22049           13 :         case PRAGMA_OACC_CLAUSE_LINK:
   22050           13 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22051           13 :           c_name = "link";
   22052           13 :           break;
   22053           10 :         case PRAGMA_OACC_CLAUSE_NO_CREATE:
   22054           10 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22055           10 :           c_name = "no_create";
   22056           10 :           break;
   22057           25 :         case PRAGMA_OACC_CLAUSE_NOHOST:
   22058           25 :           clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
   22059              :                                                  clauses);
   22060           25 :           c_name = "nohost";
   22061           25 :           break;
   22062          302 :         case PRAGMA_OACC_CLAUSE_NUM_GANGS:
   22063          302 :           clauses = c_parser_oacc_single_int_clause (parser,
   22064              :                                                      OMP_CLAUSE_NUM_GANGS,
   22065              :                                                      clauses);
   22066          302 :           c_name = "num_gangs";
   22067          302 :           break;
   22068          207 :         case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
   22069          207 :           clauses = c_parser_oacc_single_int_clause (parser,
   22070              :                                                      OMP_CLAUSE_NUM_WORKERS,
   22071              :                                                      clauses);
   22072          207 :           c_name = "num_workers";
   22073          207 :           break;
   22074          128 :         case PRAGMA_OACC_CLAUSE_PRESENT:
   22075          128 :           clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22076          128 :           c_name = "present";
   22077          128 :           break;
   22078           66 :         case PRAGMA_OACC_CLAUSE_PRIVATE:
   22079           66 :           clauses = c_parser_omp_clause_private (parser, clauses);
   22080           66 :           c_name = "private";
   22081           66 :           break;
   22082          905 :         case PRAGMA_OACC_CLAUSE_REDUCTION:
   22083          905 :           clauses
   22084          905 :             = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
   22085              :                                              false, clauses);
   22086          905 :           c_name = "reduction";
   22087          905 :           break;
   22088           66 :         case PRAGMA_OACC_CLAUSE_SELF:
   22089           66 :           if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)) == 0)
   22090              :             /* OpenACC compute construct */
   22091           48 :             clauses = c_parser_oacc_compute_clause_self (parser, clauses);
   22092              :           else
   22093              :             /* OpenACC 'update' directive */
   22094           18 :             clauses = c_parser_oacc_data_clause (parser, c_kind, clauses);
   22095              :           c_name = "self";
   22096              :           break;
   22097          261 :         case PRAGMA_OACC_CLAUSE_SEQ:
   22098          261 :           clauses = c_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
   22099              :                                                  clauses);
   22100          261 :           c_name = "seq";
   22101          261 :           break;
   22102          123 :         case PRAGMA_OACC_CLAUSE_TILE:
   22103          123 :           clauses = c_parser_oacc_clause_tile (parser, clauses);
   22104          123 :           c_name = "tile";
   22105          123 :           break;
   22106           21 :         case PRAGMA_OACC_CLAUSE_USE_DEVICE:
   22107           21 :           clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
   22108           21 :           c_name = "use_device";
   22109           21 :           break;
   22110          518 :         case PRAGMA_OACC_CLAUSE_VECTOR:
   22111          518 :           c_name = "vector";
   22112          518 :           clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_VECTOR,
   22113              :                                                 c_name, clauses);
   22114          518 :           break;
   22115          223 :         case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
   22116          223 :           clauses = c_parser_oacc_single_int_clause (parser,
   22117              :                                                      OMP_CLAUSE_VECTOR_LENGTH,
   22118              :                                                      clauses);
   22119          223 :           c_name = "vector_length";
   22120          223 :           break;
   22121           97 :         case PRAGMA_OACC_CLAUSE_WAIT:
   22122           97 :           clauses = c_parser_oacc_clause_wait (parser, clauses);
   22123           97 :           c_name = "wait";
   22124           97 :           break;
   22125          453 :         case PRAGMA_OACC_CLAUSE_WORKER:
   22126          453 :           c_name = "worker";
   22127          453 :           clauses = c_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_WORKER,
   22128              :                                                 c_name, clauses);
   22129          453 :           break;
   22130           46 :         default:
   22131           46 :           c_parser_error (parser, "expected an OpenACC clause");
   22132           46 :           goto saw_error;
   22133              :         }
   22134              : 
   22135         6727 :       first = false;
   22136              : 
   22137         6727 :       if (((mask >> c_kind) & 1) == 0)
   22138              :         {
   22139              :           /* Remove the invalid clause(s) from the list to avoid
   22140              :              confusing the rest of the compiler.  */
   22141           18 :           clauses = prev;
   22142           18 :           error_at (here, "%qs is not valid for %qs", c_name, where);
   22143              :         }
   22144              :     }
   22145              : 
   22146         5306 :  saw_error:
   22147         5352 :   c_parser_skip_to_pragma_eol (parser);
   22148              : 
   22149         5352 :   if (finish_p)
   22150         7831 :     return c_finish_omp_clauses (clauses, target_p ? C_ORT_ACC_TARGET
   22151         4656 :                                                    : C_ORT_ACC);
   22152              : 
   22153              :   return clauses;
   22154              : }
   22155              : 
   22156              : /* Parse all OpenMP clauses.  The set clauses allowed by the directive
   22157              :    is a bitmask in MASK.  Return the list of clauses found.
   22158              :    FINISH_P set if c_finish_omp_clauses should be called.
   22159              :    NESTED non-zero if clauses should be terminated by closing paren instead
   22160              :    of end of pragma.  If it is 2, additionally commas are required in between
   22161              :    the clauses.  */
   22162              : 
   22163              : static tree
   22164        20140 : c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
   22165              :                           const char *where, bool finish_p = true,
   22166              :                           int nested = 0)
   22167              : {
   22168        20140 :   tree clauses = NULL;
   22169        20140 :   bool first = true;
   22170              : 
   22171        47561 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   22172              :     {
   22173        27513 :       location_t here;
   22174        27513 :       pragma_omp_clause c_kind;
   22175        27513 :       const char *c_name;
   22176        27513 :       tree prev = clauses;
   22177              : 
   22178        27610 :       if (nested && c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   22179              :         break;
   22180              : 
   22181        27491 :       if (!first || nested != 2)
   22182              :         {
   22183        27468 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   22184         2697 :             c_parser_consume_token (parser);
   22185        24771 :           else if (nested == 2)
   22186            3 :             error_at (c_parser_peek_token (parser)->location,
   22187              :                       "clauses in %<simd%> trait should be separated "
   22188              :                       "by %<,%>");
   22189              :         }
   22190              : 
   22191        27491 :       here = c_parser_peek_token (parser)->location;
   22192        27491 :       c_kind = c_parser_omp_clause_name (parser);
   22193              : 
   22194        27491 :       switch (c_kind)
   22195              :         {
   22196          116 :         case PRAGMA_OMP_CLAUSE_BIND:
   22197          116 :           clauses = c_parser_omp_clause_bind (parser, clauses);
   22198          116 :           c_name = "bind";
   22199          116 :           break;
   22200         2895 :         case PRAGMA_OMP_CLAUSE_COLLAPSE:
   22201         2895 :           clauses = c_parser_omp_clause_collapse (parser, clauses);
   22202         2895 :           c_name = "collapse";
   22203         2895 :           break;
   22204          101 :         case PRAGMA_OMP_CLAUSE_COPYIN:
   22205          101 :           clauses = c_parser_omp_clause_copyin (parser, clauses);
   22206          101 :           c_name = "copyin";
   22207          101 :           break;
   22208           21 :         case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
   22209           21 :           clauses = c_parser_omp_clause_copyprivate (parser, clauses);
   22210           21 :           c_name = "copyprivate";
   22211           21 :           break;
   22212          641 :         case PRAGMA_OMP_CLAUSE_DEFAULT:
   22213          641 :           clauses = c_parser_omp_clause_default (parser, clauses, false);
   22214          641 :           c_name = "default";
   22215          641 :           break;
   22216           34 :         case PRAGMA_OMP_CLAUSE_DETACH:
   22217           34 :           clauses = c_parser_omp_clause_detach (parser, clauses);
   22218           34 :           c_name = "detach";
   22219           34 :           break;
   22220           63 :         case PRAGMA_OMP_CLAUSE_FILTER:
   22221           63 :           clauses = c_parser_omp_clause_filter (parser, clauses);
   22222           63 :           c_name = "filter";
   22223           63 :           break;
   22224          677 :         case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
   22225          677 :           clauses = c_parser_omp_clause_firstprivate (parser, clauses);
   22226          677 :           c_name = "firstprivate";
   22227          677 :           break;
   22228           99 :         case PRAGMA_OMP_CLAUSE_FINAL:
   22229           99 :           clauses = c_parser_omp_clause_final (parser, clauses);
   22230           99 :           c_name = "final";
   22231           99 :           break;
   22232           62 :         case PRAGMA_OMP_CLAUSE_GRAINSIZE:
   22233           62 :           clauses = c_parser_omp_clause_grainsize (parser, clauses);
   22234           62 :           c_name = "grainsize";
   22235           62 :           break;
   22236           29 :         case PRAGMA_OMP_CLAUSE_HINT:
   22237           29 :           clauses = c_parser_omp_clause_hint (parser, clauses);
   22238           29 :           c_name = "hint";
   22239           29 :           break;
   22240          238 :         case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
   22241          238 :           clauses = c_parser_omp_clause_defaultmap (parser, clauses);
   22242          238 :           c_name = "defaultmap";
   22243          238 :           break;
   22244          779 :         case PRAGMA_OMP_CLAUSE_IF:
   22245          779 :           clauses = c_parser_omp_clause_if (parser, clauses, true);
   22246          779 :           c_name = "if";
   22247          779 :           break;
   22248          321 :         case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
   22249          321 :           clauses
   22250          321 :             = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
   22251              :                                              true, clauses);
   22252          321 :           c_name = "in_reduction";
   22253          321 :           break;
   22254           26 :         case PRAGMA_OMP_CLAUSE_INDIRECT:
   22255           26 :           clauses = c_parser_omp_clause_indirect (parser, clauses);
   22256           26 :           c_name = "indirect";
   22257           26 :           break;
   22258          732 :         case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
   22259          732 :           clauses = c_parser_omp_clause_lastprivate (parser, clauses);
   22260          732 :           c_name = "lastprivate";
   22261          732 :           break;
   22262           79 :         case PRAGMA_OMP_CLAUSE_MERGEABLE:
   22263           79 :           clauses = c_parser_omp_clause_mergeable (parser, clauses);
   22264           79 :           c_name = "mergeable";
   22265           79 :           break;
   22266          391 :         case PRAGMA_OMP_CLAUSE_NOWAIT:
   22267          391 :           clauses = c_parser_omp_clause_nowait (parser, clauses);
   22268          391 :           c_name = "nowait";
   22269          391 :           break;
   22270           50 :         case PRAGMA_OMP_CLAUSE_NUM_TASKS:
   22271           50 :           clauses = c_parser_omp_clause_num_tasks (parser, clauses);
   22272           50 :           c_name = "num_tasks";
   22273           50 :           break;
   22274          426 :         case PRAGMA_OMP_CLAUSE_NUM_THREADS:
   22275          426 :           clauses = c_parser_omp_clause_num_threads (parser, clauses);
   22276          426 :           c_name = "num_threads";
   22277          426 :           break;
   22278          376 :         case PRAGMA_OMP_CLAUSE_ORDER:
   22279          376 :           clauses = c_parser_omp_clause_order (parser, clauses);
   22280          376 :           c_name = "order";
   22281          376 :           break;
   22282          310 :         case PRAGMA_OMP_CLAUSE_ORDERED:
   22283          310 :           clauses = c_parser_omp_clause_ordered (parser, clauses);
   22284          310 :           c_name = "ordered";
   22285          310 :           break;
   22286           98 :         case PRAGMA_OMP_CLAUSE_PRIORITY:
   22287           98 :           clauses = c_parser_omp_clause_priority (parser, clauses);
   22288           98 :           c_name = "priority";
   22289           98 :           break;
   22290          679 :         case PRAGMA_OMP_CLAUSE_PRIVATE:
   22291          679 :           clauses = c_parser_omp_clause_private (parser, clauses);
   22292          679 :           c_name = "private";
   22293          679 :           break;
   22294         1781 :         case PRAGMA_OMP_CLAUSE_REDUCTION:
   22295         1781 :           clauses
   22296         1781 :             = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
   22297              :                                              true, clauses);
   22298         1781 :           c_name = "reduction";
   22299         1781 :           break;
   22300         3469 :         case PRAGMA_OMP_CLAUSE_SCHEDULE:
   22301         3469 :           clauses = c_parser_omp_clause_schedule (parser, clauses);
   22302         3469 :           c_name = "schedule";
   22303         3469 :           break;
   22304          691 :         case PRAGMA_OMP_CLAUSE_SHARED:
   22305          691 :           clauses = c_parser_omp_clause_shared (parser, clauses);
   22306          691 :           c_name = "shared";
   22307          691 :           break;
   22308           86 :         case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
   22309           86 :           clauses
   22310           86 :             = c_parser_omp_clause_reduction (parser, OMP_CLAUSE_TASK_REDUCTION,
   22311              :                                              true, clauses);
   22312           86 :           c_name = "task_reduction";
   22313           86 :           break;
   22314           97 :         case PRAGMA_OMP_CLAUSE_UNTIED:
   22315           97 :           clauses = c_parser_omp_clause_untied (parser, clauses);
   22316           97 :           c_name = "untied";
   22317           97 :           break;
   22318           69 :         case PRAGMA_OMP_CLAUSE_INBRANCH:
   22319           69 :           clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
   22320              :                                                 clauses);
   22321           69 :           c_name = "inbranch";
   22322           69 :           break;
   22323          121 :         case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
   22324          121 :           clauses = c_parser_omp_clause_nontemporal (parser, clauses);
   22325          121 :           c_name = "nontemporal";
   22326          121 :           break;
   22327          136 :         case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
   22328          136 :           clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
   22329              :                                                 clauses);
   22330          136 :           c_name = "notinbranch";
   22331          136 :           break;
   22332          107 :         case PRAGMA_OMP_CLAUSE_PARALLEL:
   22333          107 :           clauses
   22334          107 :             = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
   22335              :                                               clauses);
   22336          107 :           c_name = "parallel";
   22337          107 :           if (!first)
   22338              :             {
   22339            0 :              clause_not_first:
   22340            0 :               error_at (here, "%qs must be the first clause of %qs",
   22341              :                         c_name, where);
   22342            0 :               clauses = prev;
   22343              :             }
   22344              :           break;
   22345           84 :         case PRAGMA_OMP_CLAUSE_FOR:
   22346           84 :           clauses
   22347           84 :             = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
   22348              :                                               clauses);
   22349           84 :           c_name = "for";
   22350           84 :           if (!first)
   22351            0 :             goto clause_not_first;
   22352              :           break;
   22353           78 :         case PRAGMA_OMP_CLAUSE_SECTIONS:
   22354           78 :           clauses
   22355           78 :             = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
   22356              :                                               clauses);
   22357           78 :           c_name = "sections";
   22358           78 :           if (!first)
   22359            0 :             goto clause_not_first;
   22360              :           break;
   22361          110 :         case PRAGMA_OMP_CLAUSE_TASKGROUP:
   22362          110 :           clauses
   22363          110 :             = c_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
   22364              :                                               clauses);
   22365          110 :           c_name = "taskgroup";
   22366          110 :           if (!first)
   22367            0 :             goto clause_not_first;
   22368              :           break;
   22369           30 :         case PRAGMA_OMP_CLAUSE_LINK:
   22370           30 :           clauses
   22371           30 :             = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_LINK, clauses);
   22372           30 :           c_name = "link";
   22373           30 :           break;
   22374          478 :         case PRAGMA_OMP_CLAUSE_TO:
   22375          478 :           if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
   22376              :             {
   22377           86 :               gcc_rich_location richloc (here);
   22378           86 :               richloc.add_fixit_replace ("enter");
   22379           86 :               warning_at (&richloc, OPT_Wdeprecated_openmp,
   22380              :                           "%<to%> clause with %<declare target%> deprecated "
   22381              :                           "since OpenMP 5.2, use %<enter%>");
   22382           86 :               tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
   22383              :                                                       clauses);
   22384          191 :               for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
   22385          105 :                 OMP_CLAUSE_ENTER_TO (c) = 1;
   22386           86 :               clauses = nl;
   22387           86 :             }
   22388              :           else
   22389          392 :             clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_TO,
   22390              :                                                    clauses);
   22391              :           c_name = "to";
   22392              :           break;
   22393         2450 :         case PRAGMA_OMP_CLAUSE_FROM:
   22394         2450 :           clauses = c_parser_omp_clause_from_to (parser, OMP_CLAUSE_FROM,
   22395              :                                                  clauses);
   22396         2450 :           c_name = "from";
   22397         2450 :           break;
   22398          115 :         case PRAGMA_OMP_CLAUSE_UNIFORM:
   22399          115 :           clauses = c_parser_omp_clause_uniform (parser, clauses);
   22400          115 :           c_name = "uniform";
   22401          115 :           break;
   22402          190 :         case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
   22403          190 :           clauses = c_parser_omp_clause_num_teams (parser, clauses);
   22404          190 :           c_name = "num_teams";
   22405          190 :           break;
   22406          154 :         case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
   22407          154 :           clauses = c_parser_omp_clause_thread_limit (parser, clauses);
   22408          154 :           c_name = "thread_limit";
   22409          154 :           break;
   22410          228 :         case PRAGMA_OMP_CLAUSE_ALIGNED:
   22411          228 :           clauses = c_parser_omp_clause_aligned (parser, clauses);
   22412          228 :           c_name = "aligned";
   22413          228 :           break;
   22414          479 :         case PRAGMA_OMP_CLAUSE_ALLOCATE:
   22415          479 :           clauses = c_parser_omp_clause_allocate (parser, clauses);
   22416          479 :           c_name = "allocate";
   22417          479 :           break;
   22418          476 :         case PRAGMA_OMP_CLAUSE_LINEAR:
   22419          476 :           clauses = c_parser_omp_clause_linear (parser, clauses);
   22420          476 :           c_name = "linear";
   22421          476 :           break;
   22422           30 :         case PRAGMA_OMP_CLAUSE_USES_ALLOCATORS:
   22423           30 :           clauses = c_parser_omp_clause_uses_allocators (parser, clauses);
   22424           30 :           c_name = "uses_allocators";
   22425           30 :           break;
   22426          146 :         case PRAGMA_OMP_CLAUSE_AFFINITY:
   22427          146 :           clauses = c_parser_omp_clause_affinity (parser, clauses);
   22428          146 :           c_name = "affinity";
   22429          146 :           break;
   22430          857 :         case PRAGMA_OMP_CLAUSE_DEPEND:
   22431          857 :           clauses = c_parser_omp_clause_depend (parser, clauses, here);
   22432          857 :           c_name = "depend";
   22433          857 :           break;
   22434          145 :         case PRAGMA_OMP_CLAUSE_DOACROSS:
   22435          145 :           clauses = c_parser_omp_clause_doacross (parser, clauses);
   22436          145 :           c_name = "doacross";
   22437          145 :           break;
   22438           41 :         case PRAGMA_OMP_CLAUSE_DESTROY:
   22439           41 :           clauses = c_parser_omp_clause_destroy (parser, clauses);
   22440           41 :           c_name = "destroy";
   22441           41 :           break;
   22442           21 :         case PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE:
   22443           21 :           clauses = c_parser_omp_clause_dyn_groupprivate (parser, clauses);
   22444           21 :           c_name = "dyn_groupprivate";
   22445           21 :           break;
   22446          167 :         case PRAGMA_OMP_CLAUSE_INIT:
   22447          167 :           clauses = c_parser_omp_clause_init (parser, clauses);
   22448          167 :           c_name = "init";
   22449          167 :           break;
   22450           43 :         case PRAGMA_OMP_CLAUSE_USE:
   22451           43 :           clauses = c_parser_omp_clause_use (parser, clauses);
   22452           43 :           c_name = "use";
   22453           43 :           break;
   22454           43 :         case PRAGMA_OMP_CLAUSE_INTEROP:
   22455           43 :           clauses = c_parser_omp_clause_interop (parser, clauses);
   22456           43 :           c_name = "interop";
   22457           43 :           break;
   22458         1748 :         case PRAGMA_OMP_CLAUSE_MAP:
   22459         1748 :           clauses = c_parser_omp_clause_map (parser, clauses, false);
   22460         1748 :           c_name = "map";
   22461         1748 :           break;
   22462           10 :         case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
   22463           10 :           clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
   22464           10 :           c_name = "use_device_ptr";
   22465           10 :           break;
   22466           35 :         case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
   22467           35 :           clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
   22468           35 :           c_name = "use_device_addr";
   22469           35 :           break;
   22470           88 :         case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
   22471           88 :           clauses = c_parser_omp_clause_has_device_addr (parser, clauses);
   22472           88 :           c_name = "has_device_addr";
   22473           88 :           break;
   22474          115 :         case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
   22475          115 :           clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
   22476          115 :           c_name = "is_device_ptr";
   22477          115 :           break;
   22478          369 :         case PRAGMA_OMP_CLAUSE_DEVICE:
   22479          369 :           clauses = c_parser_omp_clause_device (parser, clauses);
   22480          369 :           c_name = "device";
   22481          369 :           break;
   22482         1582 :         case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
   22483         1582 :           clauses = c_parser_omp_clause_dist_schedule (parser, clauses);
   22484         1582 :           c_name = "dist_schedule";
   22485         1582 :           break;
   22486          195 :         case PRAGMA_OMP_CLAUSE_PROC_BIND:
   22487          195 :           clauses = c_parser_omp_clause_proc_bind (parser, clauses);
   22488          195 :           c_name = "proc_bind";
   22489          195 :           break;
   22490           51 :         case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
   22491           51 :           clauses = c_parser_omp_clause_device_type (parser, clauses);
   22492           51 :           c_name = "device_type";
   22493           51 :           break;
   22494          227 :         case PRAGMA_OMP_CLAUSE_SAFELEN:
   22495          227 :           clauses = c_parser_omp_clause_safelen (parser, clauses);
   22496          227 :           c_name = "safelen";
   22497          227 :           break;
   22498          324 :         case PRAGMA_OMP_CLAUSE_SIMDLEN:
   22499          324 :           clauses = c_parser_omp_clause_simdlen (parser, clauses);
   22500          324 :           c_name = "simdlen";
   22501          324 :           break;
   22502           18 :         case PRAGMA_OMP_CLAUSE_NOGROUP:
   22503           18 :           clauses = c_parser_omp_clause_nogroup (parser, clauses);
   22504           18 :           c_name = "nogroup";
   22505           18 :           break;
   22506           46 :         case PRAGMA_OMP_CLAUSE_THREADS:
   22507           46 :           clauses
   22508           46 :             = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
   22509              :                                                clauses);
   22510           46 :           c_name = "threads";
   22511           46 :           break;
   22512           57 :         case PRAGMA_OMP_CLAUSE_SIMD:
   22513           57 :           clauses
   22514           57 :             = c_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
   22515              :                                                clauses);
   22516           57 :           c_name = "simd";
   22517           57 :           break;
   22518           45 :         case PRAGMA_OMP_CLAUSE_ENTER:
   22519           45 :           clauses
   22520           45 :             = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
   22521              :                                             clauses);
   22522           45 :           c_name = "enter";
   22523           45 :           break;
   22524           69 :         case PRAGMA_OMP_CLAUSE_FULL:
   22525           69 :           c_name = "full";
   22526           69 :           clauses = c_parser_omp_clause_full (parser, clauses);
   22527           69 :           break;
   22528          230 :         case PRAGMA_OMP_CLAUSE_PARTIAL:
   22529          230 :           c_name = "partial";
   22530          230 :           clauses = c_parser_omp_clause_partial (parser, clauses);
   22531          230 :           break;
   22532           24 :         case PRAGMA_OMP_CLAUSE_NOVARIANTS:
   22533           24 :           c_name = "novariants";
   22534           24 :           clauses = c_parser_omp_clause_novariants (parser, clauses);
   22535           24 :           break;
   22536           23 :         case PRAGMA_OMP_CLAUSE_NOCONTEXT:
   22537           23 :           c_name = "nocontext";
   22538           23 :           clauses = c_parser_omp_clause_nocontext (parser, clauses);
   22539           23 :           break;
   22540           70 :         default:
   22541           70 :           c_parser_error (parser, "expected an OpenMP clause");
   22542           70 :           goto saw_error;
   22543              :         }
   22544              : 
   22545        27421 :       first = false;
   22546              : 
   22547        27421 :       if (((mask >> c_kind) & 1) == 0)
   22548              :         {
   22549              :           /* Remove the invalid clause(s) from the list to avoid
   22550              :              confusing the rest of the compiler.  */
   22551           24 :           clauses = prev;
   22552           24 :           error_at (here, "%qs is not valid for %qs", c_name, where);
   22553              :         }
   22554              :     }
   22555              : 
   22556        20048 :  saw_error:
   22557        20140 :   if (!nested)
   22558        20117 :     c_parser_skip_to_pragma_eol (parser);
   22559              : 
   22560        20140 :   if (finish_p)
   22561              :     {
   22562        11431 :       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
   22563          399 :         return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
   22564        11032 :       if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE)) != 0)
   22565          183 :         return c_finish_omp_clauses (clauses, C_ORT_OMP_INTEROP);
   22566        10849 :       return c_finish_omp_clauses (clauses, C_ORT_OMP);
   22567              :     }
   22568              : 
   22569              :   return clauses;
   22570              : }
   22571              : 
   22572              : /* OpenACC 2.0, OpenMP 2.5:
   22573              :    structured-block:
   22574              :      statement
   22575              : 
   22576              :    In practice, we're also interested in adding the statement to an
   22577              :    outer node.  So it is convenient if we work around the fact that
   22578              :    c_parser_statement calls add_stmt.  */
   22579              : 
   22580              : static tree
   22581         6703 : c_parser_omp_structured_block (c_parser *parser, bool *if_p)
   22582              : {
   22583         6703 :   tree stmt = push_stmt_list ();
   22584         6703 :   parser->omp_attrs_forbidden_p = true;
   22585         6703 :   c_parser_statement (parser, if_p);
   22586         6703 :   return pop_stmt_list (stmt);
   22587              : }
   22588              : 
   22589              : /* OpenACC 2.0:
   22590              :    # pragma acc cache (variable-list) new-line
   22591              : 
   22592              :    OpenACC 2.7:
   22593              :    # pragma acc cache (readonly: variable-list) new-line
   22594              : 
   22595              :    LOC is the location of the #pragma token.
   22596              : */
   22597              : 
   22598              : static tree
   22599          137 : c_parser_oacc_cache (location_t loc, c_parser *parser)
   22600              : {
   22601          137 :   tree stmt, clauses = NULL_TREE;
   22602          137 :   bool readonly = false;
   22603          137 :   location_t open_loc = c_parser_peek_token (parser)->location;
   22604          137 :   matching_parens parens;
   22605          137 :   if (parens.require_open (parser))
   22606              :     {
   22607          135 :       c_token *token = c_parser_peek_token (parser);
   22608          135 :       if (token->type == CPP_NAME
   22609          131 :           && !strcmp (IDENTIFIER_POINTER (token->value), "readonly")
   22610          139 :           && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   22611              :         {
   22612            4 :           c_parser_consume_token (parser);
   22613            4 :           c_parser_consume_token (parser);
   22614            4 :           readonly = true;
   22615              :         }
   22616          135 :       clauses = c_parser_omp_variable_list (parser, open_loc,
   22617              :                                             OMP_CLAUSE__CACHE_, NULL_TREE);
   22618          135 :       parens.skip_until_found_close (parser);
   22619              :     }
   22620              : 
   22621          135 :   if (readonly)
   22622            8 :     for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   22623            4 :       OMP_CLAUSE__CACHE__READONLY (c) = 1;
   22624              : 
   22625          137 :   clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
   22626              : 
   22627          137 :   c_parser_skip_to_pragma_eol (parser);
   22628              : 
   22629          137 :   stmt = make_node (OACC_CACHE);
   22630          137 :   TREE_TYPE (stmt) = void_type_node;
   22631          137 :   OACC_CACHE_CLAUSES (stmt) = clauses;
   22632          137 :   SET_EXPR_LOCATION (stmt, loc);
   22633          137 :   add_stmt (stmt);
   22634              : 
   22635          137 :   return stmt;
   22636              : }
   22637              : 
   22638              : /* OpenACC 2.0:
   22639              :    # pragma acc data oacc-data-clause[optseq] new-line
   22640              :      structured-block
   22641              : 
   22642              :    LOC is the location of the #pragma token.
   22643              : */
   22644              : 
   22645              : #define OACC_DATA_CLAUSE_MASK                                           \
   22646              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   22647              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   22648              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   22649              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   22650              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   22651              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   22652              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   22653              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   22654              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   22655              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
   22656              : 
   22657              : static tree
   22658          497 : c_parser_oacc_data (location_t loc, c_parser *parser, bool *if_p)
   22659              : {
   22660          497 :   tree stmt, clauses, block;
   22661              : 
   22662          497 :   clauses = c_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
   22663              :                                        "#pragma acc data");
   22664              : 
   22665          497 :   block = c_begin_omp_parallel ();
   22666          497 :   add_stmt (c_parser_omp_structured_block (parser, if_p));
   22667              : 
   22668          497 :   stmt = c_finish_oacc_data (loc, clauses, block);
   22669              : 
   22670          497 :   return stmt;
   22671              : }
   22672              : 
   22673              : /* OpenACC 2.0:
   22674              :    # pragma acc declare oacc-data-clause[optseq] new-line
   22675              : */
   22676              : 
   22677              : #define OACC_DECLARE_CLAUSE_MASK                                        \
   22678              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   22679              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   22680              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   22681              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   22682              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   22683              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT)       \
   22684              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK)          \
   22685              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT))
   22686              : 
   22687              : static void
   22688          144 : c_parser_oacc_declare (c_parser *parser)
   22689              : {
   22690          144 :   location_t pragma_loc = c_parser_peek_token (parser)->location;
   22691          144 :   tree clauses, stmt, t, decl;
   22692              : 
   22693          144 :   bool error = false;
   22694              : 
   22695          144 :   c_parser_consume_pragma (parser);
   22696              : 
   22697          144 :   clauses = c_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
   22698              :                                        "#pragma acc declare");
   22699          144 :   if (!clauses)
   22700              :     {
   22701            2 :       error_at (pragma_loc,
   22702              :                 "no valid clauses specified in %<#pragma acc declare%>");
   22703            2 :       return;
   22704              :     }
   22705              : 
   22706          296 :   for (t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
   22707              :     {
   22708          154 :       location_t loc = OMP_CLAUSE_LOCATION (t);
   22709          154 :       decl = OMP_CLAUSE_DECL (t);
   22710          154 :       if (!DECL_P (decl))
   22711              :         {
   22712            1 :           error_at (loc, "array section in %<#pragma acc declare%>");
   22713            1 :           error = true;
   22714            1 :           continue;
   22715              :         }
   22716              : 
   22717          153 :       switch (OMP_CLAUSE_MAP_KIND (t))
   22718              :         {
   22719              :         case GOMP_MAP_FIRSTPRIVATE_POINTER:
   22720              :         case GOMP_MAP_ALLOC:
   22721              :         case GOMP_MAP_TO:
   22722              :         case GOMP_MAP_FORCE_DEVICEPTR:
   22723              :         case GOMP_MAP_DEVICE_RESIDENT:
   22724              :           break;
   22725              : 
   22726           13 :         case GOMP_MAP_LINK:
   22727           13 :           if (!global_bindings_p ()
   22728           13 :               && (TREE_STATIC (decl)
   22729            6 :                || !DECL_EXTERNAL (decl)))
   22730              :             {
   22731            2 :               error_at (loc,
   22732              :                         "%qD must be a global variable in "
   22733              :                         "%<#pragma acc declare link%>",
   22734              :                         decl);
   22735            2 :               error = true;
   22736            2 :               continue;
   22737              :             }
   22738              :           break;
   22739              : 
   22740           42 :         default:
   22741           42 :           if (global_bindings_p ())
   22742              :             {
   22743            5 :               error_at (loc, "invalid OpenACC clause at file scope");
   22744            5 :               error = true;
   22745            5 :               continue;
   22746              :             }
   22747           37 :           if (DECL_EXTERNAL (decl))
   22748              :             {
   22749           10 :               error_at (loc,
   22750              :                         "invalid use of %<extern%> variable %qD "
   22751              :                         "in %<#pragma acc declare%>", decl);
   22752           10 :               error = true;
   22753           10 :               continue;
   22754              :             }
   22755           27 :           else if (TREE_PUBLIC (decl))
   22756              :             {
   22757            2 :               error_at (loc,
   22758              :                         "invalid use of %<global%> variable %qD "
   22759              :                         "in %<#pragma acc declare%>", decl);
   22760            2 :               error = true;
   22761            2 :               continue;
   22762              :             }
   22763              :           break;
   22764              :         }
   22765              : 
   22766          134 :       if (!c_check_in_current_scope (decl))
   22767              :         {
   22768            2 :           error_at (loc,
   22769              :                     "%qD must be a variable declared in the same scope as "
   22770              :                     "%<#pragma acc declare%>", decl);
   22771            2 :           error = true;
   22772            2 :           continue;
   22773              :         }
   22774              : 
   22775          132 :       if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
   22776          250 :           || lookup_attribute ("omp declare target link",
   22777          118 :                                DECL_ATTRIBUTES (decl)))
   22778              :         {
   22779           17 :           error_at (loc, "variable %qD used more than once with "
   22780              :                     "%<#pragma acc declare%>", decl);
   22781           17 :           error = true;
   22782           17 :           continue;
   22783              :         }
   22784              : 
   22785          115 :       if (!error)
   22786              :         {
   22787          115 :           tree id;
   22788              : 
   22789          115 :           if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
   22790            7 :             id = get_identifier ("omp declare target link");
   22791              :           else
   22792          108 :             id = get_identifier ("omp declare target");
   22793              : 
   22794          115 :           DECL_ATTRIBUTES (decl)
   22795          115 :                            = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
   22796              : 
   22797          115 :           if (global_bindings_p ())
   22798              :             {
   22799           45 :               symtab_node *node = symtab_node::get (decl);
   22800           45 :               if (node != NULL)
   22801              :                 {
   22802           33 :                   node->offloadable = 1;
   22803           33 :                   if (ENABLE_OFFLOADING)
   22804              :                     {
   22805              :                       g->have_offload = true;
   22806              :                       if (is_a <varpool_node *> (node))
   22807              :                         vec_safe_push (offload_vars, decl);
   22808              :                     }
   22809              :                 }
   22810              :             }
   22811              :         }
   22812              :     }
   22813              : 
   22814          142 :   if (error || global_bindings_p ())
   22815           74 :     return;
   22816              : 
   22817           68 :   stmt = make_node (OACC_DECLARE);
   22818           68 :   TREE_TYPE (stmt) = void_type_node;
   22819           68 :   OACC_DECLARE_CLAUSES (stmt) = clauses;
   22820           68 :   SET_EXPR_LOCATION (stmt, pragma_loc);
   22821              : 
   22822           68 :   add_stmt (stmt);
   22823              : 
   22824           68 :   return;
   22825              : }
   22826              : 
   22827              : /* OpenACC 2.0:
   22828              :    # pragma acc enter data oacc-enter-data-clause[optseq] new-line
   22829              : 
   22830              :    or
   22831              : 
   22832              :    # pragma acc exit data oacc-exit-data-clause[optseq] new-line
   22833              : 
   22834              : 
   22835              :    LOC is the location of the #pragma token.
   22836              : */
   22837              : 
   22838              : #define OACC_ENTER_DATA_CLAUSE_MASK                                     \
   22839              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   22840              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   22841              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   22842              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   22843              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   22844              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   22845              : 
   22846              : #define OACC_EXIT_DATA_CLAUSE_MASK                                      \
   22847              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   22848              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   22849              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   22850              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE)                \
   22851              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH)                \
   22852              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE)              \
   22853              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   22854              : 
   22855              : static void
   22856          261 : c_parser_oacc_enter_exit_data (c_parser *parser, bool enter)
   22857              : {
   22858          261 :   location_t loc = c_parser_peek_token (parser)->location;
   22859          261 :   tree clauses, stmt;
   22860          261 :   const char *p = "";
   22861              : 
   22862          261 :   c_parser_consume_pragma (parser);
   22863              : 
   22864          261 :   if (c_parser_next_token_is (parser, CPP_NAME))
   22865              :     {
   22866          258 :       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   22867          258 :       c_parser_consume_token (parser);
   22868              :     }
   22869              : 
   22870          261 :   if (strcmp (p, "data") != 0)
   22871              :     {
   22872            8 :       error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
   22873              :                 enter ? "enter" : "exit");
   22874            6 :       parser->error = true;
   22875            6 :       c_parser_skip_to_pragma_eol (parser);
   22876            6 :       return;
   22877              :     }
   22878              : 
   22879          255 :   if (enter)
   22880          129 :     clauses = c_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
   22881              :                                          "#pragma acc enter data");
   22882              :   else
   22883          126 :     clauses = c_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
   22884              :                                          "#pragma acc exit data");
   22885              : 
   22886          255 :   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
   22887              :     {
   22888           15 :       error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
   22889              :                 enter ? "enter" : "exit");
   22890           15 :       return;
   22891              :     }
   22892              : 
   22893          240 :   stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
   22894          240 :   TREE_TYPE (stmt) = void_type_node;
   22895          240 :   OMP_STANDALONE_CLAUSES (stmt) = clauses;
   22896          240 :   SET_EXPR_LOCATION (stmt, loc);
   22897          240 :   add_stmt (stmt);
   22898              : }
   22899              : 
   22900              : 
   22901              : /* OpenACC 2.0:
   22902              :    # pragma acc host_data oacc-data-clause[optseq] new-line
   22903              :      structured-block
   22904              : */
   22905              : 
   22906              : #define OACC_HOST_DATA_CLAUSE_MASK                                      \
   22907              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)          \
   22908              :          | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                  \
   22909              :          | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )
   22910              : 
   22911              : static tree
   22912           23 : c_parser_oacc_host_data (location_t loc, c_parser *parser, bool *if_p)
   22913              : {
   22914           23 :   tree stmt, clauses, block;
   22915              : 
   22916           23 :   clauses = c_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
   22917              :                                        "#pragma acc host_data", false);
   22918           23 :   if (!omp_find_clause (clauses, OMP_CLAUSE_USE_DEVICE_PTR))
   22919              :     {
   22920            2 :       error_at (loc, "%<host_data%> construct requires %<use_device%> clause");
   22921            2 :       return error_mark_node;
   22922              :     }
   22923           21 :   clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
   22924           21 :   block = c_begin_omp_parallel ();
   22925           21 :   add_stmt (c_parser_omp_structured_block (parser, if_p));
   22926           21 :   stmt = c_finish_oacc_host_data (loc, clauses, block);
   22927           21 :   return stmt;
   22928              : }
   22929              : 
   22930              : 
   22931              : /* OpenACC 2.0:
   22932              : 
   22933              :    # pragma acc loop oacc-loop-clause[optseq] new-line
   22934              :      structured-block
   22935              : 
   22936              :    LOC is the location of the #pragma token.
   22937              : */
   22938              : 
   22939              : #define OACC_LOOP_CLAUSE_MASK                                           \
   22940              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE)              \
   22941              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)               \
   22942              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)             \
   22943              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)          \
   22944              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)                \
   22945              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)                \
   22946              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO)          \
   22947              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT)   \
   22948              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)                   \
   22949              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE) )
   22950              : static tree
   22951         2444 : c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
   22952              :                     omp_clause_mask mask, tree *cclauses, bool *if_p)
   22953              : {
   22954         2444 :   bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;
   22955              : 
   22956         2444 :   strcat (p_name, " loop");
   22957         2444 :   mask |= OACC_LOOP_CLAUSE_MASK;
   22958              : 
   22959         2444 :   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
   22960              :                                             /*finish_p=*/cclauses == NULL,
   22961              :                                             /*target=*/is_parallel);
   22962         2444 :   if (cclauses)
   22963              :     {
   22964          673 :       clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
   22965          673 :       if (*cclauses)
   22966          152 :         *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC_TARGET);
   22967          673 :       if (clauses)
   22968          271 :         clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
   22969              :     }
   22970              : 
   22971         2444 :   tree block = c_begin_compound_stmt (true);
   22972         2444 :   tree stmt = c_parser_omp_for_loop (loc, parser, OACC_LOOP, clauses, NULL,
   22973              :                                      if_p);
   22974         2444 :   block = c_end_compound_stmt (loc, block, true);
   22975         2444 :   add_stmt (block);
   22976              : 
   22977         2444 :   return stmt;
   22978              : }
   22979              : 
   22980              : /* OpenACC 2.0:
   22981              :    # pragma acc kernels oacc-kernels-clause[optseq] new-line
   22982              :      structured-block
   22983              : 
   22984              :    or
   22985              : 
   22986              :    # pragma acc parallel oacc-parallel-clause[optseq] new-line
   22987              :      structured-block
   22988              : 
   22989              :    OpenACC 2.6:
   22990              : 
   22991              :    # pragma acc serial oacc-serial-clause[optseq] new-line
   22992              :      structured-block
   22993              : 
   22994              :    LOC is the location of the #pragma token.
   22995              : */
   22996              : 
   22997              : #define OACC_KERNELS_CLAUSE_MASK                                        \
   22998              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   22999              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   23000              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   23001              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   23002              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   23003              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   23004              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   23005              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   23006              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   23007              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   23008              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)             \
   23009              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)           \
   23010              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)               \
   23011              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   23012              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
   23013              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   23014              : 
   23015              : #define OACC_PARALLEL_CLAUSE_MASK                                       \
   23016              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   23017              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   23018              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   23019              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   23020              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   23021              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   23022              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   23023              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   23024              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   23025              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   23026              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)               \
   23027              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)  \
   23028              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)             \
   23029              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)           \
   23030              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)               \
   23031              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)             \
   23032              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   23033              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH) \
   23034              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   23035              : 
   23036              : #define OACC_SERIAL_CLAUSE_MASK                                 \
   23037              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   23038              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)                \
   23039              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)          \
   23040              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)                \
   23041              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)               \
   23042              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)                \
   23043              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)               \
   23044              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)             \
   23045              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   23046              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)             \
   23047              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)               \
   23048              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)  \
   23049              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)               \
   23050              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)             \
   23051              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   23052              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   23053              : 
   23054              : static tree
   23055         2154 : c_parser_oacc_compute (location_t loc, c_parser *parser,
   23056              :                        enum pragma_kind p_kind, char *p_name, bool *if_p)
   23057              : {
   23058         2154 :   omp_clause_mask mask;
   23059         2154 :   enum tree_code code;
   23060         2154 :   switch (p_kind)
   23061              :     {
   23062          522 :     case PRAGMA_OACC_KERNELS:
   23063          522 :       strcat (p_name, " kernels");
   23064          522 :       mask = OACC_KERNELS_CLAUSE_MASK;
   23065          522 :       code = OACC_KERNELS;
   23066          522 :       break;
   23067         1457 :     case PRAGMA_OACC_PARALLEL:
   23068         1457 :       strcat (p_name, " parallel");
   23069         1457 :       mask = OACC_PARALLEL_CLAUSE_MASK;
   23070         1457 :       code = OACC_PARALLEL;
   23071         1457 :       break;
   23072          175 :     case PRAGMA_OACC_SERIAL:
   23073          175 :       strcat (p_name, " serial");
   23074          175 :       mask = OACC_SERIAL_CLAUSE_MASK;
   23075          175 :       code = OACC_SERIAL;
   23076          175 :       break;
   23077            0 :     default:
   23078            0 :       gcc_unreachable ();
   23079              :     }
   23080              : 
   23081         2154 :   if (c_parser_next_token_is (parser, CPP_NAME))
   23082              :     {
   23083         1710 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   23084         1710 :       if (strcmp (p, "loop") == 0)
   23085              :         {
   23086          673 :           c_parser_consume_token (parser);
   23087          673 :           tree block = c_begin_omp_parallel ();
   23088          673 :           tree clauses;
   23089          673 :           c_parser_oacc_loop (loc, parser, p_name, mask, &clauses, if_p);
   23090          673 :           return c_finish_omp_construct (loc, code, block, clauses);
   23091              :         }
   23092              :     }
   23093              : 
   23094         1481 :   tree clauses = c_parser_oacc_all_clauses (parser, mask, p_name,
   23095              :                                             /*finish_p=*/true,
   23096              :                                             /*target=*/true);
   23097              : 
   23098         1481 :   tree block = c_begin_omp_parallel ();
   23099         1481 :   add_stmt (c_parser_omp_structured_block (parser, if_p));
   23100              : 
   23101         1481 :   return c_finish_omp_construct (loc, code, block, clauses);
   23102              : }
   23103              : 
   23104              : /* OpenACC 2.0:
   23105              :    # pragma acc routine oacc-routine-clause[optseq] new-line
   23106              :      function-definition
   23107              : 
   23108              :    # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
   23109              : */
   23110              : 
   23111              : #define OACC_ROUTINE_CLAUSE_MASK                                        \
   23112              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)          \
   23113              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)                \
   23114              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)                \
   23115              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)                   \
   23116              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )
   23117              : 
   23118              : /* Parse an OpenACC routine directive.  For named directives, we apply
   23119              :    immediately to the named function.  For unnamed ones we then parse
   23120              :    a declaration or definition, which must be for a function.  */
   23121              : 
   23122              : static void
   23123          345 : c_parser_oacc_routine (c_parser *parser, enum pragma_context context)
   23124              : {
   23125          345 :   gcc_checking_assert (context == pragma_external);
   23126              : 
   23127          345 :   oacc_routine_data data;
   23128          345 :   data.error_seen = false;
   23129          345 :   data.fndecl_seen = false;
   23130          345 :   data.loc = c_parser_peek_token (parser)->location;
   23131              : 
   23132          345 :   c_parser_consume_pragma (parser);
   23133              : 
   23134              :   /* Look for optional '( name )'.  */
   23135          345 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   23136              :     {
   23137          143 :       c_parser_consume_token (parser); /* '(' */
   23138              : 
   23139          143 :       tree decl = NULL_TREE;
   23140          143 :       c_token *name_token = c_parser_peek_token (parser);
   23141          143 :       location_t name_loc = name_token->location;
   23142          143 :       if (name_token->type == CPP_NAME
   23143          135 :           && (name_token->id_kind == C_ID_ID
   23144              :               || name_token->id_kind == C_ID_TYPENAME))
   23145              :         {
   23146          135 :           decl = lookup_name (name_token->value);
   23147          135 :           if (!decl)
   23148            5 :             error_at (name_loc,
   23149              :                       "%qE has not been declared", name_token->value);
   23150          135 :           c_parser_consume_token (parser);
   23151              :         }
   23152              :       else
   23153            8 :         c_parser_error (parser, "expected function name");
   23154              : 
   23155            8 :       if (!decl
   23156          135 :           || !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   23157              :         {
   23158           15 :           c_parser_skip_to_pragma_eol (parser, false);
   23159           43 :           return;
   23160              :         }
   23161              : 
   23162          128 :       data.clauses
   23163          128 :         = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
   23164              :                                      "#pragma acc routine");
   23165              :       /* The clauses are in reverse order; fix that to make later diagnostic
   23166              :          emission easier.  */
   23167          128 :       data.clauses = nreverse (data.clauses);
   23168              : 
   23169          128 :       if (TREE_CODE (decl) != FUNCTION_DECL)
   23170              :         {
   23171            3 :           error_at (name_loc, "%qD does not refer to a function", decl);
   23172            3 :           return;
   23173              :         }
   23174              : 
   23175          125 :       c_finish_oacc_routine (&data, decl, false);
   23176              :     }
   23177              :   else /* No optional '( name )'.  */
   23178              :     {
   23179          202 :       data.clauses
   23180          202 :         = c_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
   23181              :                                      "#pragma acc routine");
   23182              :       /* The clauses are in reverse order; fix that to make later diagnostic
   23183              :          emission easier.  */
   23184          202 :       data.clauses = nreverse (data.clauses);
   23185              : 
   23186              :       /* Emit a helpful diagnostic if there's another pragma following this
   23187              :          one.  Also don't allow a static assertion declaration, as in the
   23188              :          following we'll just parse a *single* "declaration or function
   23189              :          definition", and the static assertion counts an one.  */
   23190          202 :       if (c_parser_next_token_is (parser, CPP_PRAGMA)
   23191          395 :           || c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT))
   23192              :         {
   23193           10 :           error_at (data.loc,
   23194              :                     "%<#pragma acc routine%> not immediately followed by"
   23195              :                     " function declaration or definition");
   23196              :           /* ..., and then just keep going.  */
   23197           10 :           return;
   23198              :         }
   23199              : 
   23200              :       /* We only have to consider the pragma_external case here.  */
   23201          192 :       if (c_parser_next_token_is (parser, CPP_KEYWORD)
   23202          192 :           && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
   23203              :         {
   23204            3 :           int ext = disable_extension_diagnostics ();
   23205            7 :           do
   23206            7 :             c_parser_consume_token (parser);
   23207            7 :           while (c_parser_next_token_is (parser, CPP_KEYWORD)
   23208           10 :                  && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
   23209            3 :           c_parser_declaration_or_fndef (parser, true, true, true, false, true,
   23210              :                                          false, NULL, NULL, false, NULL, &data);
   23211            3 :           restore_extension_diagnostics (ext);
   23212              :         }
   23213              :       else
   23214          189 :         c_parser_declaration_or_fndef (parser, true, true, true, false, true,
   23215              :                                        false, NULL, NULL, false, NULL, &data);
   23216              :     }
   23217              : }
   23218              : 
   23219              : /* Finalize an OpenACC routine pragma, applying it to FNDECL.
   23220              :    IS_DEFN is true if we're applying it to the definition.  */
   23221              : 
   23222              : static void
   23223          327 : c_finish_oacc_routine (struct oacc_routine_data *data, tree fndecl,
   23224              :                        bool is_defn)
   23225              : {
   23226              :   /* Keep going if we're in error reporting mode.  */
   23227          327 :   if (data->error_seen
   23228          321 :       || fndecl == error_mark_node)
   23229              :     return;
   23230              : 
   23231          321 :   if (data->fndecl_seen)
   23232              :     {
   23233            4 :       error_at (data->loc,
   23234              :                 "%<#pragma acc routine%> not immediately followed by"
   23235              :                 " a single function declaration or definition");
   23236            4 :       data->error_seen = true;
   23237            4 :       return;
   23238              :     }
   23239          317 :   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
   23240              :     {
   23241           10 :       error_at (data->loc,
   23242              :                 "%<#pragma acc routine%> not immediately followed by"
   23243              :                 " function declaration or definition");
   23244           10 :       data->error_seen = true;
   23245           10 :       return;
   23246              :     }
   23247              : 
   23248          307 :   int compatible
   23249          307 :     = oacc_verify_routine_clauses (fndecl, &data->clauses, data->loc,
   23250              :                                    "#pragma acc routine");
   23251          307 :   if (compatible < 0)
   23252              :     {
   23253           47 :       data->error_seen = true;
   23254           47 :       return;
   23255              :     }
   23256          260 :   if (compatible > 0)
   23257              :     {
   23258              :     }
   23259              :   else
   23260              :     {
   23261          269 :       if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
   23262              :         {
   23263            3 :           error_at (data->loc,
   23264              :                     TREE_USED (fndecl)
   23265              :                     ? G_("%<#pragma acc routine%> must be applied before use")
   23266              :                     : G_("%<#pragma acc routine%> must be applied before"
   23267              :                          " definition"));
   23268            2 :           data->error_seen = true;
   23269            2 :           return;
   23270              :         }
   23271              : 
   23272              :       /* Set the routine's level of parallelism.  */
   23273          197 :       tree dims = oacc_build_routine_dims (data->clauses);
   23274          197 :       oacc_replace_fn_attrib (fndecl, dims);
   23275              : 
   23276              :       /* Add an "omp declare target" attribute.  */
   23277          197 :       DECL_ATTRIBUTES (fndecl)
   23278          394 :         = tree_cons (get_identifier ("omp declare target"),
   23279          197 :                      data->clauses, DECL_ATTRIBUTES (fndecl));
   23280              :     }
   23281              : 
   23282              :   /* Remember that we've used this "#pragma acc routine".  */
   23283          258 :   data->fndecl_seen = true;
   23284              : }
   23285              : 
   23286              : /* OpenACC 2.0:
   23287              :    # pragma acc update oacc-update-clause[optseq] new-line
   23288              : */
   23289              : 
   23290              : #define OACC_UPDATE_CLAUSE_MASK                                         \
   23291              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   23292              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE)                \
   23293              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)          \
   23294              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                    \
   23295              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT)            \
   23296              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SELF)          \
   23297              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )
   23298              : 
   23299              : static void
   23300           92 : c_parser_oacc_update (c_parser *parser)
   23301              : {
   23302           92 :   location_t loc = c_parser_peek_token (parser)->location;
   23303              : 
   23304           92 :   c_parser_consume_pragma (parser);
   23305              : 
   23306           92 :   tree clauses = c_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
   23307              :                                             "#pragma acc update");
   23308           92 :   if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
   23309              :     {
   23310            1 :       error_at (loc,
   23311              :                 "%<#pragma acc update%> must contain at least one "
   23312              :                 "%<device%> or %<host%> or %<self%> clause");
   23313            1 :       return;
   23314              :     }
   23315              : 
   23316           91 :   if (parser->error)
   23317              :     return;
   23318              : 
   23319           91 :   tree stmt = make_node (OACC_UPDATE);
   23320           91 :   TREE_TYPE (stmt) = void_type_node;
   23321           91 :   OACC_UPDATE_CLAUSES (stmt) = clauses;
   23322           91 :   SET_EXPR_LOCATION (stmt, loc);
   23323           91 :   add_stmt (stmt);
   23324              : }
   23325              : 
   23326              : /* OpenACC 2.0:
   23327              :    # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line
   23328              : 
   23329              :    LOC is the location of the #pragma token.
   23330              : */
   23331              : 
   23332              : #define OACC_WAIT_CLAUSE_MASK                                           \
   23333              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)         \
   23334              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF) )
   23335              : 
   23336              : static tree
   23337           86 : c_parser_oacc_wait (location_t loc, c_parser *parser, char *p_name)
   23338              : {
   23339           86 :   tree clauses, list = NULL_TREE, stmt = NULL_TREE;
   23340              : 
   23341           86 :   if (c_parser_peek_token (parser)->type == CPP_OPEN_PAREN)
   23342           49 :     list = c_parser_oacc_wait_list (parser, loc, list);
   23343              : 
   23344           86 :   strcpy (p_name, " wait");
   23345           86 :   clauses = c_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK, p_name);
   23346           86 :   stmt = c_finish_oacc_wait (loc, list, clauses);
   23347           86 :   add_stmt (stmt);
   23348              : 
   23349           86 :   return stmt;
   23350              : }
   23351              : 
   23352              : struct c_omp_loc_tree
   23353              : {
   23354              :   location_t loc;
   23355              :   tree var;
   23356              : };
   23357              : 
   23358              : /* Check whether the expression used in the allocator clause is declared or
   23359              :    modified between the variable declaration and its allocate directive.  */
   23360              : static tree
   23361           50 : c_check_omp_allocate_allocator_r (tree *tp, int *, void *data)
   23362              : {
   23363           50 :   tree var = ((struct c_omp_loc_tree *) data)->var;
   23364           50 :   location_t loc = ((struct c_omp_loc_tree *) data)->loc;
   23365           50 :   if (TREE_CODE (*tp) == VAR_DECL && c_check_in_current_scope (*tp))
   23366              :     {
   23367           10 :       if (linemap_location_before_p (line_table, DECL_SOURCE_LOCATION (var),
   23368           10 :                                      DECL_SOURCE_LOCATION (*tp)))
   23369              :         {
   23370            2 :           error_at (loc, "variable %qD used in the %<allocator%> clause must "
   23371              :                          "be declared before %qD", *tp, var);
   23372            2 :           inform (DECL_SOURCE_LOCATION (*tp), "declared here");
   23373            2 :           inform (DECL_SOURCE_LOCATION (var),
   23374              :                   "to be allocated variable declared here");
   23375            2 :           return *tp;
   23376              :         }
   23377              :       else
   23378              :         {
   23379            8 :           gcc_assert (cur_stmt_list
   23380              :                       && TREE_CODE (cur_stmt_list) == STATEMENT_LIST);
   23381              : 
   23382            8 :           tree_stmt_iterator l = tsi_last (cur_stmt_list);
   23383            9 :           while (!tsi_end_p (l))
   23384              :             {
   23385            9 :               if (linemap_location_before_p (line_table, EXPR_LOCATION (*l),
   23386            9 :                                              DECL_SOURCE_LOCATION (var)))
   23387              :                   break;
   23388            3 :               if (TREE_CODE (*l) == MODIFY_EXPR
   23389            3 :                   && TREE_OPERAND (*l, 0) == *tp)
   23390              :                 {
   23391            2 :                   error_at (loc,
   23392              :                             "variable %qD used in the %<allocator%> clause "
   23393              :                             "must not be modified between declaration of %qD "
   23394              :                             "and its %<allocate%> directive", *tp, var);
   23395            2 :                   inform (EXPR_LOCATION (*l), "modified here");
   23396            2 :                   inform (DECL_SOURCE_LOCATION (var),
   23397              :                           "to be allocated variable declared here");
   23398            2 :                   return *tp;
   23399              :                 }
   23400            1 :               --l;
   23401              :             }
   23402              :         }
   23403              :     }
   23404              :   return NULL_TREE;
   23405              : }
   23406              : 
   23407              : /* OpenMP 5.x:
   23408              :    # pragma omp allocate (list)  clauses
   23409              : 
   23410              :    OpenMP 5.0 clause:
   23411              :    allocator (omp_allocator_handle_t expression)
   23412              : 
   23413              :    OpenMP 5.1 additional clause:
   23414              :    align (constant-expression)]  */
   23415              : 
   23416              : static void
   23417           71 : c_parser_omp_allocate (c_parser *parser)
   23418              : {
   23419           71 :   tree alignment = NULL_TREE;
   23420           71 :   tree allocator = NULL_TREE;
   23421           71 :   c_parser_consume_pragma (parser);
   23422           71 :   location_t loc = c_parser_peek_token (parser)->location;
   23423           71 :   location_t allocator_loc = UNKNOWN_LOCATION;
   23424           71 :   tree nl = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);
   23425          221 :   do
   23426              :     {
   23427          146 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   23428          146 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   23429            9 :         c_parser_consume_token (parser);
   23430          146 :       if (!c_parser_next_token_is (parser, CPP_NAME))
   23431              :         break;
   23432           78 :       matching_parens parens;
   23433           78 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   23434           78 :       c_parser_consume_token (parser);
   23435           78 :       location_t expr_loc = c_parser_peek_token (parser)->location;
   23436           78 :       if (strcmp ("align", p) != 0 && strcmp ("allocator", p) != 0)
   23437              :         {
   23438            1 :           error_at (c_parser_peek_token (parser)->location,
   23439              :                     "expected %<allocator%> or %<align%>");
   23440            1 :           break;
   23441              :         }
   23442           77 :       if (!parens.require_open (parser))
   23443              :         break;
   23444              : 
   23445           77 :       c_expr expr = c_parser_expr_no_commas (parser, NULL);
   23446           77 :       expr = convert_lvalue_to_rvalue (expr_loc, expr, false, true);
   23447           77 :       expr_loc = c_parser_peek_token (parser)->location;
   23448           77 :       if (expr.value == error_mark_node)
   23449              :         ;
   23450           76 :       else if (p[2] == 'i' && alignment)
   23451              :         {
   23452            1 :           error_at (expr_loc, "too many %qs clauses", "align");
   23453            1 :           break;
   23454              :         }
   23455           75 :       else if (p[2] == 'i')
   23456              :         {
   23457           32 :           alignment = c_fully_fold (expr.value, false, NULL);
   23458           32 :           if (TREE_CODE (alignment) != INTEGER_CST
   23459           31 :               || !INTEGRAL_TYPE_P (TREE_TYPE (alignment))
   23460           31 :               || tree_int_cst_sgn (alignment) != 1
   23461           62 :               || !integer_pow2p (alignment))
   23462              :             {
   23463            4 :               error_at (expr_loc, "%<align%> clause argument needs to be "
   23464              :                                   "positive constant power of two integer "
   23465              :                                   "expression");
   23466            4 :               alignment = NULL_TREE;
   23467              :             }
   23468              :         }
   23469           43 :       else if (allocator)
   23470              :         {
   23471            1 :           error_at (expr_loc, "too many %qs clauses", "allocator");
   23472            1 :           break;
   23473              :         }
   23474              :       else
   23475              :         {
   23476           42 :           allocator = c_fully_fold (expr.value, false, NULL);
   23477           42 :           allocator_loc = expr_loc;
   23478           42 :           tree orig_type
   23479           42 :             = expr.original_type ? expr.original_type : TREE_TYPE (allocator);
   23480           42 :           orig_type = TYPE_MAIN_VARIANT (orig_type);
   23481           43 :           if (!INTEGRAL_TYPE_P (TREE_TYPE (allocator))
   23482           42 :               || TREE_CODE (orig_type) != ENUMERAL_TYPE
   23483          124 :               || TYPE_NAME (orig_type)
   23484           41 :                  != get_identifier ("omp_allocator_handle_t"))
   23485              :             {
   23486            1 :               error_at (expr_loc,
   23487              :                         "%<allocator%> clause allocator expression has type "
   23488              :                         "%qT rather than %<omp_allocator_handle_t%>",
   23489            1 :                         TREE_TYPE (allocator));
   23490            1 :               allocator = NULL_TREE;
   23491              :             }
   23492              :         }
   23493           75 :       parens.skip_until_found_close (parser);
   23494           75 :     } while (true);
   23495           71 :   c_parser_skip_to_pragma_eol (parser);
   23496              : 
   23497           71 :   c_mark_decl_jump_unsafe_in_current_scope ();
   23498          153 :   for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
   23499              :     {
   23500           82 :       tree var = OMP_CLAUSE_DECL (c);
   23501           82 :       if (TREE_CODE (var) == PARM_DECL)
   23502              :         {
   23503            1 :           error_at (OMP_CLAUSE_LOCATION (nl),
   23504              :                     "function parameter %qD may not appear as list item in an "
   23505              :                     "%<allocate%> directive", var);
   23506            1 :           continue;
   23507              :         }
   23508           81 :       if (!parser->in_omp_decl_attribute && !c_check_in_current_scope (var))
   23509              :         {
   23510            2 :           error_at (OMP_CLAUSE_LOCATION (nl),
   23511              :                     "%<allocate%> directive must be in the same scope as %qD",
   23512              :                     var);
   23513            2 :           inform (DECL_SOURCE_LOCATION (var), "declared here");
   23514            2 :           continue;
   23515              :         }
   23516           79 :       if (lookup_attribute ("omp allocate", DECL_ATTRIBUTES (var)))
   23517              :         {
   23518            1 :           error_at (OMP_CLAUSE_LOCATION (nl),
   23519              :                     "%qD already appeared as list item in an "
   23520              :                     "%<allocate%> directive", var);
   23521            1 :           continue;
   23522              :         }
   23523           78 :       if (TREE_STATIC (var))
   23524              :         {
   23525           19 :           if (allocator == NULL_TREE && allocator_loc == UNKNOWN_LOCATION)
   23526              :             {
   23527            3 :               error_at (loc,
   23528              :                         "%<allocator%> clause required for "
   23529              :                         "static variable %qD", var);
   23530            3 :               continue;
   23531              :             }
   23532           16 :           else if (allocator
   23533           16 :                    && (wi::to_widest (allocator) < 1
   23534           15 :                        || wi::to_widest (allocator) > GOMP_OMP_PREDEF_ALLOC_MAX)
   23535           23 :                    && (wi::to_widest (allocator) < GOMP_OMPX_PREDEF_ALLOC_MIN
   23536           12 :                        || wi::to_widest (allocator) > GOMP_OMPX_PREDEF_ALLOC_MAX))
   23537              :             {
   23538            6 :               error_at (allocator_loc,
   23539              :                         "%<allocator%> clause requires a predefined allocator as "
   23540              :                         "%qD is static", var);
   23541              :             }
   23542              :         }
   23543           75 :       if (allocator)
   23544              :         {
   23545           42 :           struct c_omp_loc_tree data
   23546           82 :             = {EXPR_LOC_OR_LOC (allocator, OMP_CLAUSE_LOCATION (nl)), var};
   23547           42 :           walk_tree (&allocator, c_check_omp_allocate_allocator_r, &data, NULL);
   23548              :         }
   23549           75 :       DECL_ATTRIBUTES (var) = tree_cons (get_identifier ("omp allocate"),
   23550              :                                          build_tree_list (allocator, alignment),
   23551           75 :                                          DECL_ATTRIBUTES (var));
   23552              :     }
   23553           71 : }
   23554              : 
   23555              : /* OpenMP 2.5:
   23556              :    # pragma omp atomic new-line
   23557              :      expression-stmt
   23558              : 
   23559              :    expression-stmt:
   23560              :      x binop= expr | x++ | ++x | x-- | --x
   23561              :    binop:
   23562              :      +, *, -, /, &, ^, |, <<, >>
   23563              : 
   23564              :   where x is an lvalue expression with scalar type.
   23565              : 
   23566              :    OpenMP 3.1:
   23567              :    # pragma omp atomic new-line
   23568              :      update-stmt
   23569              : 
   23570              :    # pragma omp atomic read new-line
   23571              :      read-stmt
   23572              : 
   23573              :    # pragma omp atomic write new-line
   23574              :      write-stmt
   23575              : 
   23576              :    # pragma omp atomic update new-line
   23577              :      update-stmt
   23578              : 
   23579              :    # pragma omp atomic capture new-line
   23580              :      capture-stmt
   23581              : 
   23582              :    # pragma omp atomic capture new-line
   23583              :      capture-block
   23584              : 
   23585              :    read-stmt:
   23586              :      v = x
   23587              :    write-stmt:
   23588              :      x = expr
   23589              :    update-stmt:
   23590              :      expression-stmt | x = x binop expr
   23591              :    capture-stmt:
   23592              :      v = expression-stmt
   23593              :    capture-block:
   23594              :      { v = x; update-stmt; } | { update-stmt; v = x; }
   23595              : 
   23596              :    OpenMP 4.0:
   23597              :    update-stmt:
   23598              :      expression-stmt | x = x binop expr | x = expr binop x
   23599              :    capture-stmt:
   23600              :      v = update-stmt
   23601              :    capture-block:
   23602              :      { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }
   23603              : 
   23604              :    OpenMP 5.1:
   23605              :    # pragma omp atomic compare new-line
   23606              :      conditional-update-atomic
   23607              : 
   23608              :    # pragma omp atomic compare capture new-line
   23609              :      conditional-update-capture-atomic
   23610              : 
   23611              :    conditional-update-atomic:
   23612              :      cond-expr-stmt | cond-update-stmt
   23613              :    cond-expr-stmt:
   23614              :      x = expr ordop x ? expr : x;
   23615              :      x = x ordop expr ? expr : x;
   23616              :      x = x == e ? d : x;
   23617              :    cond-update-stmt:
   23618              :      if (expr ordop x) { x = expr; }
   23619              :      if (x ordop expr) { x = expr; }
   23620              :      if (x == e) { x = d; }
   23621              :    ordop:
   23622              :      <, >
   23623              :    conditional-update-capture-atomic:
   23624              :      v = cond-expr-stmt
   23625              :      { v = x; cond-expr-stmt }
   23626              :      { cond-expr-stmt v = x; }
   23627              :      { v = x; cond-update-stmt }
   23628              :      { cond-update-stmt v = x; }
   23629              :      if (x == e) { x = d; } else { v = x; }
   23630              :      { r = x == e; if (r) { x = d; } }
   23631              :      { r = x == e; if (r) { x = d; } else { v = x; } }
   23632              : 
   23633              :   where x, r and v are lvalue expressions with scalar type,
   23634              :   expr, e and d are expressions with scalar type and e might be
   23635              :   the same as v.
   23636              : 
   23637              :   LOC is the location of the #pragma token.  */
   23638              : 
   23639              : static void
   23640         1719 : c_parser_omp_atomic (location_t loc, c_parser *parser, bool openacc)
   23641              : {
   23642         1719 :   tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, r = NULL_TREE;
   23643         1719 :   tree lhs1 = NULL_TREE, rhs1 = NULL_TREE;
   23644         1719 :   tree stmt, orig_lhs, unfolded_lhs = NULL_TREE, unfolded_lhs1 = NULL_TREE;
   23645         1719 :   enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
   23646         1719 :   enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
   23647         1719 :   struct c_expr expr;
   23648         1719 :   location_t eloc;
   23649         1719 :   bool structured_block = false;
   23650         1719 :   bool swapped = false;
   23651         1719 :   bool non_lvalue_p;
   23652         1719 :   tree clauses = NULL_TREE;
   23653         1719 :   bool capture = false;
   23654         1719 :   bool compare = false;
   23655         1719 :   bool weak = false;
   23656         1719 :   enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
   23657         1719 :   bool no_semicolon = false;
   23658         1719 :   bool extra_scope = false;
   23659              : 
   23660         3198 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   23661              :     {
   23662         1489 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   23663         1489 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   23664           82 :         c_parser_consume_token (parser);
   23665              : 
   23666         1489 :       if (c_parser_next_token_is (parser, CPP_NAME))
   23667              :         {
   23668         1485 :           const char *p
   23669         1485 :             = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   23670         1485 :           location_t cloc = c_parser_peek_token (parser)->location;
   23671         1485 :           enum tree_code new_code = ERROR_MARK;
   23672         1485 :           enum omp_memory_order new_memory_order
   23673              :             = OMP_MEMORY_ORDER_UNSPECIFIED;
   23674         1485 :           bool new_capture = false;
   23675         1485 :           bool new_compare = false;
   23676         1485 :           bool new_weak = false;
   23677         1485 :           enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;
   23678              : 
   23679         1485 :           if (!strcmp (p, "read"))
   23680              :             new_code = OMP_ATOMIC_READ;
   23681         1227 :           else if (!strcmp (p, "write"))
   23682              :             new_code = NOP_EXPR;
   23683         1050 :           else if (!strcmp (p, "update"))
   23684              :             new_code = OMP_ATOMIC;
   23685          890 :           else if (openacc && !strcmp (p, "capture"))
   23686              :             new_code = OMP_ATOMIC_CAPTURE_NEW;
   23687            4 :           else if (openacc)
   23688              :             {
   23689            4 :               p = NULL;
   23690            4 :               error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
   23691              :                               "or %<capture%> clause");
   23692              :             }
   23693          652 :           else if (!strcmp (p, "capture"))
   23694              :             new_capture = true;
   23695          408 :           else if (!strcmp (p, "compare"))
   23696              :             new_compare = true;
   23697          235 :           else if (!strcmp (p, "weak"))
   23698              :             new_weak = true;
   23699          222 :           else if (!strcmp (p, "fail"))
   23700              :             {
   23701           33 :               matching_parens parens;
   23702              : 
   23703           33 :               c_parser_consume_token (parser);
   23704           33 :               if (!parens.require_open (parser))
   23705            1 :                 continue;
   23706              : 
   23707           32 :               if (c_parser_next_token_is (parser, CPP_NAME))
   23708              :                 {
   23709           30 :                   const char *q
   23710           30 :                     = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   23711              : 
   23712           30 :                   if (!strcmp (q, "seq_cst"))
   23713              :                     new_fail = OMP_MEMORY_ORDER_SEQ_CST;
   23714           24 :                   else if (!strcmp (q, "acquire"))
   23715              :                     new_fail = OMP_MEMORY_ORDER_ACQUIRE;
   23716           17 :                   else if (!strcmp (q, "relaxed"))
   23717              :                     new_fail = OMP_MEMORY_ORDER_RELAXED;
   23718              :                 }
   23719              : 
   23720              :               if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
   23721              :                 {
   23722           27 :                   c_parser_consume_token (parser);
   23723           27 :                   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
   23724            2 :                     error_at (cloc, "too many %qs clauses", "fail");
   23725              :                   else
   23726              :                     fail = new_fail;
   23727              :                 }
   23728              :               else
   23729            5 :                 c_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
   23730              :                                         "or %<relaxed%>");
   23731           32 :               parens.skip_until_found_close (parser);
   23732           32 :               continue;
   23733           32 :             }
   23734          189 :           else if (!strcmp (p, "seq_cst"))
   23735              :             new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   23736          112 :           else if (!strcmp (p, "acq_rel"))
   23737              :             new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
   23738          100 :           else if (!strcmp (p, "release"))
   23739              :             new_memory_order = OMP_MEMORY_ORDER_RELEASE;
   23740           70 :           else if (!strcmp (p, "acquire"))
   23741              :             new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   23742           57 :           else if (!strcmp (p, "relaxed"))
   23743              :             new_memory_order = OMP_MEMORY_ORDER_RELAXED;
   23744           31 :           else if (!strcmp (p, "hint"))
   23745              :             {
   23746           29 :               c_parser_consume_token (parser);
   23747           29 :               clauses = c_parser_omp_clause_hint (parser, clauses);
   23748           29 :               continue;
   23749              :             }
   23750              :           else
   23751              :             {
   23752            2 :               p = NULL;
   23753            2 :               error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
   23754              :                               "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
   23755              :                               "%<seq_cst%>, %<acq_rel%>, %<release%>, "
   23756              :                               "%<relaxed%> or %<hint%> clause");
   23757              :             }
   23758            6 :           if (p)
   23759              :             {
   23760         1417 :               if (new_code != ERROR_MARK)
   23761              :                 {
   23762              :                   /* OpenACC permits 'update capture'.  */
   23763          829 :                   if (openacc
   23764          829 :                       && code == OMP_ATOMIC
   23765            4 :                       && new_code == OMP_ATOMIC_CAPTURE_NEW)
   23766              :                     code = new_code;
   23767          826 :                   else if (code != ERROR_MARK)
   23768            5 :                     error_at (cloc, "too many atomic clauses");
   23769              :                   else
   23770              :                     code = new_code;
   23771              :                 }
   23772          588 :               else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
   23773              :                 {
   23774          158 :                   if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
   23775           35 :                     error_at (cloc, "too many memory order clauses");
   23776              :                   else
   23777              :                     memory_order = new_memory_order;
   23778              :                 }
   23779          430 :               else if (new_capture)
   23780              :                 {
   23781          244 :                   if (capture)
   23782            1 :                     error_at (cloc, "too many %qs clauses", "capture");
   23783              :                   else
   23784              :                     capture = true;
   23785              :                 }
   23786          186 :               else if (new_compare)
   23787              :                 {
   23788          173 :                   if (compare)
   23789            1 :                     error_at (cloc, "too many %qs clauses", "compare");
   23790              :                   else
   23791              :                     compare = true;
   23792              :                 }
   23793           13 :               else if (new_weak)
   23794              :                 {
   23795           13 :                   if (weak)
   23796            1 :                     error_at (cloc, "too many %qs clauses", "weak");
   23797              :                   else
   23798              :                     weak = true;
   23799              :                 }
   23800         1417 :               c_parser_consume_token (parser);
   23801         1417 :               continue;
   23802              :             }
   23803              :         }
   23804              :       break;
   23805              :     }
   23806         1719 :   c_parser_skip_to_pragma_eol (parser);
   23807              : 
   23808         1719 :   if (code == ERROR_MARK)
   23809          898 :     code = OMP_ATOMIC;
   23810         1719 :   if (capture)
   23811              :     {
   23812          243 :       if (code != OMP_ATOMIC)
   23813            2 :         error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
   23814              :                        "clauses", "capture");
   23815              :       else
   23816              :         code = OMP_ATOMIC_CAPTURE_NEW;
   23817              :     }
   23818         1719 :   if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
   23819              :     {
   23820            2 :       error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
   23821              :                       "clauses", "compare");
   23822            2 :       compare = false;
   23823              :     }
   23824         1719 :   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
   23825              :     {
   23826            5 :       error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
   23827            5 :       fail = OMP_MEMORY_ORDER_UNSPECIFIED;
   23828              :     }
   23829         1719 :   if (weak && !compare)
   23830              :     {
   23831            5 :       error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
   23832            5 :       weak = false;
   23833              :     }
   23834         1719 :   if (openacc)
   23835              :     memory_order = OMP_MEMORY_ORDER_RELAXED;
   23836         1410 :   else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
   23837              :     {
   23838         1287 :       omp_requires_mask
   23839         1287 :         = (enum omp_requires) (omp_requires_mask
   23840              :                                | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
   23841         1287 :       switch ((enum omp_memory_order)
   23842              :               (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
   23843              :         {
   23844              :         case OMP_MEMORY_ORDER_UNSPECIFIED:
   23845              :         case OMP_MEMORY_ORDER_RELAXED:
   23846              :           memory_order = OMP_MEMORY_ORDER_RELAXED;
   23847              :           break;
   23848              :         case OMP_MEMORY_ORDER_SEQ_CST:
   23849            9 :           memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   23850              :           break;
   23851            4 :         case OMP_MEMORY_ORDER_ACQUIRE:
   23852            4 :           if (code == NOP_EXPR)  /* atomic write */
   23853              :             {
   23854            1 :               error_at (loc, "%<#pragma omp atomic write%> incompatible with "
   23855              :                              "%<acquire%> clause implicitly provided by a "
   23856              :                              "%<requires%> directive");
   23857            1 :               memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   23858              :             }
   23859              :           else
   23860              :             memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   23861              :           break;
   23862            3 :         case OMP_MEMORY_ORDER_RELEASE:
   23863            3 :           if (code == OMP_ATOMIC_READ)
   23864              :             {
   23865            1 :               error_at (loc, "%<#pragma omp atomic read%> incompatible with "
   23866              :                              "%<release%> clause implicitly provided by a "
   23867              :                              "%<requires%> directive");
   23868            1 :               memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   23869              :             }
   23870              :           else
   23871              :             memory_order = OMP_MEMORY_ORDER_RELEASE;
   23872              :           break;
   23873            9 :         case OMP_MEMORY_ORDER_ACQ_REL:
   23874            9 :           switch (code)
   23875              :             {
   23876              :             case OMP_ATOMIC_READ:
   23877              :               memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   23878              :               break;
   23879              :             case NOP_EXPR: /* atomic write */
   23880            5 :               memory_order = OMP_MEMORY_ORDER_RELEASE;
   23881              :               break;
   23882              :             default:
   23883         1719 :               memory_order = OMP_MEMORY_ORDER_ACQ_REL;
   23884              :               break;
   23885              :             }
   23886              :           break;
   23887            0 :         default:
   23888            0 :           gcc_unreachable ();
   23889              :         }
   23890              :     }
   23891              :   else
   23892          123 :     switch (code)
   23893              :       {
   23894           25 :       case OMP_ATOMIC_READ:
   23895           25 :         if (memory_order == OMP_MEMORY_ORDER_RELEASE)
   23896              :           {
   23897            1 :             error_at (loc, "%<#pragma omp atomic read%> incompatible with "
   23898              :                            "%<release%> clause");
   23899            1 :             memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   23900              :           }
   23901           24 :         else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
   23902            6 :           memory_order = OMP_MEMORY_ORDER_ACQUIRE;
   23903              :         break;
   23904           16 :       case NOP_EXPR: /* atomic write */
   23905           16 :         if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
   23906              :           {
   23907            1 :             error_at (loc, "%<#pragma omp atomic write%> incompatible with "
   23908              :                            "%<acquire%> clause");
   23909            1 :             memory_order = OMP_MEMORY_ORDER_SEQ_CST;
   23910              :           }
   23911           15 :         else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
   23912            5 :           memory_order = OMP_MEMORY_ORDER_RELEASE;
   23913              :         break;
   23914              :       default:
   23915              :         break;
   23916              :       }
   23917         1719 :   if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
   23918           20 :     memory_order
   23919           20 :       = (enum omp_memory_order) (memory_order
   23920              :                                  | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));
   23921              : 
   23922         1719 :   switch (code)
   23923              :     {
   23924          434 :     case OMP_ATOMIC_READ:
   23925          434 :     case NOP_EXPR: /* atomic write */
   23926          434 :       v = c_parser_cast_expression (parser, NULL).value;
   23927          434 :       non_lvalue_p = !lvalue_p (v);
   23928          434 :       v = c_fully_fold (v, false, NULL, true);
   23929          434 :       if (v == error_mark_node)
   23930            0 :         goto saw_error;
   23931          434 :       if (non_lvalue_p)
   23932            4 :         v = non_lvalue (v);
   23933          434 :       loc = c_parser_peek_token (parser)->location;
   23934          434 :       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   23935            0 :         goto saw_error;
   23936          434 :       if (code == NOP_EXPR)
   23937              :         {
   23938          176 :           eloc = c_parser_peek_token (parser)->location;
   23939          176 :           expr = c_parser_expression (parser);
   23940          176 :           expr = default_function_array_read_conversion (eloc, expr);
   23941              :           /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
   23942              :              opcode.  */
   23943          176 :           code = OMP_ATOMIC;
   23944          176 :           lhs = v;
   23945          176 :           v = NULL_TREE;
   23946          176 :           rhs = c_fully_fold (expr.value, false, NULL);
   23947          176 :           if (rhs == error_mark_node)
   23948            0 :             goto saw_error;
   23949              :         }
   23950              :       else
   23951              :         {
   23952          258 :           lhs = c_parser_cast_expression (parser, NULL).value;
   23953          258 :           non_lvalue_p = !lvalue_p (lhs);
   23954          258 :           lhs = c_fully_fold (lhs, false, NULL, true);
   23955          258 :           if (lhs == error_mark_node)
   23956            0 :             goto saw_error;
   23957          258 :           if (non_lvalue_p)
   23958            2 :             lhs = non_lvalue (lhs);
   23959              :         }
   23960          434 :       goto done;
   23961          473 :     case OMP_ATOMIC_CAPTURE_NEW:
   23962          473 :       if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   23963              :         {
   23964          314 :           c_parser_consume_token (parser);
   23965          314 :           structured_block = true;
   23966              :         }
   23967          159 :       else if (compare
   23968          188 :                && c_parser_next_token_is_keyword (parser, RID_IF))
   23969              :         break;
   23970              :       else
   23971              :         {
   23972          142 :           v = c_parser_cast_expression (parser, NULL).value;
   23973          142 :           non_lvalue_p = !lvalue_p (v);
   23974          142 :           v = c_fully_fold (v, false, NULL, true);
   23975          142 :           if (v == error_mark_node)
   23976            0 :             goto saw_error;
   23977          142 :           if (non_lvalue_p)
   23978            2 :             v = non_lvalue (v);
   23979          142 :           if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   23980            0 :             goto saw_error;
   23981          154 :           if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
   23982              :             {
   23983            1 :               eloc = c_parser_peek_token (parser)->location;
   23984            1 :               error_at (eloc, "expected expression");
   23985            1 :               goto saw_error;
   23986              :             }
   23987              :         }
   23988              :       break;
   23989              :     default:
   23990              :       break;
   23991              :     }
   23992              : 
   23993              :   /* For structured_block case we don't know yet whether
   23994              :      old or new x should be captured.  */
   23995         1284 : restart:
   23996         1676 :   if (compare && c_parser_next_token_is_keyword (parser, RID_IF))
   23997              :     {
   23998           85 :       c_parser_consume_token (parser);
   23999              : 
   24000           85 :       matching_parens parens;
   24001           85 :       if (!parens.require_open (parser))
   24002           34 :         goto saw_error;
   24003           84 :       eloc = c_parser_peek_token (parser)->location;
   24004           84 :       c_expr cmp_expr;
   24005           84 :       if (r)
   24006              :         {
   24007           17 :           cmp_expr = c_parser_cast_expression (parser, NULL);
   24008           17 :           cmp_expr = default_function_array_conversion (eloc, cmp_expr);
   24009              :         }
   24010              :       else
   24011           67 :         cmp_expr = c_parser_binary_expression (parser, NULL, void_list_node);
   24012           84 :       parens.skip_until_found_close (parser);
   24013           84 :       if (cmp_expr.value == error_mark_node)
   24014            0 :         goto saw_error;
   24015           84 :       if (r)
   24016              :         {
   24017           17 :           if (!c_tree_equal (cmp_expr.value, unfolded_lhs))
   24018            1 :             goto bad_if;
   24019           16 :           cmp_expr.value = rhs1;
   24020           16 :           rhs1 = NULL_TREE;
   24021           16 :           gcc_assert (TREE_CODE (cmp_expr.value) == EQ_EXPR);
   24022              :         }
   24023           83 :       if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
   24024              :         ;
   24025           36 :       else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
   24026              :         {
   24027            4 :           error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
   24028              :                     "expected %<==%> comparison in %<if%> condition");
   24029            2 :           goto saw_error;
   24030              :         }
   24031           34 :       else if (TREE_CODE (cmp_expr.value) != GT_EXPR
   24032           25 :                && TREE_CODE (cmp_expr.value) != LT_EXPR)
   24033              :         {
   24034           16 :           error_at (EXPR_LOC_OR_LOC (cmp_expr.value, eloc),
   24035              :                     "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
   24036              :                     "condition");
   24037           10 :           goto saw_error;
   24038              :         }
   24039           71 :       if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   24040            2 :         goto saw_error;
   24041              : 
   24042           69 :       extra_scope = true;
   24043           69 :       eloc = c_parser_peek_token (parser)->location;
   24044           69 :       expr = c_parser_cast_expression (parser, NULL);
   24045           69 :       lhs = expr.value;
   24046           69 :       expr = default_function_array_conversion (eloc, expr);
   24047           69 :       unfolded_lhs = expr.value;
   24048           69 :       lhs = c_fully_fold (lhs, false, NULL, true);
   24049           69 :       orig_lhs = lhs;
   24050           69 :       if (lhs == error_mark_node)
   24051            0 :         goto saw_error;
   24052           69 :       if (!lvalue_p (unfolded_lhs))
   24053            0 :         lhs = non_lvalue (lhs);
   24054           69 :       if (!c_parser_next_token_is (parser, CPP_EQ))
   24055              :         {
   24056            1 :           c_parser_error (parser, "expected %<=%>");
   24057            1 :           goto saw_error;
   24058              :         }
   24059           68 :       c_parser_consume_token (parser);
   24060           68 :       eloc = c_parser_peek_token (parser)->location;
   24061           68 :       expr = c_parser_expr_no_commas (parser, NULL);
   24062           68 :       rhs1 = expr.value;
   24063              : 
   24064           68 :       if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
   24065            1 :         goto saw_error;
   24066              : 
   24067           67 :       if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
   24068            1 :         goto saw_error;
   24069              : 
   24070           66 :       extra_scope = false;
   24071           66 :       no_semicolon = true;
   24072              : 
   24073           66 :       if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), unfolded_lhs))
   24074              :         {
   24075           59 :           if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
   24076              :             {
   24077           44 :               opcode = COND_EXPR;
   24078           44 :               rhs = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
   24079              :                                   false, NULL, true);
   24080           44 :               rhs1 = c_fully_fold (rhs1, false, NULL, true);
   24081              :             }
   24082           15 :           else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), rhs1))
   24083              :             {
   24084            7 :               opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
   24085           13 :                         ? MIN_EXPR : MAX_EXPR);
   24086           13 :               rhs = c_fully_fold (rhs1, false, NULL, true);
   24087           13 :               rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 0),
   24088              :                                    false, NULL, true);
   24089              :             }
   24090              :           else
   24091            2 :             goto bad_if;
   24092              :         }
   24093            7 :       else if (TREE_CODE (cmp_expr.value) == EQ_EXPR)
   24094            2 :         goto bad_if;
   24095            5 :       else if (c_tree_equal (TREE_OPERAND (cmp_expr.value, 1), unfolded_lhs)
   24096            5 :                && c_tree_equal (TREE_OPERAND (cmp_expr.value, 0), rhs1))
   24097              :         {
   24098            2 :           opcode = (TREE_CODE (cmp_expr.value) == GT_EXPR
   24099            3 :                     ? MAX_EXPR : MIN_EXPR);
   24100            3 :           rhs = c_fully_fold (rhs1, false, NULL, true);
   24101            3 :           rhs1 = c_fully_fold (TREE_OPERAND (cmp_expr.value, 1),
   24102              :                                false, NULL, true);
   24103              :         }
   24104              :       else
   24105              :         {
   24106            8 :         bad_if:
   24107            8 :           c_parser_error (parser,
   24108              :                           "invalid form of %<#pragma omp atomic compare%>");
   24109            8 :           goto saw_error;
   24110              :         }
   24111              : 
   24112           60 :       if (c_parser_next_token_is_keyword (parser, RID_ELSE))
   24113              :         {
   24114           24 :           if (code != OMP_ATOMIC_CAPTURE_NEW
   24115           22 :               || (structured_block && r == NULL_TREE)
   24116           21 :               || TREE_CODE (cmp_expr.value) != EQ_EXPR)
   24117              :             {
   24118            3 :               eloc = c_parser_peek_token (parser)->location;
   24119            3 :               error_at (eloc, "unexpected %<else%>");
   24120            3 :               goto saw_error;
   24121              :             }
   24122              : 
   24123           21 :           c_parser_consume_token (parser);
   24124              : 
   24125           21 :           if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   24126            1 :             goto saw_error;
   24127              : 
   24128           20 :           extra_scope = true;
   24129           20 :           v = c_parser_cast_expression (parser, NULL).value;
   24130           20 :           non_lvalue_p = !lvalue_p (v);
   24131           20 :           v = c_fully_fold (v, false, NULL, true);
   24132           20 :           if (v == error_mark_node)
   24133            0 :             goto saw_error;
   24134           20 :           if (non_lvalue_p)
   24135            0 :             v = non_lvalue (v);
   24136           20 :           if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   24137            1 :             goto saw_error;
   24138              : 
   24139           19 :           expr = c_parser_expr_no_commas (parser, NULL);
   24140              : 
   24141           19 :           if (!c_tree_equal (expr.value, unfolded_lhs))
   24142            1 :             goto bad_if;
   24143              : 
   24144           18 :           if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
   24145            1 :             goto saw_error;
   24146              : 
   24147           17 :           if (!c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>"))
   24148            0 :             goto saw_error;
   24149              : 
   24150           17 :           extra_scope = false;
   24151           17 :           code = OMP_ATOMIC_CAPTURE_OLD;
   24152           17 :           if (r == NULL_TREE)
   24153              :             /* Signal to c_finish_omp_atomic that in
   24154              :                if (x == e) { x = d; } else { v = x; }
   24155              :                case the store to v should be conditional.  */
   24156           10 :             r = void_list_node;
   24157              :         }
   24158           36 :       else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
   24159              :         {
   24160            1 :           c_parser_require_keyword (parser, RID_ELSE, "expected %<else%>");
   24161            1 :           goto saw_error;
   24162              :         }
   24163           35 :       else if (code == OMP_ATOMIC_CAPTURE_NEW
   24164           35 :                && r != NULL_TREE
   24165            9 :                && v == NULL_TREE)
   24166           52 :         code = OMP_ATOMIC;
   24167           52 :       goto stmt_done;
   24168              :     }
   24169         1383 :   eloc = c_parser_peek_token (parser)->location;
   24170         1383 :   expr = c_parser_cast_expression (parser, NULL);
   24171         1383 :   lhs = expr.value;
   24172         1383 :   expr = default_function_array_conversion (eloc, expr);
   24173         1383 :   unfolded_lhs = expr.value;
   24174         1383 :   lhs = c_fully_fold (lhs, false, NULL, true);
   24175         1383 :   orig_lhs = lhs;
   24176         1383 :   switch (TREE_CODE (lhs))
   24177              :     {
   24178            4 :     invalid_compare:
   24179            4 :       error_at (eloc, "invalid form of %<pragma omp atomic compare%>");
   24180              :       /* FALLTHRU */
   24181           84 :     case ERROR_MARK:
   24182           84 :     saw_error:
   24183           84 :       c_parser_skip_to_end_of_block_or_statement (parser);
   24184           90 :       if (extra_scope && c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   24185            4 :         c_parser_consume_token (parser);
   24186           84 :       if (structured_block)
   24187              :         {
   24188           10 :           if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   24189            9 :             c_parser_consume_token (parser);
   24190            1 :           else if (code == OMP_ATOMIC_CAPTURE_NEW)
   24191              :             {
   24192            1 :               c_parser_skip_to_end_of_block_or_statement (parser);
   24193            1 :               if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   24194            1 :                 c_parser_consume_token (parser);
   24195              :             }
   24196              :         }
   24197           84 :       return;
   24198              : 
   24199          159 :     case POSTINCREMENT_EXPR:
   24200          159 :       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
   24201           20 :         code = OMP_ATOMIC_CAPTURE_OLD;
   24202              :       /* FALLTHROUGH */
   24203          221 :     case PREINCREMENT_EXPR:
   24204          221 :       lhs = TREE_OPERAND (lhs, 0);
   24205          221 :       unfolded_lhs = NULL_TREE;
   24206          221 :       opcode = PLUS_EXPR;
   24207          221 :       rhs = integer_one_node;
   24208          221 :       if (compare)
   24209            2 :         goto invalid_compare;
   24210              :       break;
   24211              : 
   24212           24 :     case POSTDECREMENT_EXPR:
   24213           24 :       if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
   24214            2 :         code = OMP_ATOMIC_CAPTURE_OLD;
   24215              :       /* FALLTHROUGH */
   24216           52 :     case PREDECREMENT_EXPR:
   24217           52 :       lhs = TREE_OPERAND (lhs, 0);
   24218           52 :       unfolded_lhs = NULL_TREE;
   24219           52 :       opcode = MINUS_EXPR;
   24220           52 :       rhs = integer_one_node;
   24221           52 :       if (compare)
   24222            2 :         goto invalid_compare;
   24223              :       break;
   24224              : 
   24225           12 :     case COMPOUND_EXPR:
   24226           12 :       if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
   24227           12 :           && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
   24228           12 :           && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
   24229           12 :           && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
   24230           24 :           && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
   24231              :                                               (TREE_OPERAND (lhs, 1), 0), 0))))
   24232              :         /* Undo effects of boolean_increment for post {in,de}crement.  */
   24233           12 :         lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
   24234              :       /* FALLTHRU */
   24235           24 :     case MODIFY_EXPR:
   24236           24 :       if (TREE_CODE (lhs) == MODIFY_EXPR
   24237           24 :           && C_BOOLEAN_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0))))
   24238              :         {
   24239              :           /* Undo effects of boolean_increment.  */
   24240           24 :           if (integer_onep (TREE_OPERAND (lhs, 1)))
   24241              :             {
   24242              :               /* This is pre or post increment.  */
   24243           12 :               rhs = TREE_OPERAND (lhs, 1);
   24244           12 :               lhs = TREE_OPERAND (lhs, 0);
   24245           12 :               unfolded_lhs = NULL_TREE;
   24246           12 :               opcode = NOP_EXPR;
   24247           12 :               if (code == OMP_ATOMIC_CAPTURE_NEW
   24248           12 :                   && !structured_block
   24249            2 :                   && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
   24250            1 :                 code = OMP_ATOMIC_CAPTURE_OLD;
   24251           12 :               if (compare)
   24252            0 :                 goto invalid_compare;
   24253              :               break;
   24254              :             }
   24255           12 :           if (TREE_CODE (TREE_OPERAND (lhs, 1)) == TRUTH_NOT_EXPR
   24256           12 :               && TREE_OPERAND (lhs, 0)
   24257           12 :                  == TREE_OPERAND (TREE_OPERAND (lhs, 1), 0))
   24258              :             {
   24259              :               /* This is pre or post decrement.  */
   24260           12 :               rhs = TREE_OPERAND (lhs, 1);
   24261           12 :               lhs = TREE_OPERAND (lhs, 0);
   24262           12 :               unfolded_lhs = NULL_TREE;
   24263           12 :               opcode = NOP_EXPR;
   24264           12 :               if (code == OMP_ATOMIC_CAPTURE_NEW
   24265           12 :                   && !structured_block
   24266            2 :                   && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
   24267            1 :                 code = OMP_ATOMIC_CAPTURE_OLD;
   24268           12 :               if (compare)
   24269            0 :                 goto invalid_compare;
   24270              :               break;
   24271              :             }
   24272              :         }
   24273              :       /* FALLTHRU */
   24274         1082 :     default:
   24275         1082 :       if (!lvalue_p (unfolded_lhs))
   24276            5 :         lhs = non_lvalue (lhs);
   24277         1201 :       if (compare && !c_parser_next_token_is (parser, CPP_EQ))
   24278              :         {
   24279            7 :           c_parser_error (parser, "expected %<=%>");
   24280            7 :           goto saw_error;
   24281              :         }
   24282         1075 :       switch (c_parser_peek_token (parser)->type)
   24283              :         {
   24284              :         case CPP_MULT_EQ:
   24285              :           opcode = MULT_EXPR;
   24286              :           break;
   24287              :         case CPP_DIV_EQ:
   24288              :           opcode = TRUNC_DIV_EXPR;
   24289              :           break;
   24290              :         case CPP_PLUS_EQ:
   24291              :           opcode = PLUS_EXPR;
   24292              :           break;
   24293              :         case CPP_MINUS_EQ:
   24294              :           opcode = MINUS_EXPR;
   24295              :           break;
   24296              :         case CPP_LSHIFT_EQ:
   24297              :           opcode = LSHIFT_EXPR;
   24298              :           break;
   24299              :         case CPP_RSHIFT_EQ:
   24300              :           opcode = RSHIFT_EXPR;
   24301              :           break;
   24302              :         case CPP_AND_EQ:
   24303              :           opcode = BIT_AND_EXPR;
   24304              :           break;
   24305              :         case CPP_OR_EQ:
   24306              :           opcode = BIT_IOR_EXPR;
   24307              :           break;
   24308              :         case CPP_XOR_EQ:
   24309              :           opcode = BIT_XOR_EXPR;
   24310              :           break;
   24311          556 :         case CPP_EQ:
   24312          556 :           c_parser_consume_token (parser);
   24313          556 :           eloc = c_parser_peek_token (parser)->location;
   24314          556 :           expr = c_parser_expr_no_commas (parser, NULL, unfolded_lhs);
   24315          556 :           rhs1 = expr.value;
   24316          556 :           switch (TREE_CODE (rhs1))
   24317              :             {
   24318          289 :             case MULT_EXPR:
   24319          289 :             case TRUNC_DIV_EXPR:
   24320          289 :             case RDIV_EXPR:
   24321          289 :             case PLUS_EXPR:
   24322          289 :             case MINUS_EXPR:
   24323          289 :             case LSHIFT_EXPR:
   24324          289 :             case RSHIFT_EXPR:
   24325          289 :             case BIT_AND_EXPR:
   24326          289 :             case BIT_IOR_EXPR:
   24327          289 :             case BIT_XOR_EXPR:
   24328          289 :               if (compare)
   24329              :                 break;
   24330          282 :               if (c_tree_equal (TREE_OPERAND (rhs1, 0), unfolded_lhs))
   24331              :                 {
   24332          147 :                   opcode = TREE_CODE (rhs1);
   24333          147 :                   rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
   24334              :                                       true);
   24335          147 :                   rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
   24336              :                                        true);
   24337          147 :                   goto stmt_done;
   24338              :                 }
   24339          135 :               if (c_tree_equal (TREE_OPERAND (rhs1, 1), unfolded_lhs))
   24340              :                 {
   24341          117 :                   opcode = TREE_CODE (rhs1);
   24342          117 :                   rhs = c_fully_fold (TREE_OPERAND (rhs1, 0), false, NULL,
   24343              :                                       true);
   24344          117 :                   rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
   24345              :                                        true);
   24346          117 :                   swapped = !commutative_tree_code (opcode);
   24347          117 :                   goto stmt_done;
   24348              :                 }
   24349              :               break;
   24350           69 :             case COND_EXPR:
   24351           69 :               if (!compare)
   24352              :                 break;
   24353           66 :               if (TREE_CODE (TREE_OPERAND (rhs1, 0)) != GT_EXPR
   24354           44 :                   && TREE_CODE (TREE_OPERAND (rhs1, 0)) != LT_EXPR
   24355           97 :                   && TREE_CODE (TREE_OPERAND (rhs1, 0)) != EQ_EXPR)
   24356              :                 break;
   24357           63 :               if (!TREE_OPERAND (rhs1, 1))
   24358              :                 break;
   24359           63 :               if (!c_tree_equal (TREE_OPERAND (rhs1, 2), unfolded_lhs))
   24360              :                 break;
   24361           58 :               if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
   24362              :                                 unfolded_lhs))
   24363              :                 {
   24364           39 :                   if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
   24365              :                     {
   24366           23 :                       opcode = COND_EXPR;
   24367           23 :                       rhs = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
   24368              :                                                                       0), 1),
   24369              :                                           false, NULL, true);
   24370           23 :                       rhs1 = c_fully_fold (TREE_OPERAND (rhs1, 1), false,
   24371              :                                            NULL, true);
   24372           23 :                       goto stmt_done;
   24373              :                     }
   24374           16 :                   if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
   24375           16 :                                     TREE_OPERAND (rhs1, 1)))
   24376              :                     {
   24377           21 :                       opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
   24378           14 :                                 ? MIN_EXPR : MAX_EXPR);
   24379           14 :                       rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
   24380              :                                           true);
   24381           14 :                       rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
   24382              :                                                                        0), 0),
   24383              :                                            false, NULL, true);
   24384           14 :                       goto stmt_done;
   24385              :                     }
   24386              :                 }
   24387           19 :               else if (TREE_CODE (TREE_OPERAND (rhs1, 0)) == EQ_EXPR)
   24388              :                 break;
   24389           17 :               else if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 1),
   24390              :                                      unfolded_lhs))
   24391              :                 {
   24392           15 :                   if (c_tree_equal (TREE_OPERAND (TREE_OPERAND (rhs1, 0), 0),
   24393           15 :                                     TREE_OPERAND (rhs1, 1)))
   24394              :                     {
   24395           18 :                       opcode = (TREE_CODE (TREE_OPERAND (rhs1, 0)) == GT_EXPR
   24396           15 :                                 ? MAX_EXPR : MIN_EXPR);
   24397           15 :                       rhs = c_fully_fold (TREE_OPERAND (rhs1, 1), false, NULL,
   24398              :                                           true);
   24399           15 :                       rhs1 = c_fully_fold (TREE_OPERAND (TREE_OPERAND (rhs1,
   24400              :                                                                        0), 1),
   24401              :                                            false, NULL, true);
   24402           15 :                       goto stmt_done;
   24403              :                     }
   24404              :                 }
   24405              :               break;
   24406           17 :             case EQ_EXPR:
   24407           17 :               if (!compare
   24408           17 :                   || code != OMP_ATOMIC_CAPTURE_NEW
   24409           17 :                   || !structured_block
   24410           17 :                   || v
   24411           17 :                   || r)
   24412              :                 break;
   24413           17 :               if (c_parser_next_token_is (parser, CPP_SEMICOLON)
   24414           17 :                   && c_parser_peek_2nd_token (parser)->keyword == RID_IF)
   24415              :                 {
   24416           17 :                   r = lhs;
   24417           17 :                   lhs = NULL_TREE;
   24418           17 :                   c_parser_consume_token (parser);
   24419           17 :                   goto restart;
   24420              :                 }
   24421              :               break;
   24422            0 :             case ERROR_MARK:
   24423            0 :               goto saw_error;
   24424              :             default:
   24425              :               break;
   24426              :             }
   24427          223 :           if (c_parser_peek_token (parser)->type == CPP_SEMICOLON)
   24428              :             {
   24429          223 :               if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
   24430              :                 {
   24431          167 :                   code = OMP_ATOMIC_CAPTURE_OLD;
   24432          167 :                   v = lhs;
   24433          167 :                   lhs = NULL_TREE;
   24434          167 :                   expr = default_function_array_read_conversion (eloc, expr);
   24435          167 :                   unfolded_lhs1 = expr.value;
   24436          167 :                   lhs1 = c_fully_fold (unfolded_lhs1, false, NULL, true);
   24437          167 :                   rhs1 = NULL_TREE;
   24438          167 :                   c_parser_consume_token (parser);
   24439          167 :                   goto restart;
   24440              :                 }
   24441           56 :               if (structured_block && !compare)
   24442              :                 {
   24443           26 :                   opcode = NOP_EXPR;
   24444           26 :                   expr = default_function_array_read_conversion (eloc, expr);
   24445           26 :                   rhs = c_fully_fold (expr.value, false, NULL, true);
   24446           26 :                   rhs1 = NULL_TREE;
   24447           26 :                   goto stmt_done;
   24448              :                 }
   24449              :             }
   24450           30 :           c_parser_error (parser, "invalid form of %<#pragma omp atomic%>");
   24451           30 :           goto saw_error;
   24452            5 :         default:
   24453            5 :           c_parser_error (parser,
   24454              :                           "invalid operator for %<#pragma omp atomic%>");
   24455            5 :           goto saw_error;
   24456              :         }
   24457              : 
   24458              :       /* Arrange to pass the location of the assignment operator to
   24459              :          c_finish_omp_atomic.  */
   24460          514 :       loc = c_parser_peek_token (parser)->location;
   24461          514 :       c_parser_consume_token (parser);
   24462          514 :       eloc = c_parser_peek_token (parser)->location;
   24463          514 :       expr = c_parser_expression (parser);
   24464          514 :       expr = default_function_array_read_conversion (eloc, expr);
   24465          514 :       rhs = expr.value;
   24466          514 :       rhs = c_fully_fold (rhs, false, NULL, true);
   24467          514 :       break;
   24468              :     }
   24469         1201 : stmt_done:
   24470         1201 :   if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
   24471              :     {
   24472          129 :       if (!no_semicolon
   24473          129 :           && !c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
   24474            0 :         goto saw_error;
   24475          129 :       no_semicolon = false;
   24476          129 :       v = c_parser_cast_expression (parser, NULL).value;
   24477          129 :       non_lvalue_p = !lvalue_p (v);
   24478          129 :       v = c_fully_fold (v, false, NULL, true);
   24479          129 :       if (v == error_mark_node)
   24480            0 :         goto saw_error;
   24481          129 :       if (non_lvalue_p)
   24482            2 :         v = non_lvalue (v);
   24483          129 :       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   24484            0 :         goto saw_error;
   24485          129 :       eloc = c_parser_peek_token (parser)->location;
   24486          129 :       expr = c_parser_cast_expression (parser, NULL);
   24487          129 :       lhs1 = expr.value;
   24488          129 :       expr = default_function_array_read_conversion (eloc, expr);
   24489          129 :       unfolded_lhs1 = expr.value;
   24490          129 :       lhs1 = c_fully_fold (lhs1, false, NULL, true);
   24491          129 :       if (lhs1 == error_mark_node)
   24492            0 :         goto saw_error;
   24493          129 :       if (!lvalue_p (unfolded_lhs1))
   24494            2 :         lhs1 = non_lvalue (lhs1);
   24495              :     }
   24496         1201 :   if (structured_block)
   24497              :     {
   24498          304 :       if (!no_semicolon)
   24499          280 :         c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   24500          304 :       c_parser_require (parser, CPP_CLOSE_BRACE, "expected %<}%>");
   24501              :     }
   24502          897 : done:
   24503         1635 :   if (weak && opcode != COND_EXPR)
   24504              :     {
   24505            1 :       error_at (loc, "%<weak%> clause requires atomic equality comparison");
   24506            1 :       weak = false;
   24507              :     }
   24508         1635 :   if (unfolded_lhs && unfolded_lhs1
   24509         1635 :       && !c_tree_equal (unfolded_lhs, unfolded_lhs1))
   24510              :     {
   24511            5 :       error ("%<#pragma omp atomic capture%> uses two different "
   24512              :              "expressions for memory");
   24513            5 :       stmt = error_mark_node;
   24514              :     }
   24515              :   else
   24516         1630 :     stmt = c_finish_omp_atomic (loc, code, opcode, lhs, rhs, v, lhs1, rhs1, r,
   24517              :                                 swapped, memory_order, weak);
   24518         1635 :   if (stmt != error_mark_node)
   24519         1605 :     add_stmt (stmt);
   24520              : 
   24521         1635 :   if (!structured_block && !no_semicolon)
   24522         1312 :     c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   24523              : }
   24524              : 
   24525              : 
   24526              : /* OpenMP 2.5:
   24527              :    # pragma omp barrier new-line
   24528              : */
   24529              : 
   24530              : static void
   24531          346 : c_parser_omp_barrier (c_parser *parser)
   24532              : {
   24533          346 :   location_t loc = c_parser_peek_token (parser)->location;
   24534          346 :   c_parser_consume_pragma (parser);
   24535          346 :   c_parser_skip_to_pragma_eol (parser);
   24536              : 
   24537          346 :   c_finish_omp_barrier (loc);
   24538          346 : }
   24539              : 
   24540              : /* OpenMP 2.5:
   24541              :    # pragma omp critical [(name)] new-line
   24542              :      structured-block
   24543              : 
   24544              :    OpenMP 4.5:
   24545              :    # pragma omp critical [(name) [hint(expression)]] new-line
   24546              : 
   24547              :   LOC is the location of the #pragma itself.  */
   24548              : 
   24549              : #define OMP_CRITICAL_CLAUSE_MASK                \
   24550              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )
   24551              : 
   24552              : static tree
   24553          144 : c_parser_omp_critical (location_t loc, c_parser *parser, bool *if_p)
   24554              : {
   24555          144 :   tree stmt, name = NULL_TREE, clauses = NULL_TREE;
   24556              : 
   24557          144 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   24558              :     {
   24559           49 :       c_parser_consume_token (parser);
   24560           49 :       if (c_parser_next_token_is (parser, CPP_NAME))
   24561              :         {
   24562           48 :           name = c_parser_peek_token (parser)->value;
   24563           48 :           c_parser_consume_token (parser);
   24564           48 :           c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
   24565              :         }
   24566              :       else
   24567            1 :         c_parser_error (parser, "expected identifier");
   24568              : 
   24569           49 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   24570           49 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   24571            4 :         c_parser_consume_token (parser);
   24572              :     }
   24573          144 :   clauses = c_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
   24574              :                                       "#pragma omp critical");
   24575          144 :   stmt = c_parser_omp_structured_block (parser, if_p);
   24576          144 :   return c_finish_omp_critical (loc, stmt, name, clauses);
   24577              : }
   24578              : 
   24579              : /* OpenMP 5.0:
   24580              :    # pragma omp depobj ( depobj ) depobj-clause new-line
   24581              : 
   24582              :    depobj-clause:
   24583              :      depend (dependence-type : locator)
   24584              :      destroy
   24585              :      update (dependence-type)
   24586              : 
   24587              :    OpenMP 5.2 additionally:
   24588              :      destroy ( depobj )
   24589              : 
   24590              :    dependence-type:
   24591              :      in
   24592              :      out
   24593              :      inout
   24594              :      mutexinout  */
   24595              : 
   24596              : static void
   24597           75 : c_parser_omp_depobj (c_parser *parser)
   24598              : {
   24599           75 :   location_t loc = c_parser_peek_token (parser)->location;
   24600           75 :   c_parser_consume_pragma (parser);
   24601           75 :   matching_parens parens;
   24602           75 :   if (!parens.require_open (parser))
   24603              :     {
   24604            3 :       c_parser_skip_to_pragma_eol (parser);
   24605            3 :       return;
   24606              :     }
   24607              : 
   24608           72 :   tree depobj = c_parser_expr_no_commas (parser, NULL).value;
   24609           72 :   if (depobj != error_mark_node)
   24610              :     {
   24611           71 :       if (!lvalue_p (depobj))
   24612              :         {
   24613            1 :           error_at (EXPR_LOC_OR_LOC (depobj, loc),
   24614              :                     "%<depobj%> expression is not lvalue expression");
   24615            1 :           depobj = error_mark_node;
   24616              :         }
   24617              :       else
   24618              :         {
   24619          123 :           tree addr = build_unary_op (EXPR_LOC_OR_LOC (depobj, loc), ADDR_EXPR,
   24620              :                                       depobj, false);
   24621           70 :           if (addr == error_mark_node)
   24622              :             depobj = error_mark_node;
   24623              :           else
   24624          123 :             depobj = build_indirect_ref (EXPR_LOC_OR_LOC (depobj, loc),
   24625              :                                          addr, RO_UNARY_STAR);
   24626              :         }
   24627              :     }
   24628              : 
   24629           72 :   parens.skip_until_found_close (parser);
   24630           72 :   tree clause = NULL_TREE;
   24631           72 :   enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
   24632           72 :   if (c_parser_next_token_is (parser, CPP_COMMA))
   24633            3 :     c_parser_consume_token (parser);
   24634           72 :   location_t c_loc = c_parser_peek_token (parser)->location;
   24635           72 :   if (c_parser_next_token_is (parser, CPP_NAME))
   24636              :     {
   24637           71 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   24638              : 
   24639           71 :       c_parser_consume_token (parser);
   24640           71 :       if (!strcmp ("depend", p))
   24641              :         {
   24642           38 :           clause = c_parser_omp_clause_depend (parser, NULL_TREE, c_loc);
   24643           38 :           clause = c_finish_omp_clauses (clause, C_ORT_OMP);
   24644           38 :           if (!clause)
   24645            2 :             clause = error_mark_node;
   24646              :         }
   24647           33 :       else if (!strcmp ("destroy", p))
   24648              :         {
   24649           22 :           matching_parens c_parens;
   24650           22 :           kind = OMP_CLAUSE_DEPEND_LAST;
   24651           22 :           if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)
   24652           22 :               && c_parens.require_open (parser))
   24653              :             {
   24654            7 :               tree destobj = c_parser_expr_no_commas (parser, NULL).value;
   24655            7 :               if (!lvalue_p (destobj))
   24656            1 :                 error_at (EXPR_LOC_OR_LOC (destobj, c_loc),
   24657              :                           "%<destroy%> expression is not lvalue expression");
   24658            6 :               else if (depobj != error_mark_node
   24659            6 :                        && !operand_equal_p (destobj, depobj,
   24660              :                                             OEP_MATCH_SIDE_EFFECTS
   24661              :                                             | OEP_LEXICOGRAPHIC))
   24662            4 :                 warning_at (EXPR_LOC_OR_LOC (destobj, c_loc), OPT_Wopenmp,
   24663              :                             "the %<destroy%> expression %qE should be the same "
   24664              :                             "as the %<depobj%> argument %qE", destobj, depobj);
   24665            7 :               c_parens.skip_until_found_close (parser);
   24666              :             }
   24667              :         }
   24668           11 :       else if (!strcmp ("update", p))
   24669              :         {
   24670           10 :           matching_parens c_parens;
   24671           10 :           if (c_parens.require_open (parser))
   24672              :             {
   24673           10 :               location_t c2_loc = c_parser_peek_token (parser)->location;
   24674           10 :               if (c_parser_next_token_is (parser, CPP_NAME))
   24675              :                 {
   24676           10 :                   const char *p2
   24677           10 :                     = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   24678              : 
   24679           10 :                   c_parser_consume_token (parser);
   24680           10 :                   if (!strcmp ("in", p2))
   24681              :                     kind = OMP_CLAUSE_DEPEND_IN;
   24682            8 :                   else if (!strcmp ("out", p2))
   24683              :                     kind = OMP_CLAUSE_DEPEND_OUT;
   24684            7 :                   else if (!strcmp ("inout", p2))
   24685              :                     kind = OMP_CLAUSE_DEPEND_INOUT;
   24686            4 :                   else if (!strcmp ("mutexinoutset", p2))
   24687              :                     kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
   24688            3 :                   else if (!strcmp ("inoutset", p2))
   24689              :                     kind = OMP_CLAUSE_DEPEND_INOUTSET;
   24690              :                 }
   24691              :               if (kind == OMP_CLAUSE_DEPEND_INVALID)
   24692              :                 {
   24693            1 :                   clause = error_mark_node;
   24694            1 :                   error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
   24695              :                                     "%<mutexinoutset%> or %<inoutset%>");
   24696              :                 }
   24697           10 :               c_parens.skip_until_found_close (parser);
   24698              :             }
   24699              :           else
   24700            0 :             clause = error_mark_node;
   24701              :         }
   24702              :     }
   24703           72 :   if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
   24704              :     {
   24705            2 :       clause = error_mark_node;
   24706            2 :       error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
   24707              :     }
   24708           72 :   c_parser_skip_to_pragma_eol (parser);
   24709              : 
   24710           72 :   c_finish_omp_depobj (loc, depobj, kind, clause);
   24711              : }
   24712              : 
   24713              : 
   24714              : /* OpenMP 2.5:
   24715              :    # pragma omp flush flush-vars[opt] new-line
   24716              : 
   24717              :    flush-vars:
   24718              :      ( variable-list )
   24719              : 
   24720              :    OpenMP 5.0:
   24721              :    # pragma omp flush memory-order-clause new-line  */
   24722              : 
   24723              : static void
   24724           59 : c_parser_omp_flush (c_parser *parser)
   24725              : {
   24726           59 :   location_t loc = c_parser_peek_token (parser)->location;
   24727           59 :   c_parser_consume_pragma (parser);
   24728           59 :   enum memmodel mo = MEMMODEL_LAST;
   24729           59 :   if (c_parser_next_token_is (parser, CPP_COMMA)
   24730           59 :       && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   24731            8 :     c_parser_consume_token (parser);
   24732           59 :   if (c_parser_next_token_is (parser, CPP_NAME))
   24733              :     {
   24734           27 :       const char *p
   24735           27 :         = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   24736              : 
   24737           27 :       if (!strcmp (p, "seq_cst"))
   24738              :         mo = MEMMODEL_SEQ_CST;
   24739           21 :       else if (!strcmp (p, "acq_rel"))
   24740              :         mo = MEMMODEL_ACQ_REL;
   24741           15 :       else if (!strcmp (p, "release"))
   24742              :         mo = MEMMODEL_RELEASE;
   24743            9 :       else if (!strcmp (p, "acquire"))
   24744              :         mo = MEMMODEL_ACQUIRE;
   24745              :       else
   24746            3 :         error_at (c_parser_peek_token (parser)->location,
   24747              :                   "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
   24748              :                   "%<acquire%>");
   24749           27 :       c_parser_consume_token (parser);
   24750              :     }
   24751           59 :   if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   24752              :     {
   24753           20 :       if (mo != MEMMODEL_LAST)
   24754            4 :         error_at (c_parser_peek_token (parser)->location,
   24755              :                   "%<flush%> list specified together with memory order "
   24756              :                   "clause");
   24757           20 :       c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
   24758              :     }
   24759           39 :   else if (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   24760            1 :     c_parser_error (parser, "expected %<(%> or end of line");
   24761           59 :   c_parser_skip_to_pragma_eol (parser);
   24762              : 
   24763           59 :   c_finish_omp_flush (loc, mo);
   24764           59 : }
   24765              : 
   24766              : /* Return true if next tokens contain a standard attribute that contains
   24767              :    omp::directive (DIRECTIVE).  */
   24768              : 
   24769              : static bool
   24770          363 : c_parser_omp_section_scan (c_parser *parser, const char *directive,
   24771              :                            bool tentative)
   24772              : {
   24773          363 :   if (!c_parser_nth_token_starts_std_attributes (parser, 1))
   24774              :     return false;
   24775           36 :   unsigned int n = 3;
   24776           36 :   if (!c_parser_check_balanced_raw_token_sequence (parser, &n))
   24777              :     return false;
   24778           36 :   c_token *token = c_parser_peek_nth_token_raw (parser, n);
   24779           36 :   if (token->type != CPP_CLOSE_SQUARE)
   24780              :     return false;
   24781           36 :   token = c_parser_peek_nth_token_raw (parser, n + 1);
   24782           36 :   if (token->type != CPP_CLOSE_SQUARE)
   24783              :     return false;
   24784           36 :   if (n < 9)
   24785              :     return false;
   24786           35 :   if (c_parser_peek_nth_token_raw (parser, 3)->type == CPP_NAME
   24787           35 :       && c_parser_peek_nth_token_raw (parser, 4)->type == CPP_OPEN_PAREN
   24788           35 :       && c_parser_peek_nth_token_raw (parser, 5)->type == CPP_NAME)
   24789              :     {
   24790            0 :       tree first = c_parser_peek_nth_token_raw (parser, 3)->value;
   24791            0 :       tree second = c_parser_peek_nth_token_raw (parser, 5)->value;
   24792            0 :       if (strcmp (IDENTIFIER_POINTER (first), "directive")
   24793            0 :           && strcmp (IDENTIFIER_POINTER (first), "__directive__"))
   24794              :         return false;
   24795            0 :       if (strcmp (IDENTIFIER_POINTER (second), directive))
   24796              :         return false;
   24797              :     }
   24798           35 :   if (tentative)
   24799              :     return true;
   24800           32 :   location_t first_loc = c_parser_peek_token (parser)->location;
   24801           32 :   location_t last_loc = c_parser_peek_nth_token_raw (parser, n + 1)->location;
   24802           32 :   location_t middle_loc = UNKNOWN_LOCATION;
   24803           32 :   tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
   24804           32 :   bool seen = false;
   24805           32 :   int cnt = 0;
   24806           67 :   for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
   24807           35 :     if (is_attribute_namespace_p ("omp", attr)
   24808           35 :         && is_attribute_p ("directive", get_attribute_name (attr)))
   24809              :       {
   24810           68 :         for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
   24811              :           {
   24812           36 :             tree d = TREE_VALUE (a);
   24813           36 :             gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
   24814           36 :             c_token *first = C_TOKEN_VEC_TOKENS (d)->address ();
   24815           36 :             cnt++;
   24816           36 :             if (first->type == CPP_NAME
   24817           36 :                 && strcmp (IDENTIFIER_POINTER (first->value),
   24818              :                            directive) == 0)
   24819              :               {
   24820           31 :                 seen = true;
   24821           31 :                 if (middle_loc == UNKNOWN_LOCATION)
   24822           31 :                   middle_loc = first->location;
   24823              :               }
   24824              :           }
   24825              :       }
   24826           32 :   if (!seen)
   24827              :     return false;
   24828           31 :   if (cnt != 1 || TREE_CHAIN (std_attrs))
   24829              :     {
   24830            7 :       error_at (make_location (first_loc, last_loc, middle_loc),
   24831              :                 "%<[[omp::directive(%s)]]%> must be the only specified "
   24832              :                 "attribute on a statement", directive);
   24833            7 :       return false;
   24834              :     }
   24835           24 :   c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
   24836           24 :   return true;
   24837              : }
   24838              : 
   24839              : /* Parse an OpenMP structured block sequence.  KIND is the corresponding
   24840              :    separating directive.  */
   24841              : 
   24842              : static tree
   24843          815 : c_parser_omp_structured_block_sequence (c_parser *parser,
   24844              :                                         enum pragma_kind kind)
   24845              : {
   24846          815 :   tree stmt = push_stmt_list ();
   24847          815 :   c_parser_statement (parser, NULL);
   24848          909 :   do
   24849              :     {
   24850          862 :       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   24851              :         break;
   24852          461 :       if (c_parser_next_token_is (parser, CPP_EOF))
   24853              :         break;
   24854              : 
   24855          461 :       if (kind != PRAGMA_NONE
   24856          461 :           && c_parser_peek_token (parser)->pragma_kind == kind)
   24857              :         break;
   24858              : 
   24859           69 :       if (kind != PRAGMA_NONE
   24860          104 :           && c_parser_omp_section_scan (parser,
   24861              :                                         kind == PRAGMA_OMP_SCAN
   24862              :                                         ? "scan" : "section", false))
   24863              :         break;
   24864              : 
   24865           47 :       c_parser_statement (parser, NULL);
   24866              :     }
   24867              :   while (1);
   24868          815 :   return pop_stmt_list (stmt);
   24869              : }
   24870              : 
   24871              : /* OpenMP 5.0:
   24872              : 
   24873              :    scan-loop-body:
   24874              :      { structured-block scan-directive structured-block }  */
   24875              : 
   24876              : static void
   24877          264 : c_parser_omp_scan_loop_body (c_parser *parser, bool open_brace_parsed)
   24878              : {
   24879          264 :   tree substmt;
   24880          264 :   location_t loc;
   24881          264 :   tree clauses = NULL_TREE;
   24882          264 :   bool found_scan = false;
   24883              : 
   24884          264 :   loc = c_parser_peek_token (parser)->location;
   24885          264 :   if (!open_brace_parsed
   24886          264 :       && !c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   24887              :     {
   24888              :       /* Avoid skipping until the end of the block.  */
   24889            1 :       parser->error = false;
   24890            1 :       return;
   24891              :     }
   24892              : 
   24893          263 :   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SCAN)
   24894          261 :     substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
   24895              :   else
   24896              :     {
   24897            2 :       warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
   24898              :                   "%<#pragma omp scan%> with zero preceding executable "
   24899              :                   "statements");
   24900            2 :       substmt = build_empty_stmt (loc);
   24901              :     }
   24902          263 :   substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
   24903          263 :   SET_EXPR_LOCATION (substmt, loc);
   24904          263 :   add_stmt (substmt);
   24905              : 
   24906          263 :   loc = c_parser_peek_token (parser)->location;
   24907          263 :   if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SCAN)
   24908              :     {
   24909          256 :       enum omp_clause_code clause = OMP_CLAUSE_ERROR;
   24910          256 :       found_scan = true;
   24911              : 
   24912          256 :       c_parser_consume_pragma (parser);
   24913              : 
   24914          256 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   24915            4 :         c_parser_consume_token (parser);
   24916              : 
   24917          256 :       if (c_parser_next_token_is (parser, CPP_NAME))
   24918              :         {
   24919          254 :           const char *p
   24920          254 :             = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   24921          254 :           if (strcmp (p, "inclusive") == 0)
   24922              :             clause = OMP_CLAUSE_INCLUSIVE;
   24923          126 :           else if (strcmp (p, "exclusive") == 0)
   24924              :             clause = OMP_CLAUSE_EXCLUSIVE;
   24925              :         }
   24926              :       if (clause != OMP_CLAUSE_ERROR)
   24927              :         {
   24928          254 :           c_parser_consume_token (parser);
   24929          254 :           clauses = c_parser_omp_var_list_parens (parser, clause, NULL_TREE);
   24930              :         }
   24931              :       else
   24932            2 :         c_parser_error (parser, "expected %<inclusive%> or "
   24933              :                                 "%<exclusive%> clause");
   24934          256 :       c_parser_skip_to_pragma_eol (parser);
   24935              :     }
   24936              :   else
   24937            7 :     error ("expected %<#pragma omp scan%>");
   24938              : 
   24939          263 :   clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
   24940          263 :   if (!c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   24941          254 :     substmt = c_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
   24942              :   else
   24943              :     {
   24944            9 :       if (found_scan)
   24945            2 :         warning_at (loc, OPT_Wopenmp,
   24946              :                     "%<#pragma omp scan%> with zero succeeding executable "
   24947              :                     "statements");
   24948            9 :       substmt = build_empty_stmt (loc);
   24949              :     }
   24950          263 :   substmt = build2 (OMP_SCAN, void_type_node, substmt, clauses);
   24951          263 :   SET_EXPR_LOCATION (substmt, loc);
   24952          263 :   add_stmt (substmt);
   24953              : 
   24954          263 :   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
   24955              :                              "expected %<}%>");
   24956              : }
   24957              : 
   24958              : 
   24959              : /* Check if the next tokens can start a canonical loop.  Return true if yes,
   24960              :    otherwise diagnose an error if ERROR_P is true, and return false.  */
   24961              : static bool
   24962        17322 : c_parser_omp_next_tokens_can_be_canon_loop (c_parser *parser,
   24963              :                                             enum tree_code code,
   24964              :                                             bool error_p)
   24965              : {
   24966        17322 :   if (code == OACC_LOOP)
   24967              :     {
   24968         2581 :       if (c_parser_next_token_is_keyword (parser, RID_FOR))
   24969              :         return true;
   24970           27 :       if (error_p)
   24971            4 :         c_parser_error (parser, "for statement expected");
   24972              :     }
   24973              :   else
   24974              :     {
   24975        14741 :       if (c_parser_next_token_is_keyword (parser, RID_FOR))
   24976              :         return true;
   24977              : 
   24978          897 :       if (c_parser_next_token_is (parser, CPP_PRAGMA))
   24979          582 :         switch (c_parser_peek_token (parser)->pragma_kind)
   24980              :           {
   24981              :           case PRAGMA_OMP_UNROLL:
   24982              :           case PRAGMA_OMP_TILE:
   24983              :             return true;
   24984              :           default:
   24985              :             break;
   24986              :           }
   24987              : 
   24988              :       /* Skip standard attributes on next for in case they are
   24989              :          [[omp::directive (unroll partial (4))]] or
   24990              :          [[omp::directive (tile sizes (1, 2, 3))]] etc.  */
   24991          329 :       size_t n = c_parser_skip_std_attribute_spec_seq (parser, 1);
   24992          329 :       c_token *token = c_parser_peek_nth_token_raw (parser, n);
   24993              :       /* TOKEN is a raw token that hasn't been converted to a keyword yet,
   24994              :          we have to do the lookup explicitly.  */
   24995          329 :       if (token->type == CPP_NAME
   24996          108 :           && C_IS_RESERVED_WORD (token->value)
   24997          341 :           && C_RID_CODE (token->value) == RID_FOR)
   24998              :         return true;
   24999          317 :       if (error_p)
   25000            7 :         c_parser_error (parser, "loop nest expected");
   25001              :     }
   25002              : 
   25003              :   return false;
   25004              : }
   25005              : 
   25006              : static tree c_parser_omp_tile (location_t, c_parser *, bool *);
   25007              : static tree c_parser_omp_unroll (location_t, c_parser *, bool *);
   25008              : 
   25009              : /* This function parses a single level of a loop nest, invoking itself
   25010              :    recursively if necessary.
   25011              : 
   25012              :    loop-nest :: for (...) loop-body
   25013              :    loop-body :: loop-nest
   25014              :              |  { [intervening-code] loop-body [intervening-code] }
   25015              :              |  final-loop-body
   25016              :    intervening-code :: structured-block-sequence
   25017              :    final-loop-body :: structured-block
   25018              : 
   25019              :    For a collapsed loop nest, only a single OMP_FOR is built, pulling out
   25020              :    all the iterator information from the inner loops into the
   25021              :    parser->omp_for_parse_state structure.
   25022              : 
   25023              :    The iterator decl, init, cond, and incr are stored in vectors.
   25024              : 
   25025              :    Initialization code for iterator variables is collected into
   25026              :    parser->omp_for_parse_state->pre_body and ends up inserted directly
   25027              :    into the OMP_FOR structure.  */
   25028              : 
   25029              : static tree
   25030        16978 : c_parser_omp_loop_nest (c_parser *parser, bool *if_p)
   25031              : {
   25032        16978 :   tree decl = NULL_TREE, cond = NULL_TREE, incr = NULL_TREE, init = NULL_TREE;
   25033        16978 :   tree body = NULL_TREE;
   25034        16978 :   matching_parens parens;
   25035        16978 :   bool moreloops;
   25036        16978 :   unsigned char save_in_statement;
   25037        16978 :   tree loop_scope;
   25038        16978 :   location_t loc;
   25039        16978 :   struct omp_for_parse_data *omp_for_parse_state
   25040              :     = parser->omp_for_parse_state;
   25041        16978 :   gcc_assert (omp_for_parse_state);
   25042        16978 :   int depth = omp_for_parse_state->depth;
   25043              : 
   25044              :   /* Arrange for C23 standard attribute syntax to be parsed as regular
   25045              :      pragmas.  */
   25046        16978 :   if (c_parser_nth_token_starts_std_attributes (parser, 1))
   25047              :     {
   25048           12 :       tree std_attrs = c_parser_std_attribute_specifier_sequence (parser);
   25049           12 :       c_parser_handle_statement_omp_attributes (parser, std_attrs, NULL);
   25050           12 :       if (std_attrs)
   25051            0 :         error_at (c_parser_peek_token (parser)->location,
   25052              :                   "attributes other than OpenMP directives "
   25053              :                   "are not allowed on %<for%> in loop nest");
   25054              :     }
   25055              : 
   25056        16978 :   loc = c_parser_peek_token (parser)->location;
   25057              : 
   25058              :   /* Handle loop transformations first.  */
   25059        16978 :   if (c_parser_next_token_is (parser, CPP_PRAGMA))
   25060              :     {
   25061          576 :       tree transform = NULL_TREE, sizes, body = NULL_TREE;
   25062          576 :       int count = 0;
   25063          576 :       switch (c_parser_peek_token (parser)->pragma_kind)
   25064              :         {
   25065          208 :         case PRAGMA_OMP_UNROLL:
   25066          208 :           c_parser_consume_pragma (parser);
   25067          208 :           body = push_stmt_list ();
   25068          208 :           transform = c_parser_omp_unroll (loc, parser, if_p);
   25069          208 :           body = pop_stmt_list (body);
   25070          208 :           if (transform == NULL_TREE || transform == error_mark_node)
   25071              :             {
   25072            7 :               transform = error_mark_node;
   25073            7 :               break;
   25074              :             }
   25075          201 :           gcc_assert (TREE_CODE (transform) == OMP_UNROLL);
   25076          201 :           if (omp_find_clause (OMP_FOR_CLAUSES (transform),
   25077              :                                OMP_CLAUSE_PARTIAL))
   25078              :             {
   25079          172 :               if (omp_for_parse_state->count - depth > 1)
   25080              :                 {
   25081           10 :                   error_at (loc, "%<unroll%> construct with %<partial%> "
   25082              :                                  "clause generates just one loop with "
   25083              :                                  "canonical form but %d loops are needed",
   25084              :                             omp_for_parse_state->count - depth);
   25085           10 :                   transform = error_mark_node;
   25086              :                 }
   25087              :               else
   25088          576 :                 count = 1;
   25089              :             }
   25090              :           else
   25091              :             {
   25092           29 :               error_at (loc, "generated loop of %<unroll%> construct "
   25093              :                              "without %<partial%> clause does not have "
   25094              :                              "canonical form");
   25095           29 :               transform = error_mark_node;
   25096              :             }
   25097              :           break;
   25098          366 :         case PRAGMA_OMP_TILE:
   25099          366 :           c_parser_consume_pragma (parser);
   25100          366 :           body = push_stmt_list ();
   25101          366 :           transform = c_parser_omp_tile (loc, parser, if_p);
   25102          366 :           body = pop_stmt_list (body);
   25103          366 :           if (transform == NULL_TREE || transform == error_mark_node)
   25104              :             {
   25105           40 :               transform = error_mark_node;
   25106           40 :               break;
   25107              :             }
   25108          326 :           gcc_assert (TREE_CODE (transform) == OMP_TILE);
   25109          326 :           sizes = omp_find_clause (OMP_FOR_CLAUSES (transform),
   25110              :                                    OMP_CLAUSE_SIZES);
   25111          326 :           gcc_assert (sizes);
   25112          326 :           count = list_length (OMP_CLAUSE_SIZES_LIST (sizes));
   25113          326 :           if (depth + count < omp_for_parse_state->count)
   25114              :             {
   25115           16 :               error_at (loc, "%<tile%> construct generates %d loops "
   25116              :                              "with canonical form but %d loops are needed",
   25117              :                         count, omp_for_parse_state->count - depth);
   25118           16 :               transform = error_mark_node;
   25119              :             }
   25120              :           break;
   25121            2 :         default:
   25122            2 :           c_parser_pragma (parser, pragma_stmt, NULL, void_list_node);
   25123            2 :           break;
   25124              :         }
   25125          576 :       if (transform == NULL_TREE)
   25126            2 :         error_at (loc, "expected %<for%> loop or OpenMP loop "
   25127              :                        "transformation construct");
   25128          576 :       if (transform == NULL_TREE || transform == error_mark_node)
   25129              :         {
   25130          104 :           omp_for_parse_state->fail = true;
   25131          104 :           return NULL_TREE;
   25132              :         }
   25133         1030 :       for (count = omp_for_parse_state->count; depth < count; ++depth)
   25134              :         {
   25135          558 :           TREE_VEC_ELT (omp_for_parse_state->declv, depth) = NULL_TREE;
   25136          558 :           TREE_VEC_ELT (omp_for_parse_state->initv, depth) = NULL_TREE;
   25137          558 :           TREE_VEC_ELT (omp_for_parse_state->condv, depth) = NULL_TREE;
   25138          558 :           TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = NULL_TREE;
   25139              :         }
   25140          472 :       omp_for_parse_state->want_nested_loop = false;
   25141          472 :       return body;
   25142              :     }
   25143              : 
   25144              :   /* We have already matched the FOR token but not consumed it yet.  */
   25145        16402 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
   25146        16402 :   c_parser_consume_token (parser);
   25147              : 
   25148              :   /* Forbid break/continue in the loop initializer, condition, and
   25149              :      increment expressions.  */
   25150        16402 :   save_in_statement = in_statement;
   25151        16402 :   in_statement = IN_OMP_BLOCK;
   25152              : 
   25153              :   /* We are not in intervening code now.  */
   25154        16402 :   omp_for_parse_state->in_intervening_code = false;
   25155              : 
   25156        16402 :   if (!parens.require_open (parser))
   25157              :     {
   25158            0 :       omp_for_parse_state->fail = true;
   25159            0 :       return NULL_TREE;
   25160              :     }
   25161              : 
   25162              :   /* An implicit scope block surrounds each level of FOR loop, for
   25163              :      declarations of iteration variables at this loop depth.  */
   25164        16402 :   loop_scope = c_begin_compound_stmt (true);
   25165              : 
   25166              :   /* Parse the initialization declaration or expression.  */
   25167        16402 :   if (c_parser_next_tokens_start_declaration (parser))
   25168              :     {
   25169              :       /* This is a declaration, which must be added to the pre_body code.  */
   25170         4753 :       tree this_pre_body = push_stmt_list ();
   25171         4753 :       c_in_omp_for = true;
   25172         4753 :       c_parser_declaration_or_fndef (parser, true, true, true, true, true,
   25173              :                                      false);
   25174         4753 :       c_in_omp_for = false;
   25175         4753 :       this_pre_body = pop_stmt_list (this_pre_body);
   25176         4753 :       append_to_statement_list_force (this_pre_body,
   25177              :                                       &(omp_for_parse_state->pre_body));
   25178         4753 :       decl = check_for_loop_decls (omp_for_parse_state->for_loc, flag_isoc99);
   25179         4753 :       if (decl == NULL)
   25180            0 :         goto error_init;
   25181         4753 :       if (DECL_INITIAL (decl) == error_mark_node)
   25182            1 :         decl = error_mark_node;
   25183              :       init = decl;
   25184              :     }
   25185        11649 :   else if (c_parser_next_token_is (parser, CPP_NAME)
   25186        11649 :            && c_parser_peek_2nd_token (parser)->type == CPP_EQ)
   25187              :     {
   25188        11647 :       struct c_expr decl_exp;
   25189        11647 :       struct c_expr init_exp;
   25190        11647 :       location_t init_loc;
   25191              : 
   25192        11647 :       decl_exp = c_parser_postfix_expression (parser);
   25193        11647 :       decl = decl_exp.value;
   25194              : 
   25195        11647 :       c_parser_require (parser, CPP_EQ, "expected %<=%>");
   25196              : 
   25197        11647 :       init_loc = c_parser_peek_token (parser)->location;
   25198        11647 :       init_exp = c_parser_expr_no_commas (parser, NULL);
   25199        11647 :       init_exp = default_function_array_read_conversion (init_loc,
   25200              :                                                          init_exp);
   25201        11647 :       c_in_omp_for = true;
   25202        11647 :       init = build_modify_expr (init_loc, decl, decl_exp.original_type,
   25203              :                                 NOP_EXPR, init_loc, init_exp.value,
   25204              :                                 init_exp.original_type);
   25205        11647 :       c_in_omp_for = false;
   25206        11647 :       init = c_process_expr_stmt (init_loc, init);
   25207              : 
   25208        11647 :       c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   25209              :     }
   25210              :   else
   25211              :     {
   25212            2 :     error_init:
   25213            2 :       c_parser_error (parser,
   25214              :                       "expected iteration declaration or initialization");
   25215            2 :       c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
   25216              :                                  "expected %<)%>");
   25217            2 :       omp_for_parse_state->fail = true;
   25218            2 :       goto parse_next;
   25219              :     }
   25220              : 
   25221              :   /* Parse the loop condition.  */
   25222        16400 :   if (c_parser_next_token_is_not (parser, CPP_SEMICOLON))
   25223              :     {
   25224        16398 :       location_t cond_loc = c_parser_peek_token (parser)->location;
   25225        16398 :       c_in_omp_for = true;
   25226        16398 :       struct c_expr cond_expr
   25227        16398 :         = c_parser_binary_expression (parser, NULL, NULL_TREE);
   25228        16398 :       c_in_omp_for = false;
   25229              : 
   25230        16398 :       cond = cond_expr.value;
   25231        16398 :       cond = c_objc_common_truthvalue_conversion (cond_loc, cond);
   25232        16398 :       switch (cond_expr.original_code)
   25233              :         {
   25234              :         case GT_EXPR:
   25235              :         case GE_EXPR:
   25236              :         case LT_EXPR:
   25237              :         case LE_EXPR:
   25238              :           break;
   25239         2425 :         case NE_EXPR:
   25240         2425 :           if (omp_for_parse_state->code != OACC_LOOP)
   25241              :             break;
   25242              :           /* FALLTHRU.  */
   25243            7 :         default:
   25244              :           /* Can't be cond = error_mark_node, because we want to preserve
   25245              :              the location until c_finish_omp_for.  */
   25246            7 :           cond = build1 (NOP_EXPR, boolean_type_node, error_mark_node);
   25247            7 :           break;
   25248              :         }
   25249        16398 :       protected_set_expr_location (cond, cond_loc);
   25250              :     }
   25251        16400 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   25252              : 
   25253              :   /* Parse the increment expression.  */
   25254        16400 :   if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
   25255              :     {
   25256        16400 :       location_t incr_loc = c_parser_peek_token (parser)->location;
   25257              : 
   25258        16400 :       incr = c_process_expr_stmt (incr_loc,
   25259        32800 :                                   c_parser_expression (parser).value);
   25260              :     }
   25261        16400 :   parens.skip_until_found_close (parser);
   25262              : 
   25263        16400 :   if (decl == NULL || decl == error_mark_node || init == error_mark_node)
   25264            3 :     omp_for_parse_state->fail = true;
   25265              :   else
   25266              :     {
   25267        16397 :       TREE_VEC_ELT (omp_for_parse_state->declv, depth) = decl;
   25268        16397 :       TREE_VEC_ELT (omp_for_parse_state->initv, depth) = init;
   25269        16397 :       TREE_VEC_ELT (omp_for_parse_state->condv, depth) = cond;
   25270        16397 :       TREE_VEC_ELT (omp_for_parse_state->incrv, depth) = incr;
   25271              :     }
   25272              : 
   25273        16402 : parse_next:
   25274        16402 :   moreloops = depth < omp_for_parse_state->count - 1;
   25275        16402 :   omp_for_parse_state->want_nested_loop = moreloops;
   25276        16402 :   if (moreloops
   25277        16402 :       && c_parser_omp_next_tokens_can_be_canon_loop (parser,
   25278              :                                                      omp_for_parse_state->code,
   25279              :                                                      false))
   25280              :     {
   25281         5327 :       omp_for_parse_state->depth++;
   25282         5327 :       body = c_parser_omp_loop_nest (parser, if_p);
   25283         5327 :       omp_for_parse_state->depth--;
   25284              :     }
   25285        11221 :   else if (moreloops && c_parser_next_token_is (parser, CPP_OPEN_BRACE))
   25286              :     {
   25287              :       /* This is the open brace in the loop-body grammar production.  Rather
   25288              :          than trying to special-case braces, just parse it as a compound
   25289              :          statement and handle the nested loop-body case there.  Note that
   25290              :          when we see a further open brace inside the compound statement
   25291              :          loop-body, we don't know whether it is the start of intervening
   25292              :          code that is a compound statement, or a level of braces
   25293              :          surrounding a nested loop-body.  Use the WANT_NESTED_LOOP state
   25294              :          bit to ensure we have only one nested loop at each level.  */
   25295          127 :       omp_for_parse_state->in_intervening_code = true;
   25296          127 :       body = c_parser_compound_statement (parser, NULL);
   25297          127 :       omp_for_parse_state->in_intervening_code = false;
   25298          127 :       if (omp_for_parse_state->want_nested_loop)
   25299              :         {
   25300              :           /* We have already parsed the whole loop body and not found a
   25301              :              nested loop.  */
   25302           11 :           error_at (omp_for_parse_state->for_loc,
   25303              :                     "not enough nested loops");
   25304           11 :           omp_for_parse_state->fail = true;
   25305              :         }
   25306        16402 :       if_p = NULL;
   25307              :     }
   25308              :   else
   25309              :     {
   25310              :       /* This is the final-loop-body case in the grammar: we have
   25311              :          something that is not a FOR and not an open brace.  */
   25312        10948 :       if (moreloops)
   25313              :         {
   25314              :           /* If we were expecting a nested loop, give an error and mark
   25315              :              that parsing has failed, and try to recover by parsing the
   25316              :              body as regular code without further collapsing.  */
   25317           19 :           error_at (omp_for_parse_state->for_loc,
   25318              :                     "not enough nested loops");
   25319           19 :           omp_for_parse_state->fail = true;
   25320              :         }
   25321        10948 :       in_statement = IN_OMP_FOR;
   25322        10948 :       parser->omp_for_parse_state = NULL;
   25323        10948 :       body = push_stmt_list ();
   25324        10948 :       if (omp_for_parse_state->inscan)
   25325          264 :         c_parser_omp_scan_loop_body (parser, false);
   25326              :       else
   25327        10684 :         add_stmt (c_parser_c99_block_statement (parser, if_p));
   25328        10948 :       body = pop_stmt_list (body);
   25329        10948 :       parser->omp_for_parse_state = omp_for_parse_state;
   25330              :     }
   25331        16402 :   in_statement = save_in_statement;
   25332        16402 :   omp_for_parse_state->want_nested_loop = false;
   25333        16402 :   omp_for_parse_state->in_intervening_code = true;
   25334              : 
   25335              :   /* Pop and return the implicit scope surrounding this level of loop.
   25336              :      If the iteration variable at this depth was bound in the for loop,
   25337              :      pull out and save the binding.  Later in c_parser_omp_for_loop,
   25338              :      these bindings will be moved to the scope surrounding the entire
   25339              :      OMP_FOR.  That keeps the gimplifier happy later on, and meanwhile
   25340              :      we have already resolved all references to the iteration variable
   25341              :      in its true scope.  */
   25342        16402 :   if (body)
   25343        16396 :     add_stmt (body);
   25344        16402 :   body = c_end_compound_stmt (loc, loop_scope, true);
   25345        16402 :   if (decl && TREE_CODE (body) == BIND_EXPR)
   25346              :     {
   25347         5139 :       tree t = BIND_EXPR_VARS (body);
   25348         5139 :       tree prev = NULL_TREE, next = NULL_TREE;
   25349         5575 :       while (t)
   25350              :         {
   25351         5188 :           next = DECL_CHAIN (t);
   25352         5188 :           if (t == decl)
   25353              :             {
   25354         4752 :               if (prev)
   25355            0 :                 DECL_CHAIN (prev) = next;
   25356              :               else
   25357              :                 {
   25358         4752 :                   BIND_EXPR_VARS (body) = next;
   25359         4752 :                   BLOCK_VARS (BIND_EXPR_BLOCK (body)) = next;
   25360              :                 }
   25361         4752 :               DECL_CHAIN (t) = omp_for_parse_state->bindings;
   25362         4752 :               omp_for_parse_state->bindings = t;
   25363         4752 :               break;
   25364              :             }
   25365              :           else
   25366              :             {
   25367              :               prev = t;
   25368              :               t = next;
   25369              :             }
   25370              :         }
   25371         5139 :       if (BIND_EXPR_VARS (body) == NULL_TREE)
   25372         4752 :         body = BIND_EXPR_BODY (body);
   25373              :     }
   25374              : 
   25375              :   return body;
   25376              : }
   25377              : 
   25378              : /* Parse the restricted form of loop statements allowed by OpenACC and OpenMP.
   25379              :    The real trick here is to determine the loop control variable early
   25380              :    so that we can push a new decl if necessary to make it private.
   25381              :    LOC is the location of the "acc" or "omp" in "#pragma acc" or "#pragma omp",
   25382              :    respectively.  */
   25383              : 
   25384              : static tree
   25385        11546 : c_parser_omp_for_loop (location_t loc, c_parser *parser, enum tree_code code,
   25386              :                        tree clauses, tree *cclauses, bool *if_p)
   25387              : {
   25388        11546 :   tree body, stmt, cl;
   25389        11546 :   tree ret = NULL_TREE;
   25390        11546 :   tree ordered_cl = NULL_TREE;
   25391        11546 :   int i, collapse = 1, ordered = 0, count;
   25392        11546 :   bool oacc_tiling = false;
   25393        11546 :   bool inscan = false;
   25394        11546 :   struct omp_for_parse_data data;
   25395        11546 :   struct omp_for_parse_data *save_data = parser->omp_for_parse_state;
   25396              : 
   25397        27488 :   for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
   25398        15942 :     if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
   25399         2954 :       collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
   25400        12988 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
   25401              :       {
   25402          111 :         oacc_tiling = true;
   25403          111 :         collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
   25404              :       }
   25405        12877 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_SIZES)
   25406          464 :       collapse = list_length (OMP_CLAUSE_SIZES_LIST (cl));
   25407        12413 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
   25408        12413 :              && OMP_CLAUSE_ORDERED_EXPR (cl))
   25409              :       {
   25410          161 :         ordered_cl = cl;
   25411          161 :         ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
   25412              :       }
   25413        12252 :     else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
   25414         2107 :              && OMP_CLAUSE_REDUCTION_INSCAN (cl)
   25415        12637 :              && (code == OMP_SIMD || code == OMP_FOR))
   25416              :       inscan = true;
   25417              : 
   25418        11546 :   if (ordered && ordered < collapse)
   25419              :     {
   25420            2 :       error_at (OMP_CLAUSE_LOCATION (ordered_cl),
   25421              :                 "%<ordered%> clause parameter is less than %<collapse%>");
   25422            2 :       OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
   25423            2 :         = build_int_cst (NULL_TREE, collapse);
   25424            2 :       ordered = collapse;
   25425              :     }
   25426              : 
   25427        11546 :   gcc_assert (oacc_tiling || (collapse >= 1 && ordered >= 0));
   25428        11546 :   count = ordered ? ordered : collapse;
   25429              : 
   25430        11546 :   if (!c_parser_omp_next_tokens_can_be_canon_loop (parser, code, true))
   25431              :     return NULL;
   25432              : 
   25433              :   /* Initialize parse state for recursive descent.  */
   25434        11535 :   data.declv = make_tree_vec (count);
   25435        11535 :   data.initv = make_tree_vec (count);
   25436        11535 :   data.condv = make_tree_vec (count);
   25437        11535 :   data.incrv = make_tree_vec (count);
   25438        11535 :   data.pre_body = NULL_TREE;
   25439        11535 :   data.bindings = NULL_TREE;
   25440        11535 :   data.for_loc = c_parser_peek_token (parser)->location;
   25441        11535 :   data.count = count;
   25442        11535 :   data.depth = 0;
   25443        11535 :   data.want_nested_loop = true;
   25444        11535 :   data.ordered = ordered > 0;
   25445        11535 :   data.in_intervening_code = false;
   25446        11535 :   data.perfect_nesting_fail = false;
   25447        11535 :   data.fail = false;
   25448        11535 :   data.inscan = inscan;
   25449        11535 :   data.saw_intervening_code = false;
   25450        11535 :   data.code = code;
   25451        11535 :   parser->omp_for_parse_state = &data;
   25452              : 
   25453        11535 :   body = c_parser_omp_loop_nest (parser, if_p);
   25454              : 
   25455              :   /* Add saved bindings for iteration variables that were declared in
   25456              :      the nested for loop to the scope surrounding the entire loop.  */
   25457        16287 :   for (tree t = data.bindings; t; )
   25458              :     {
   25459         4752 :       tree n = TREE_CHAIN (t);
   25460         4752 :       TREE_CHAIN (t) = NULL_TREE;
   25461         4752 :       pushdecl (t);
   25462         4752 :       t = n;
   25463              :     }
   25464              : 
   25465              :   /* Only bother calling c_finish_omp_for if we haven't already generated
   25466              :      an error from the initialization parsing.  */
   25467        11535 :   if (!data.fail)
   25468              :     {
   25469        11372 :       c_in_omp_for = true;
   25470        11372 :       stmt = c_finish_omp_for (loc, code, data.declv, NULL, data.initv,
   25471              :                                data.condv, data.incrv,
   25472              :                                body, data.pre_body, true);
   25473        11372 :       c_in_omp_for = false;
   25474              : 
   25475              :       /* Check for iterators appearing in lb, b or incr expressions.  */
   25476        11372 :       if (stmt && !c_omp_check_loop_iv (stmt, data.declv, NULL))
   25477              :         stmt = NULL_TREE;
   25478              : 
   25479              :       /* Check for errors involving lb/ub/incr expressions referencing
   25480              :          variables declared in intervening code.  */
   25481        11372 :       if (data.saw_intervening_code
   25482           42 :           && stmt
   25483        11414 :           && !c_omp_check_loop_binding_exprs (stmt, NULL))
   25484              :         stmt = NULL_TREE;
   25485              : 
   25486        11362 :       if (stmt)
   25487              :         {
   25488        11217 :           add_stmt (stmt);
   25489              : 
   25490        27317 :           for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (stmt)); i++)
   25491              :             {
   25492        16558 :               tree init = TREE_VEC_ELT (OMP_FOR_INIT (stmt), i);
   25493        16558 :               if (init == NULL_TREE)
   25494              :                 break;
   25495        16100 :               gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
   25496        16100 :               tree decl = TREE_OPERAND (init, 0);
   25497        16100 :               tree cond = TREE_VEC_ELT (OMP_FOR_COND (stmt), i);
   25498        16100 :               gcc_assert (COMPARISON_CLASS_P (cond));
   25499        16100 :               gcc_assert (TREE_OPERAND (cond, 0) == decl);
   25500              : 
   25501        16100 :               tree op0 = TREE_OPERAND (init, 1);
   25502        16100 :               if (!OMP_FOR_NON_RECTANGULAR (stmt)
   25503        16100 :                   || TREE_CODE (op0) != TREE_VEC)
   25504        15913 :                 TREE_OPERAND (init, 1) = c_fully_fold (op0, false, NULL);
   25505              :               else
   25506              :                 {
   25507          187 :                   TREE_VEC_ELT (op0, 1)
   25508          187 :                     = c_fully_fold (TREE_VEC_ELT (op0, 1), false, NULL);
   25509          187 :                   TREE_VEC_ELT (op0, 2)
   25510          374 :                     = c_fully_fold (TREE_VEC_ELT (op0, 2), false, NULL);
   25511              :                 }
   25512              : 
   25513        16100 :               tree op1 = TREE_OPERAND (cond, 1);
   25514        16100 :               if (!OMP_FOR_NON_RECTANGULAR (stmt)
   25515        16100 :                   || TREE_CODE (op1) != TREE_VEC)
   25516        15894 :                 TREE_OPERAND (cond, 1) = c_fully_fold (op1, false, NULL);
   25517              :               else
   25518              :                 {
   25519          206 :                   TREE_VEC_ELT (op1, 1)
   25520          206 :                     = c_fully_fold (TREE_VEC_ELT (op1, 1), false, NULL);
   25521          206 :                   TREE_VEC_ELT (op1, 2)
   25522          412 :                     = c_fully_fold (TREE_VEC_ELT (op1, 2), false, NULL);
   25523              :                 }
   25524              :             }
   25525              : 
   25526        11217 :           if (cclauses != NULL
   25527         5259 :               && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL)
   25528              :             {
   25529          757 :               tree *c;
   25530         3317 :               for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
   25531         2560 :                 if (OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_FIRSTPRIVATE
   25532         2560 :                     && OMP_CLAUSE_CODE (*c) != OMP_CLAUSE_LASTPRIVATE)
   25533         1860 :                   c = &OMP_CLAUSE_CHAIN (*c);
   25534              :                 else
   25535              :                   {
   25536         1441 :                     for (i = 0; i < count; i++)
   25537          923 :                       if (TREE_VEC_ELT (data.declv, i) == OMP_CLAUSE_DECL (*c))
   25538              :                         break;
   25539          700 :                     if (i == count)
   25540          518 :                       c = &OMP_CLAUSE_CHAIN (*c);
   25541          182 :                     else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE)
   25542              :                       {
   25543            1 :                         error_at (loc,
   25544              :                                   "iteration variable %qD should not be firstprivate",
   25545            1 :                                   OMP_CLAUSE_DECL (*c));
   25546            1 :                         *c = OMP_CLAUSE_CHAIN (*c);
   25547              :                       }
   25548              :                     else
   25549              :                       {
   25550              :                         /* Move lastprivate (decl) clause to
   25551              :                            OMP_FOR_CLAUSES.  */
   25552          181 :                         tree l = *c;
   25553          181 :                         *c = OMP_CLAUSE_CHAIN (*c);
   25554          181 :                         if (code == OMP_SIMD)
   25555              :                           {
   25556           46 :                             OMP_CLAUSE_CHAIN (l)
   25557           46 :                               = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
   25558           46 :                             cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
   25559              :                           }
   25560              :                         else
   25561              :                           {
   25562          135 :                             OMP_CLAUSE_CHAIN (l) = clauses;
   25563          135 :                             clauses = l;
   25564              :                           }
   25565              :                       }
   25566              :                   }
   25567              :             }
   25568        11217 :           OMP_FOR_CLAUSES (stmt) = clauses;
   25569              :         }
   25570              :       ret = stmt;
   25571              :     }
   25572              : 
   25573        11535 :   parser->omp_for_parse_state = save_data;
   25574        11535 :   return ret;
   25575              : }
   25576              : 
   25577              : /* Helper function for OpenMP parsing, split clauses and call
   25578              :    finish_omp_clauses on each of the set of clauses afterwards.  */
   25579              : 
   25580              : static void
   25581         6573 : omp_split_clauses (location_t loc, enum tree_code code,
   25582              :                    omp_clause_mask mask, tree clauses, tree *cclauses)
   25583              : {
   25584         6573 :   int i;
   25585         6573 :   c_omp_split_clauses (loc, code, mask, clauses, cclauses);
   25586        52584 :   for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
   25587        39438 :     if (cclauses[i])
   25588        20253 :       cclauses[i] = c_finish_omp_clauses (cclauses[i],
   25589              :                                           i == C_OMP_CLAUSE_SPLIT_TARGET
   25590              :                                           ? C_ORT_OMP_TARGET : C_ORT_OMP);
   25591         6573 : }
   25592              : 
   25593              : /* OpenMP 5.0:
   25594              :    #pragma omp loop loop-clause[optseq] new-line
   25595              :      for-loop
   25596              : 
   25597              :    LOC is the location of the #pragma token.
   25598              : */
   25599              : 
   25600              : #define OMP_LOOP_CLAUSE_MASK                                    \
   25601              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   25602              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   25603              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   25604              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   25605              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)           \
   25606              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   25607              : 
   25608              : static tree
   25609          235 : c_parser_omp_loop (location_t loc, c_parser *parser,
   25610              :                    char *p_name, omp_clause_mask mask, tree *cclauses,
   25611              :                    bool *if_p)
   25612              : {
   25613          235 :   tree block, clauses, ret;
   25614              : 
   25615          235 :   strcat (p_name, " loop");
   25616          235 :   mask |= OMP_LOOP_CLAUSE_MASK;
   25617              : 
   25618          235 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   25619          235 :   if (cclauses)
   25620              :     {
   25621           77 :       omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
   25622           77 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
   25623              :     }
   25624              : 
   25625          235 :   block = c_begin_compound_stmt (true);
   25626          235 :   ret = c_parser_omp_for_loop (loc, parser, OMP_LOOP, clauses, cclauses, if_p);
   25627          235 :   block = c_end_compound_stmt (loc, block, true);
   25628          235 :   add_stmt (block);
   25629              : 
   25630          235 :   return ret;
   25631              : }
   25632              : 
   25633              : /* OpenMP 4.0:
   25634              :    #pragma omp simd simd-clause[optseq] new-line
   25635              :      for-loop
   25636              : 
   25637              :    LOC is the location of the #pragma token.
   25638              : */
   25639              : 
   25640              : #define OMP_SIMD_CLAUSE_MASK                                    \
   25641              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)        \
   25642              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)        \
   25643              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
   25644              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)        \
   25645              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   25646              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   25647              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   25648              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   25649              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   25650              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)    \
   25651              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   25652              : 
   25653              : static tree
   25654         3514 : c_parser_omp_simd (location_t loc, c_parser *parser,
   25655              :                    char *p_name, omp_clause_mask mask, tree *cclauses,
   25656              :                    bool *if_p)
   25657              : {
   25658         3514 :   tree block, clauses, ret;
   25659              : 
   25660         3514 :   strcat (p_name, " simd");
   25661         3514 :   mask |= OMP_SIMD_CLAUSE_MASK;
   25662              : 
   25663         3514 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   25664         3514 :   if (cclauses)
   25665              :     {
   25666         2783 :       omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
   25667         2783 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
   25668              :     }
   25669              : 
   25670         3514 :   block = c_begin_compound_stmt (true);
   25671         3514 :   ret = c_parser_omp_for_loop (loc, parser, OMP_SIMD, clauses, cclauses, if_p);
   25672         3514 :   block = c_end_compound_stmt (loc, block, true);
   25673         3514 :   add_stmt (block);
   25674              : 
   25675         3514 :   return ret;
   25676              : }
   25677              : 
   25678              : /* OpenMP 2.5:
   25679              :    #pragma omp for for-clause[optseq] new-line
   25680              :      for-loop
   25681              : 
   25682              :    OpenMP 4.0:
   25683              :    #pragma omp for simd for-simd-clause[optseq] new-line
   25684              :      for-loop
   25685              : 
   25686              :    LOC is the location of the #pragma token.
   25687              : */
   25688              : 
   25689              : #define OMP_FOR_CLAUSE_MASK                                     \
   25690              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   25691              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   25692              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   25693              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
   25694              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   25695              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)        \
   25696              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)       \
   25697              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   25698              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
   25699              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   25700              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   25701              : 
   25702              : static tree
   25703         6191 : c_parser_omp_for (location_t loc, c_parser *parser,
   25704              :                   char *p_name, omp_clause_mask mask, tree *cclauses,
   25705              :                   bool *if_p)
   25706              : {
   25707         6191 :   tree block, clauses, ret;
   25708              : 
   25709         6191 :   strcat (p_name, " for");
   25710         6191 :   mask |= OMP_FOR_CLAUSE_MASK;
   25711              :   /* parallel for{, simd} disallows nowait clause, but for
   25712              :      target {teams distribute ,}parallel for{, simd} it should be accepted.  */
   25713         6191 :   if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
   25714         3248 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
   25715              :   /* Composite distribute parallel for{, simd} disallows ordered clause.  */
   25716         6191 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
   25717         2724 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);
   25718              : 
   25719         6191 :   if (c_parser_next_token_is (parser, CPP_NAME))
   25720              :     {
   25721         5440 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   25722              : 
   25723         5440 :       if (strcmp (p, "simd") == 0)
   25724              :         {
   25725         2205 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   25726         2205 :           if (cclauses == NULL)
   25727          301 :             cclauses = cclauses_buf;
   25728              : 
   25729         2205 :           c_parser_consume_token (parser);
   25730         2205 :           if (!flag_openmp)  /* flag_openmp_simd  */
   25731           14 :             return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
   25732           14 :                                       if_p);
   25733         2191 :           block = c_begin_compound_stmt (true);
   25734         2191 :           ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
   25735         2191 :           block = c_end_compound_stmt (loc, block, true);
   25736         2191 :           if (ret == NULL_TREE)
   25737              :             return ret;
   25738         2180 :           ret = make_node (OMP_FOR);
   25739         2180 :           TREE_TYPE (ret) = void_type_node;
   25740         2180 :           OMP_FOR_BODY (ret) = block;
   25741         2180 :           OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
   25742         2180 :           SET_EXPR_LOCATION (ret, loc);
   25743         2180 :           add_stmt (ret);
   25744         2180 :           return ret;
   25745              :         }
   25746              :     }
   25747         3986 :   if (!flag_openmp)  /* flag_openmp_simd  */
   25748              :     {
   25749            9 :       c_parser_skip_to_pragma_eol (parser, false);
   25750            9 :       return NULL_TREE;
   25751              :     }
   25752              : 
   25753              :   /* Composite distribute parallel for disallows linear clause.  */
   25754         3977 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
   25755         1371 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);
   25756              : 
   25757         3977 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   25758         3977 :   if (cclauses)
   25759              :     {
   25760         2462 :       omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
   25761         2462 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
   25762              :     }
   25763              : 
   25764         3977 :   block = c_begin_compound_stmt (true);
   25765         3977 :   ret = c_parser_omp_for_loop (loc, parser, OMP_FOR, clauses, cclauses, if_p);
   25766         3977 :   block = c_end_compound_stmt (loc, block, true);
   25767         3977 :   add_stmt (block);
   25768              : 
   25769         3977 :   return ret;
   25770              : }
   25771              : 
   25772              : static tree c_parser_omp_taskloop (location_t, c_parser *, char *,
   25773              :                                    omp_clause_mask, tree *, bool *);
   25774              : 
   25775              : /* OpenMP 2.5:
   25776              :    # pragma omp master new-line
   25777              :      structured-block
   25778              : 
   25779              :    LOC is the location of the #pragma token.
   25780              : */
   25781              : 
   25782              : static tree
   25783          228 : c_parser_omp_master (location_t loc, c_parser *parser,
   25784              :                      char *p_name, omp_clause_mask mask, tree *cclauses,
   25785              :                      bool *if_p, location_t master_loc)
   25786              : {
   25787          228 :   tree block, clauses, ret;
   25788          228 :   gcc_rich_location richloc (loc);
   25789          228 :   if (master_loc != UNKNOWN_LOCATION)
   25790           91 :     richloc.add_fixit_replace (master_loc, "masked");
   25791          228 :   warning_at (&richloc, OPT_Wdeprecated_openmp,
   25792              :               "%<master%> construct deprecated since OpenMP 5.1, use "
   25793              :               "%<masked%>");
   25794              : 
   25795          228 :   strcat (p_name, " master");
   25796              : 
   25797          228 :   if (c_parser_next_token_is (parser, CPP_NAME))
   25798              :     {
   25799          123 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   25800              : 
   25801          123 :       if (strcmp (p, "taskloop") == 0)
   25802              :         {
   25803           94 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   25804           94 :           if (cclauses == NULL)
   25805           47 :             cclauses = cclauses_buf;
   25806              : 
   25807           94 :           c_parser_consume_token (parser);
   25808           94 :           if (!flag_openmp)  /* flag_openmp_simd  */
   25809            4 :             return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
   25810            4 :                                           if_p);
   25811           90 :           block = c_begin_compound_stmt (true);
   25812           90 :           ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
   25813              :                                        if_p);
   25814           90 :           block = c_end_compound_stmt (loc, block, true);
   25815           90 :           if (ret == NULL_TREE)
   25816              :             return ret;
   25817           90 :           ret = c_finish_omp_master (loc, block);
   25818           90 :           OMP_MASTER_COMBINED (ret) = 1;
   25819           90 :           return ret;
   25820              :         }
   25821              :     }
   25822          134 :   if (!flag_openmp)  /* flag_openmp_simd  */
   25823              :     {
   25824            2 :       c_parser_skip_to_pragma_eol (parser, false);
   25825            2 :       return NULL_TREE;
   25826              :     }
   25827              : 
   25828          132 :   if (cclauses)
   25829              :     {
   25830           43 :       clauses = c_parser_omp_all_clauses (parser, mask, p_name, false);
   25831           43 :       omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
   25832              :     }
   25833              :   else
   25834           89 :     c_parser_skip_to_pragma_eol (parser);
   25835              : 
   25836          132 :   return c_finish_omp_master (loc, c_parser_omp_structured_block (parser,
   25837          132 :                                                                   if_p));
   25838          228 : }
   25839              : 
   25840              : /* OpenMP 5.1:
   25841              :    # pragma omp masked masked-clauses new-line
   25842              :      structured-block
   25843              : 
   25844              :    LOC is the location of the #pragma token.
   25845              : */
   25846              : 
   25847              : #define OMP_MASKED_CLAUSE_MASK                                  \
   25848              :         (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)
   25849              : 
   25850              : static tree
   25851          126 : c_parser_omp_masked (location_t loc, c_parser *parser,
   25852              :                      char *p_name, omp_clause_mask mask, tree *cclauses,
   25853              :                      bool *if_p)
   25854              : {
   25855          126 :   tree block, clauses, ret;
   25856              : 
   25857          126 :   strcat (p_name, " masked");
   25858          126 :   mask |= OMP_MASKED_CLAUSE_MASK;
   25859              : 
   25860          126 :   if (c_parser_next_token_is (parser, CPP_NAME))
   25861              :     {
   25862           87 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   25863              : 
   25864           87 :       if (strcmp (p, "taskloop") == 0)
   25865              :         {
   25866           68 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   25867           68 :           if (cclauses == NULL)
   25868           21 :             cclauses = cclauses_buf;
   25869              : 
   25870           68 :           c_parser_consume_token (parser);
   25871           68 :           if (!flag_openmp)  /* flag_openmp_simd  */
   25872            0 :             return c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
   25873            0 :                                           if_p);
   25874           68 :           block = c_begin_compound_stmt (true);
   25875           68 :           ret = c_parser_omp_taskloop (loc, parser, p_name, mask, cclauses,
   25876              :                                        if_p);
   25877           68 :           block = c_end_compound_stmt (loc, block, true);
   25878           68 :           if (ret == NULL_TREE)
   25879              :             return ret;
   25880           68 :           ret = c_finish_omp_masked (loc, block,
   25881              :                                      cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
   25882           68 :           OMP_MASKED_COMBINED (ret) = 1;
   25883           68 :           return ret;
   25884              :         }
   25885              :     }
   25886           58 :   if (!flag_openmp)  /* flag_openmp_simd  */
   25887              :     {
   25888            0 :       c_parser_skip_to_pragma_eol (parser, false);
   25889            0 :       return NULL_TREE;
   25890              :     }
   25891              : 
   25892           58 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   25893           58 :   if (cclauses)
   25894              :     {
   25895            9 :       omp_split_clauses (loc, OMP_MASKED, mask, clauses, cclauses);
   25896            9 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
   25897              :     }
   25898              : 
   25899           58 :   return c_finish_omp_masked (loc, c_parser_omp_structured_block (parser,
   25900              :                                                                   if_p),
   25901           58 :                               clauses);
   25902              : }
   25903              : 
   25904              : /* OpenMP 5.1:
   25905              :    # pragma omp interop clauses[opt] new-line */
   25906              : 
   25907              : #define OMP_INTEROP_CLAUSE_MASK                                 \
   25908              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   25909              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DESTROY)        \
   25910              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   25911              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INIT)           \
   25912              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
   25913              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE))
   25914              : 
   25915              : static void
   25916          183 : c_parser_omp_interop (c_parser *parser)
   25917              : {
   25918          183 :   location_t loc = c_parser_peek_token (parser)->location;
   25919          183 :   c_parser_consume_pragma (parser);
   25920          366 :   tree clauses = c_parser_omp_all_clauses (parser,
   25921          183 :                                            OMP_INTEROP_CLAUSE_MASK,
   25922              :                                            "#pragma omp interop");
   25923          183 :   tree stmt = make_node (OMP_INTEROP);
   25924          183 :   TREE_TYPE (stmt) = void_type_node;
   25925          183 :   OMP_INTEROP_CLAUSES (stmt) = clauses;
   25926          183 :   SET_EXPR_LOCATION (stmt, loc);
   25927          183 :   add_stmt (stmt);
   25928          183 : }
   25929              : 
   25930              : /* OpenMP 2.5:
   25931              :    # pragma omp ordered new-line
   25932              :      structured-block
   25933              : 
   25934              :    OpenMP 4.5:
   25935              :    # pragma omp ordered ordered-clauses new-line
   25936              :      structured-block
   25937              : 
   25938              :    # pragma omp ordered depend-clauses new-line
   25939              : 
   25940              :    OpenMP 5.2
   25941              :    # pragma omp ordered doacross-clauses new-line  */
   25942              : 
   25943              : #define OMP_ORDERED_CLAUSE_MASK                                 \
   25944              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)        \
   25945              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))
   25946              : 
   25947              : #define OMP_ORDERED_DEPEND_CLAUSE_MASK                          \
   25948              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   25949              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))
   25950              : 
   25951              : static bool
   25952          545 : c_parser_omp_ordered (c_parser *parser, enum pragma_context context,
   25953              :                       bool *if_p)
   25954              : {
   25955          545 :   location_t loc = c_parser_peek_token (parser)->location;
   25956          545 :   c_parser_consume_pragma (parser);
   25957              : 
   25958          545 :   if (context != pragma_stmt && context != pragma_compound)
   25959              :     {
   25960            1 :       c_parser_error (parser, "expected declaration specifiers");
   25961            1 :       c_parser_skip_to_pragma_eol (parser, false);
   25962            1 :       return false;
   25963              :     }
   25964              : 
   25965          544 :   int n = 1;
   25966          544 :   if (c_parser_next_token_is (parser, CPP_COMMA))
   25967            8 :     n = 2;
   25968              : 
   25969          544 :   if (c_parser_peek_nth_token (parser, n)->type == CPP_NAME)
   25970              :     {
   25971          433 :       const char *p
   25972          433 :         = IDENTIFIER_POINTER (c_parser_peek_nth_token (parser, n)->value);
   25973              : 
   25974          433 :       if (!strcmp ("depend", p) || !strcmp ("doacross", p))
   25975              :         {
   25976          349 :           if (!flag_openmp)     /* flag_openmp_simd  */
   25977              :             {
   25978            2 :               c_parser_skip_to_pragma_eol (parser, false);
   25979            2 :               return false;
   25980              :             }
   25981          347 :           if (context == pragma_stmt)
   25982              :             {
   25983           16 :               error_at (loc,
   25984              :                         "%<#pragma omp ordered%> with %qs clause may "
   25985              :                         "only be used in compound statements", p);
   25986           16 :               c_parser_skip_to_pragma_eol (parser, false);
   25987           16 :               return true;
   25988              :             }
   25989              : 
   25990          331 :           tree clauses
   25991          662 :             = c_parser_omp_all_clauses (parser,
   25992          331 :                                         OMP_ORDERED_DEPEND_CLAUSE_MASK,
   25993              :                                         "#pragma omp ordered");
   25994          331 :           c_finish_omp_ordered (loc, clauses, NULL_TREE);
   25995          331 :           return false;
   25996              :         }
   25997              :     }
   25998              : 
   25999          195 :   tree clauses = c_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
   26000              :                                            "#pragma omp ordered");
   26001              : 
   26002          195 :   if (!flag_openmp      /* flag_openmp_simd  */
   26003          195 :       && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
   26004              :     return false;
   26005              : 
   26006          193 :   c_finish_omp_ordered (loc, clauses,
   26007              :                         c_parser_omp_structured_block (parser, if_p));
   26008          193 :   return true;
   26009              : }
   26010              : 
   26011              : /* OpenMP 2.5:
   26012              : 
   26013              :    section-scope:
   26014              :      { section-sequence }
   26015              : 
   26016              :    section-sequence:
   26017              :      section-directive[opt] structured-block
   26018              :      section-sequence section-directive structured-block
   26019              : 
   26020              :    OpenMP 5.1 allows structured-block-sequence instead of structured-block.
   26021              : 
   26022              :     SECTIONS_LOC is the location of the #pragma omp sections.  */
   26023              : 
   26024              : static tree
   26025          142 : c_parser_omp_sections_scope (location_t sections_loc, c_parser *parser)
   26026              : {
   26027          142 :   tree stmt, substmt;
   26028          142 :   bool error_suppress = false;
   26029          142 :   location_t loc;
   26030              : 
   26031          142 :   loc = c_parser_peek_token (parser)->location;
   26032          142 :   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   26033              :     {
   26034              :       /* Avoid skipping until the end of the block.  */
   26035            2 :       parser->error = false;
   26036            2 :       return NULL_TREE;
   26037              :     }
   26038              : 
   26039          140 :   stmt = push_stmt_list ();
   26040              : 
   26041          140 :   if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_SECTION
   26042          140 :       && !c_parser_omp_section_scan (parser, "section", true))
   26043              :     {
   26044           81 :       substmt = c_parser_omp_structured_block_sequence (parser,
   26045              :                                                         PRAGMA_OMP_SECTION);
   26046           81 :       substmt = build1 (OMP_SECTION, void_type_node, substmt);
   26047           81 :       SET_EXPR_LOCATION (substmt, loc);
   26048           81 :       add_stmt (substmt);
   26049              :     }
   26050              : 
   26051          578 :   while (1)
   26052              :     {
   26053          359 :       if (c_parser_next_token_is (parser, CPP_CLOSE_BRACE))
   26054              :         break;
   26055          219 :       if (c_parser_next_token_is (parser, CPP_EOF))
   26056              :         break;
   26057              : 
   26058          219 :       loc = c_parser_peek_token (parser)->location;
   26059          219 :       c_parser_omp_section_scan (parser, "section", false);
   26060          219 :       if (c_parser_peek_token (parser)->pragma_kind == PRAGMA_OMP_SECTION)
   26061              :         {
   26062          218 :           c_parser_consume_pragma (parser);
   26063          218 :           c_parser_skip_to_pragma_eol (parser);
   26064          218 :           error_suppress = false;
   26065              :         }
   26066            1 :       else if (!error_suppress)
   26067              :         {
   26068            1 :           error_at (loc, "expected %<#pragma omp section%> or %<}%>");
   26069            1 :           error_suppress = true;
   26070              :         }
   26071              : 
   26072          219 :       substmt = c_parser_omp_structured_block_sequence (parser,
   26073              :                                                         PRAGMA_OMP_SECTION);
   26074          219 :       substmt = build1 (OMP_SECTION, void_type_node, substmt);
   26075          219 :       SET_EXPR_LOCATION (substmt, loc);
   26076          219 :       add_stmt (substmt);
   26077              :     }
   26078          140 :   c_parser_skip_until_found (parser, CPP_CLOSE_BRACE,
   26079              :                              "expected %<#pragma omp section%> or %<}%>");
   26080              : 
   26081          140 :   substmt = pop_stmt_list (stmt);
   26082              : 
   26083          140 :   stmt = make_node (OMP_SECTIONS);
   26084          140 :   SET_EXPR_LOCATION (stmt, sections_loc);
   26085          140 :   TREE_TYPE (stmt) = void_type_node;
   26086          140 :   OMP_SECTIONS_BODY (stmt) = substmt;
   26087              : 
   26088          140 :   return add_stmt (stmt);
   26089              : }
   26090              : 
   26091              : /* OpenMP 2.5:
   26092              :    # pragma omp sections sections-clause[optseq] newline
   26093              :      sections-scope
   26094              : 
   26095              :    LOC is the location of the #pragma token.
   26096              : */
   26097              : 
   26098              : #define OMP_SECTIONS_CLAUSE_MASK                                \
   26099              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26100              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26101              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   26102              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   26103              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26104              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   26105              : 
   26106              : static tree
   26107          142 : c_parser_omp_sections (location_t loc, c_parser *parser,
   26108              :                        char *p_name, omp_clause_mask mask, tree *cclauses)
   26109              : {
   26110          142 :   tree block, clauses, ret;
   26111              : 
   26112          142 :   strcat (p_name, " sections");
   26113          142 :   mask |= OMP_SECTIONS_CLAUSE_MASK;
   26114          142 :   if (cclauses)
   26115           36 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
   26116              : 
   26117          142 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   26118          142 :   if (cclauses)
   26119              :     {
   26120           36 :       omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
   26121           36 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
   26122              :     }
   26123              : 
   26124          142 :   block = c_begin_compound_stmt (true);
   26125          142 :   ret = c_parser_omp_sections_scope (loc, parser);
   26126          142 :   if (ret)
   26127          140 :     OMP_SECTIONS_CLAUSES (ret) = clauses;
   26128          142 :   block = c_end_compound_stmt (loc, block, true);
   26129          142 :   add_stmt (block);
   26130              : 
   26131          142 :   return ret;
   26132              : }
   26133              : 
   26134              : /* OpenMP 2.5:
   26135              :    # pragma omp parallel parallel-clause[optseq] new-line
   26136              :      structured-block
   26137              :    # pragma omp parallel for parallel-for-clause[optseq] new-line
   26138              :      structured-block
   26139              :    # pragma omp parallel sections parallel-sections-clause[optseq] new-line
   26140              :      structured-block
   26141              : 
   26142              :    OpenMP 4.0:
   26143              :    # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
   26144              :      structured-block
   26145              : 
   26146              :    LOC is the location of the #pragma token.
   26147              : */
   26148              : 
   26149              : #define OMP_PARALLEL_CLAUSE_MASK                                \
   26150              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   26151              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26152              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26153              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)        \
   26154              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   26155              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN) \
   26156              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   26157              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)    \
   26158              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26159              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))
   26160              : 
   26161              : static tree
   26162         5704 : c_parser_omp_parallel (location_t loc, c_parser *parser,
   26163              :                        char *p_name, omp_clause_mask mask, tree *cclauses,
   26164              :                        bool *if_p)
   26165              : {
   26166         5704 :   tree stmt, clauses, block;
   26167              : 
   26168         5704 :   strcat (p_name, " parallel");
   26169         5704 :   mask |= OMP_PARALLEL_CLAUSE_MASK;
   26170              :   /* #pragma omp target parallel{, for, for simd} disallow copyin clause.  */
   26171         5704 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
   26172         1166 :       && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
   26173          490 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);
   26174              : 
   26175         5704 :   if (c_parser_next_token_is_keyword (parser, RID_FOR))
   26176              :     {
   26177         4374 :       tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26178         4374 :       if (cclauses == NULL)
   26179         1200 :         cclauses = cclauses_buf;
   26180              : 
   26181         4374 :       c_parser_consume_token (parser);
   26182         4374 :       if (!flag_openmp)  /* flag_openmp_simd  */
   26183           20 :         return c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
   26184         4354 :       block = c_begin_omp_parallel ();
   26185         4354 :       tree ret = c_parser_omp_for (loc, parser, p_name, mask, cclauses, if_p);
   26186         4354 :       stmt
   26187         4354 :         = c_finish_omp_parallel (loc, cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   26188              :                                  block);
   26189         4354 :       if (ret == NULL_TREE)
   26190              :         return ret;
   26191         4293 :       OMP_PARALLEL_COMBINED (stmt) = 1;
   26192         4293 :       return stmt;
   26193              :     }
   26194              :   /* When combined with distribute, parallel has to be followed by for.
   26195              :      #pragma omp target parallel is allowed though.  */
   26196         1330 :   else if (cclauses
   26197         1330 :            && (mask & (OMP_CLAUSE_MASK_1
   26198           40 :                        << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
   26199              :     {
   26200            0 :       error_at (loc, "expected %<for%> after %qs", p_name);
   26201            0 :       c_parser_skip_to_pragma_eol (parser);
   26202            0 :       return NULL_TREE;
   26203              :     }
   26204         1330 :   else if (c_parser_next_token_is (parser, CPP_NAME))
   26205              :     {
   26206          720 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   26207          720 :       location_t ploc = c_parser_peek_token (parser)->location;
   26208          720 :       if (cclauses == NULL && strcmp (p, "masked") == 0)
   26209              :         {
   26210           56 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26211           56 :           cclauses = cclauses_buf;
   26212              : 
   26213           56 :           c_parser_consume_token (parser);
   26214           56 :           if (!flag_openmp)  /* flag_openmp_simd  */
   26215            0 :             return c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
   26216            0 :                                         if_p);
   26217           56 :           block = c_begin_omp_parallel ();
   26218           56 :           tree ret = c_parser_omp_masked (loc, parser, p_name, mask, cclauses,
   26219              :                                           if_p);
   26220           56 :           stmt = c_finish_omp_parallel (loc,
   26221              :                                         cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   26222              :                                         block);
   26223           56 :           if (ret == NULL)
   26224              :             return ret;
   26225              :           /* masked does have just filter clause, but during gimplification
   26226              :              isn't represented by a gimplification omp context, so for
   26227              :              #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
   26228              :              so that
   26229              :              #pragma omp parallel masked
   26230              :              #pragma omp taskloop simd lastprivate (x)
   26231              :              isn't confused with
   26232              :              #pragma omp parallel masked taskloop simd lastprivate (x)  */
   26233           56 :           if (OMP_MASKED_COMBINED (ret))
   26234           47 :             OMP_PARALLEL_COMBINED (stmt) = 1;
   26235           56 :           return stmt;
   26236              :         }
   26237          629 :       else if (cclauses == NULL && strcmp (p, "master") == 0)
   26238              :         {
   26239           91 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26240           91 :           cclauses = cclauses_buf;
   26241              : 
   26242           91 :           c_parser_consume_token (parser);
   26243           91 :           if (!flag_openmp)  /* flag_openmp_simd  */
   26244            3 :             return c_parser_omp_master (loc, parser, p_name, mask, cclauses,
   26245            3 :                                         if_p, ploc);
   26246           88 :           block = c_begin_omp_parallel ();
   26247           88 :           tree ret = c_parser_omp_master (loc, parser, p_name, mask, cclauses,
   26248              :                                           if_p, ploc);
   26249           88 :           stmt = c_finish_omp_parallel (loc,
   26250              :                                         cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   26251              :                                         block);
   26252           88 :           if (ret == NULL)
   26253              :             return ret;
   26254              :           /* master doesn't have any clauses and during gimplification
   26255              :              isn't represented by a gimplification omp context, so for
   26256              :              #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
   26257              :              so that
   26258              :              #pragma omp parallel master
   26259              :              #pragma omp taskloop simd lastprivate (x)
   26260              :              isn't confused with
   26261              :              #pragma omp parallel master taskloop simd lastprivate (x)  */
   26262           88 :           if (OMP_MASTER_COMBINED (ret))
   26263           45 :             OMP_PARALLEL_COMBINED (stmt) = 1;
   26264           88 :           return stmt;
   26265              :         }
   26266          573 :       else if (strcmp (p, "loop") == 0)
   26267              :         {
   26268           43 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26269           43 :           if (cclauses == NULL)
   26270           24 :             cclauses = cclauses_buf;
   26271              : 
   26272           43 :           c_parser_consume_token (parser);
   26273           43 :           if (!flag_openmp)  /* flag_openmp_simd  */
   26274            2 :             return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
   26275            2 :                                       if_p);
   26276           41 :           block = c_begin_omp_parallel ();
   26277           41 :           tree ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
   26278              :                                         if_p);
   26279           41 :           stmt
   26280           41 :             = c_finish_omp_parallel (loc,
   26281              :                                      cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   26282              :                                      block);
   26283           41 :           if (ret == NULL_TREE)
   26284              :             return ret;
   26285           41 :           OMP_PARALLEL_COMBINED (stmt) = 1;
   26286           41 :           return stmt;
   26287              :         }
   26288          530 :       else if (!flag_openmp)  /* flag_openmp_simd  */
   26289              :         {
   26290            1 :           c_parser_skip_to_pragma_eol (parser, false);
   26291            1 :           return NULL_TREE;
   26292              :         }
   26293          529 :       else if (cclauses == NULL && strcmp (p, "sections") == 0)
   26294              :         {
   26295           36 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26296           36 :           cclauses = cclauses_buf;
   26297              : 
   26298           36 :           c_parser_consume_token (parser);
   26299           36 :           block = c_begin_omp_parallel ();
   26300           36 :           c_parser_omp_sections (loc, parser, p_name, mask, cclauses);
   26301           36 :           stmt = c_finish_omp_parallel (loc,
   26302              :                                         cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
   26303              :                                         block);
   26304           36 :           OMP_PARALLEL_COMBINED (stmt) = 1;
   26305           36 :           return stmt;
   26306              :         }
   26307              :     }
   26308          610 :   else if (!flag_openmp)  /* flag_openmp_simd  */
   26309              :     {
   26310            1 :       c_parser_skip_to_pragma_eol (parser, false);
   26311            1 :       return NULL_TREE;
   26312              :     }
   26313              : 
   26314         1102 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   26315         1102 :   if (cclauses)
   26316              :     {
   26317           20 :       omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
   26318           20 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
   26319              :     }
   26320              : 
   26321         1102 :   block = c_begin_omp_parallel ();
   26322         1102 :   parser->omp_attrs_forbidden_p = true;
   26323         1102 :   c_parser_statement (parser, if_p);
   26324         1102 :   stmt = c_finish_omp_parallel (loc, clauses, block);
   26325              : 
   26326         1102 :   return stmt;
   26327              : }
   26328              : 
   26329              : /* OpenMP 2.5:
   26330              :    # pragma omp single single-clause[optseq] new-line
   26331              :      structured-block
   26332              : 
   26333              :    LOC is the location of the #pragma.
   26334              : */
   26335              : 
   26336              : #define OMP_SINGLE_CLAUSE_MASK                                  \
   26337              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26338              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26339              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE)    \
   26340              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26341              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   26342              : 
   26343              : static tree
   26344          222 : c_parser_omp_single (location_t loc, c_parser *parser, bool *if_p)
   26345              : {
   26346          222 :   tree stmt = make_node (OMP_SINGLE);
   26347          222 :   SET_EXPR_LOCATION (stmt, loc);
   26348          222 :   TREE_TYPE (stmt) = void_type_node;
   26349              : 
   26350          222 :   OMP_SINGLE_CLAUSES (stmt)
   26351          222 :     = c_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
   26352              :                                 "#pragma omp single");
   26353          222 :   OMP_SINGLE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
   26354              : 
   26355          222 :   return add_stmt (stmt);
   26356              : }
   26357              : 
   26358              : /* OpenMP 5.1:
   26359              :    # pragma omp scope scope-clause[optseq] new-line
   26360              :      structured-block
   26361              : 
   26362              :    LOC is the location of the #pragma.
   26363              : */
   26364              : 
   26365              : #define OMP_SCOPE_CLAUSE_MASK                                   \
   26366              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26367              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26368              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   26369              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26370              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   26371              : 
   26372              : static tree
   26373           61 : c_parser_omp_scope (location_t loc, c_parser *parser, bool *if_p)
   26374              : {
   26375           61 :   tree stmt = make_node (OMP_SCOPE);
   26376           61 :   SET_EXPR_LOCATION (stmt, loc);
   26377           61 :   TREE_TYPE (stmt) = void_type_node;
   26378              : 
   26379           61 :   OMP_SCOPE_CLAUSES (stmt)
   26380           61 :     = c_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
   26381              :                                 "#pragma omp scope");
   26382           61 :   OMP_SCOPE_BODY (stmt) = c_parser_omp_structured_block (parser, if_p);
   26383              : 
   26384           61 :   return add_stmt (stmt);
   26385              : }
   26386              : 
   26387              : /* Parse a function dispatch structured block:
   26388              : 
   26389              :     lvalue-expression = target-call ( [expression-list] );
   26390              :     or
   26391              :     target-call ( [expression-list] );
   26392              : 
   26393              :    Adapted from c_parser_expr_no_commas and c_parser_postfix_expression
   26394              :    (CPP_NAME/C_ID_ID) for the function name.
   26395              : */
   26396              : static tree
   26397          155 : c_parser_omp_dispatch_body (c_parser *parser)
   26398              : {
   26399          155 :   struct c_expr lhs, rhs, ret;
   26400          155 :   location_t expr_loc = c_parser_peek_token (parser)->location;
   26401          155 :   source_range tok_range = c_parser_peek_token (parser)->get_range ();
   26402              : 
   26403          155 :   lhs = c_parser_conditional_expression (parser, NULL, NULL);
   26404          155 :   if (TREE_CODE (lhs.value) == CALL_EXPR)
   26405              :     return lhs.value;
   26406              : 
   26407           56 :   location_t op_location = c_parser_peek_token (parser)->location;
   26408           56 :   if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   26409            4 :     return error_mark_node;
   26410              : 
   26411              :   /* Parse function name.  */
   26412           52 :   if (!c_parser_next_token_is (parser, CPP_NAME))
   26413              :     {
   26414            1 :       c_parser_error (parser, "expected a function name");
   26415            1 :       return error_mark_node;
   26416              :     }
   26417           51 :   expr_loc = c_parser_peek_token (parser)->location;
   26418           51 :   tree id = c_parser_peek_token (parser)->value;
   26419           51 :   c_parser_consume_token (parser);
   26420           51 :   if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   26421              :     {
   26422            1 :       c_parser_error (parser, "expected a function name");
   26423            1 :       return error_mark_node;
   26424              :     }
   26425              : 
   26426           50 :   rhs.value = build_external_ref (expr_loc, id, true, &rhs.original_type);
   26427           50 :   set_c_expr_source_range (&rhs, tok_range);
   26428              : 
   26429              :   /* Parse argument list.  */
   26430           50 :   rhs = c_parser_postfix_expression_after_primary (
   26431           50 :     parser, EXPR_LOC_OR_LOC (rhs.value, expr_loc), rhs);
   26432           50 :   if (TREE_CODE (rhs.value) != CALL_EXPR)
   26433              :     {
   26434            0 :       error_at (EXPR_LOC_OR_LOC (rhs.value, expr_loc),
   26435              :                 "expected target-function call");
   26436            0 :       return error_mark_node;
   26437              :     }
   26438              : 
   26439              :   /* Build assignment. */
   26440           50 :   rhs = convert_lvalue_to_rvalue (expr_loc, rhs, true, true);
   26441           50 :   ret.value
   26442           50 :     = build_modify_expr (op_location, lhs.value, lhs.original_type, NOP_EXPR,
   26443              :                          expr_loc, rhs.value, rhs.original_type);
   26444           50 :   ret.m_decimal = 0;
   26445           50 :   set_c_expr_source_range (&ret, lhs.get_start (), rhs.get_finish ());
   26446           50 :   ret.original_code = MODIFY_EXPR;
   26447           50 :   ret.original_type = NULL;
   26448           50 :   return ret.value;
   26449              : }
   26450              : 
   26451              : /* OpenMP 5.1:
   26452              :    # pragma omp dispatch dispatch-clause[optseq] new-line
   26453              :      expression-stmt
   26454              : 
   26455              :    LOC is the location of the #pragma.
   26456              : */
   26457              : 
   26458              : #define OMP_DISPATCH_CLAUSE_MASK                                               \
   26459              :   ((OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)                             \
   26460              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)                           \
   26461              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOVARIANTS)                       \
   26462              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOCONTEXT)                        \
   26463              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR)                  \
   26464              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INTEROP)                          \
   26465              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)                    \
   26466              :    | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   26467              : 
   26468              : static tree
   26469          155 : c_parser_omp_dispatch (location_t loc, c_parser *parser)
   26470              : {
   26471          155 :   tree stmt = make_node (OMP_DISPATCH);
   26472          155 :   SET_EXPR_LOCATION (stmt, loc);
   26473          155 :   TREE_TYPE (stmt) = void_type_node;
   26474              : 
   26475          155 :   OMP_DISPATCH_CLAUSES (stmt)
   26476          155 :     = c_parser_omp_all_clauses (parser, OMP_DISPATCH_CLAUSE_MASK,
   26477              :                                 "#pragma omp dispatch");
   26478              : 
   26479              :   // Extract depend clauses and create taskwait
   26480          155 :   tree depend_clauses = NULL_TREE;
   26481          155 :   tree *depend_clauses_ptr = &depend_clauses;
   26482          342 :   for (tree c = OMP_DISPATCH_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
   26483              :     {
   26484          187 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEPEND)
   26485              :         {
   26486            5 :           *depend_clauses_ptr = c;
   26487            5 :           depend_clauses_ptr = &OMP_CLAUSE_CHAIN (c);
   26488              :         }
   26489              :     }
   26490          155 :   if (depend_clauses != NULL_TREE)
   26491              :     {
   26492            5 :       tree stmt = make_node (OMP_TASK);
   26493            5 :       TREE_TYPE (stmt) = void_node;
   26494            5 :       OMP_TASK_CLAUSES (stmt) = depend_clauses;
   26495            5 :       OMP_TASK_BODY (stmt) = NULL_TREE;
   26496            5 :       SET_EXPR_LOCATION (stmt, loc);
   26497            5 :       add_stmt (stmt);
   26498              :     }
   26499              : 
   26500              :   // Parse body as expression statement
   26501          155 :   loc = c_parser_peek_token (parser)->location;
   26502          155 :   tree dispatch_body = c_parser_omp_dispatch_body (parser);
   26503          155 :   if (dispatch_body == error_mark_node)
   26504              :     {
   26505            6 :       inform (loc, "%<#pragma omp dispatch%> must be followed by a function "
   26506              :                    "call with optional assignment");
   26507            6 :       c_parser_skip_to_end_of_block_or_statement (parser);
   26508            6 :       return NULL_TREE;
   26509              :     }
   26510              : 
   26511              :   // Walk the tree to find the dispatch function call and wrap it into an IFN
   26512          149 :   gcc_assert (TREE_CODE (dispatch_body) == CALL_EXPR
   26513              :               || TREE_CODE (dispatch_body) == MODIFY_EXPR);
   26514          149 :   tree *dispatch_call = TREE_CODE (dispatch_body) == MODIFY_EXPR
   26515          149 :                           ? &TREE_OPERAND (dispatch_body, 1)
   26516              :                           : &dispatch_body;
   26517          154 :   while (TREE_CODE (*dispatch_call) == FLOAT_EXPR
   26518              :          || TREE_CODE (*dispatch_call) == CONVERT_EXPR
   26519          154 :          || TREE_CODE (*dispatch_call) == NOP_EXPR)
   26520            5 :     dispatch_call = &TREE_OPERAND (*dispatch_call, 0);
   26521          149 :   *dispatch_call = build_call_expr_internal_loc (
   26522              :     loc, IFN_GOMP_DISPATCH,
   26523          149 :     TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (*dispatch_call))), 1, *dispatch_call);
   26524              : 
   26525          149 :   c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
   26526          149 :   OMP_DISPATCH_BODY (stmt) = dispatch_body;
   26527              : 
   26528          149 :   return add_stmt (stmt);
   26529              : }
   26530              : 
   26531              : /* OpenMP 3.0:
   26532              :    # pragma omp task task-clause[optseq] new-line
   26533              : 
   26534              :    LOC is the location of the #pragma.
   26535              : */
   26536              : 
   26537              : #define OMP_TASK_CLAUSE_MASK                                    \
   26538              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   26539              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
   26540              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)        \
   26541              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26542              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26543              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   26544              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)  \
   26545              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)      \
   26546              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   26547              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)       \
   26548              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26549              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)   \
   26550              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH) \
   26551              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))
   26552              : 
   26553              : static tree
   26554          898 : c_parser_omp_task (location_t loc, c_parser *parser, bool *if_p)
   26555              : {
   26556          898 :   tree clauses, block;
   26557              : 
   26558          898 :   clauses = c_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
   26559              :                                       "#pragma omp task");
   26560              : 
   26561          898 :   block = c_begin_omp_task ();
   26562          898 :   parser->omp_attrs_forbidden_p = true;
   26563          898 :   c_parser_statement (parser, if_p);
   26564          898 :   return c_finish_omp_task (loc, clauses, block);
   26565              : }
   26566              : 
   26567              : /* OpenMP 3.0:
   26568              :    # pragma omp taskwait new-line
   26569              : 
   26570              :    OpenMP 5.0:
   26571              :    # pragma omp taskwait taskwait-clause[optseq] new-line
   26572              : */
   26573              : 
   26574              : #define OMP_TASKWAIT_CLAUSE_MASK                                        \
   26575              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)         \
   26576              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   26577              : 
   26578              : static void
   26579           93 : c_parser_omp_taskwait (c_parser *parser)
   26580              : {
   26581           93 :   location_t loc = c_parser_peek_token (parser)->location;
   26582           93 :   c_parser_consume_pragma (parser);
   26583              : 
   26584           93 :   tree clauses
   26585           93 :     = c_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
   26586              :                                 "#pragma omp taskwait");
   26587              : 
   26588           93 :   if (clauses)
   26589              :     {
   26590           21 :       tree stmt = make_node (OMP_TASK);
   26591           21 :       TREE_TYPE (stmt) = void_node;
   26592           21 :       OMP_TASK_CLAUSES (stmt) = clauses;
   26593           21 :       OMP_TASK_BODY (stmt) = NULL_TREE;
   26594           21 :       SET_EXPR_LOCATION (stmt, loc);
   26595           21 :       add_stmt (stmt);
   26596              :     }
   26597              :   else
   26598           72 :     c_finish_omp_taskwait (loc);
   26599           93 : }
   26600              : 
   26601              : /* OpenMP 3.1:
   26602              :    # pragma omp taskyield new-line
   26603              : */
   26604              : 
   26605              : static void
   26606            6 : c_parser_omp_taskyield (c_parser *parser)
   26607              : {
   26608            6 :   location_t loc = c_parser_peek_token (parser)->location;
   26609            6 :   c_parser_consume_pragma (parser);
   26610            6 :   c_parser_skip_to_pragma_eol (parser);
   26611              : 
   26612            6 :   c_finish_omp_taskyield (loc);
   26613            6 : }
   26614              : 
   26615              : /* OpenMP 4.0:
   26616              :    # pragma omp taskgroup new-line
   26617              : 
   26618              :    OpenMP 5.0:
   26619              :    # pragma omp taskgroup taskgroup-clause[optseq] new-line
   26620              : */
   26621              : 
   26622              : #define OMP_TASKGROUP_CLAUSE_MASK                               \
   26623              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26624              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))
   26625              : 
   26626              : static tree
   26627          138 : c_parser_omp_taskgroup (location_t loc, c_parser *parser, bool *if_p)
   26628              : {
   26629          138 :   tree clauses = c_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
   26630              :                                            "#pragma omp taskgroup");
   26631              : 
   26632          138 :   tree body = c_parser_omp_structured_block (parser, if_p);
   26633          138 :   return c_finish_omp_taskgroup (loc, body, clauses);
   26634              : }
   26635              : 
   26636              : /* OpenMP 4.0:
   26637              :    # pragma omp cancel cancel-clause[optseq] new-line
   26638              : 
   26639              :    LOC is the location of the #pragma.
   26640              : */
   26641              : 
   26642              : #define OMP_CANCEL_CLAUSE_MASK                                  \
   26643              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)       \
   26644              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)            \
   26645              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)       \
   26646              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)      \
   26647              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))
   26648              : 
   26649              : static void
   26650          213 : c_parser_omp_cancel (c_parser *parser)
   26651              : {
   26652          213 :   location_t loc = c_parser_peek_token (parser)->location;
   26653              : 
   26654          213 :   c_parser_consume_pragma (parser);
   26655          213 :   tree clauses = c_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
   26656              :                                            "#pragma omp cancel");
   26657              : 
   26658          213 :   c_finish_omp_cancel (loc, clauses);
   26659          213 : }
   26660              : 
   26661              : /* OpenMP 4.0:
   26662              :    # pragma omp cancellation point cancelpt-clause[optseq] new-line
   26663              : 
   26664              :    LOC is the location of the #pragma.
   26665              : */
   26666              : 
   26667              : #define OMP_CANCELLATION_POINT_CLAUSE_MASK                      \
   26668              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)       \
   26669              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)            \
   26670              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)       \
   26671              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))
   26672              : 
   26673              : static bool
   26674          179 : c_parser_omp_cancellation_point (c_parser *parser, enum pragma_context context)
   26675              : {
   26676          179 :   location_t loc = c_parser_peek_token (parser)->location;
   26677          179 :   tree clauses;
   26678          179 :   bool point_seen = false;
   26679              : 
   26680          179 :   c_parser_consume_pragma (parser);
   26681          179 :   if (c_parser_next_token_is (parser, CPP_NAME))
   26682              :     {
   26683          179 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   26684          179 :       if (strcmp (p, "point") == 0)
   26685              :         {
   26686          177 :           c_parser_consume_token (parser);
   26687          177 :           point_seen = true;
   26688              :         }
   26689              :     }
   26690          177 :   if (!point_seen)
   26691              :     {
   26692            2 :       c_parser_error (parser, "expected %<point%>");
   26693            2 :       c_parser_skip_to_pragma_eol (parser);
   26694            2 :       return false;
   26695              :     }
   26696              : 
   26697          177 :   if (context != pragma_compound)
   26698              :     {
   26699           10 :       if (context == pragma_stmt)
   26700            9 :         error_at (loc,
   26701              :                   "%<#pragma %s%> may only be used in compound statements",
   26702              :                   "omp cancellation point");
   26703              :       else
   26704            1 :         c_parser_error (parser, "expected declaration specifiers");
   26705           10 :       c_parser_skip_to_pragma_eol (parser, false);
   26706           10 :       return true;
   26707              :     }
   26708              : 
   26709          167 :   clauses
   26710          167 :     = c_parser_omp_all_clauses (parser, OMP_CANCELLATION_POINT_CLAUSE_MASK,
   26711              :                                 "#pragma omp cancellation point");
   26712              : 
   26713          167 :   c_finish_omp_cancellation_point (loc, clauses);
   26714          167 :   return true;
   26715              : }
   26716              : 
   26717              : /* OpenMP 4.0:
   26718              :    #pragma omp distribute distribute-clause[optseq] new-line
   26719              :      for-loop  */
   26720              : 
   26721              : #define OMP_DISTRIBUTE_CLAUSE_MASK                              \
   26722              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26723              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26724              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   26725              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
   26726              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26727              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   26728              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))
   26729              : 
   26730              : static tree
   26731         3427 : c_parser_omp_distribute (location_t loc, c_parser *parser,
   26732              :                          char *p_name, omp_clause_mask mask, tree *cclauses,
   26733              :                          bool *if_p)
   26734              : {
   26735         3427 :   tree clauses, block, ret;
   26736              : 
   26737         3427 :   strcat (p_name, " distribute");
   26738         3427 :   mask |= OMP_DISTRIBUTE_CLAUSE_MASK;
   26739              : 
   26740         3427 :   if (c_parser_next_token_is (parser, CPP_NAME))
   26741              :     {
   26742         3331 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   26743         3331 :       bool simd = false;
   26744         3331 :       bool parallel = false;
   26745              : 
   26746         3331 :       if (strcmp (p, "simd") == 0)
   26747              :         simd = true;
   26748              :       else
   26749         2991 :         parallel = strcmp (p, "parallel") == 0;
   26750         2991 :       if (parallel || simd)
   26751              :         {
   26752         3064 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26753         3064 :           if (cclauses == NULL)
   26754         1147 :             cclauses = cclauses_buf;
   26755         3064 :           c_parser_consume_token (parser);
   26756         3064 :           if (!flag_openmp)  /* flag_openmp_simd  */
   26757              :             {
   26758           15 :               if (simd)
   26759            6 :                 return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
   26760            6 :                                           if_p);
   26761              :               else
   26762            9 :                 return c_parser_omp_parallel (loc, parser, p_name, mask,
   26763            9 :                                               cclauses, if_p);
   26764              :             }
   26765         3049 :           block = c_begin_compound_stmt (true);
   26766         3049 :           if (simd)
   26767          334 :             ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
   26768              :                                      if_p);
   26769              :           else
   26770         2715 :             ret = c_parser_omp_parallel (loc, parser, p_name, mask, cclauses,
   26771              :                                          if_p);
   26772         3049 :           block = c_end_compound_stmt (loc, block, true);
   26773         3049 :           if (ret == NULL)
   26774              :             return ret;
   26775         3044 :           ret = make_node (OMP_DISTRIBUTE);
   26776         3044 :           TREE_TYPE (ret) = void_type_node;
   26777         3044 :           OMP_FOR_BODY (ret) = block;
   26778         3044 :           OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
   26779         3044 :           SET_EXPR_LOCATION (ret, loc);
   26780         3044 :           add_stmt (ret);
   26781         3044 :           return ret;
   26782              :         }
   26783              :     }
   26784          363 :   if (!flag_openmp)  /* flag_openmp_simd  */
   26785              :     {
   26786            2 :       c_parser_skip_to_pragma_eol (parser, false);
   26787            2 :       return NULL_TREE;
   26788              :     }
   26789              : 
   26790          361 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   26791          361 :   if (cclauses)
   26792              :     {
   26793          194 :       omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
   26794          194 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
   26795              :     }
   26796              : 
   26797          361 :   block = c_begin_compound_stmt (true);
   26798          361 :   ret = c_parser_omp_for_loop (loc, parser, OMP_DISTRIBUTE, clauses, NULL,
   26799              :                                if_p);
   26800          361 :   block = c_end_compound_stmt (loc, block, true);
   26801          361 :   add_stmt (block);
   26802              : 
   26803          361 :   return ret;
   26804              : }
   26805              : 
   26806              : /* OpenMP 4.0:
   26807              :    # pragma omp teams teams-clause[optseq] new-line
   26808              :      structured-block  */
   26809              : 
   26810              : #define OMP_TEAMS_CLAUSE_MASK                                   \
   26811              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   26812              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   26813              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   26814              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   26815              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)      \
   26816              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)   \
   26817              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   26818              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))
   26819              : 
   26820              : static tree
   26821         3670 : c_parser_omp_teams (location_t loc, c_parser *parser,
   26822              :                     char *p_name, omp_clause_mask mask, tree *cclauses,
   26823              :                     bool *if_p)
   26824              : {
   26825         3670 :   tree clauses, block, ret;
   26826              : 
   26827         3670 :   strcat (p_name, " teams");
   26828         3670 :   mask |= OMP_TEAMS_CLAUSE_MASK;
   26829              : 
   26830         3670 :   if (c_parser_next_token_is (parser, CPP_NAME))
   26831              :     {
   26832         2341 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   26833         2341 :       if (strcmp (p, "distribute") == 0)
   26834              :         {
   26835         2113 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26836         2113 :           if (cclauses == NULL)
   26837         1271 :             cclauses = cclauses_buf;
   26838              : 
   26839         2113 :           c_parser_consume_token (parser);
   26840         2113 :           if (!flag_openmp)  /* flag_openmp_simd  */
   26841           12 :             return c_parser_omp_distribute (loc, parser, p_name, mask,
   26842           12 :                                             cclauses, if_p);
   26843         2101 :           block = c_begin_omp_parallel ();
   26844         2101 :           ret = c_parser_omp_distribute (loc, parser, p_name, mask, cclauses,
   26845              :                                          if_p);
   26846         2101 :           block = c_end_compound_stmt (loc, block, true);
   26847         2101 :           if (ret == NULL)
   26848              :             return ret;
   26849         2101 :           clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   26850         2101 :           ret = make_node (OMP_TEAMS);
   26851         2101 :           TREE_TYPE (ret) = void_type_node;
   26852         2101 :           OMP_TEAMS_CLAUSES (ret) = clauses;
   26853         2101 :           OMP_TEAMS_BODY (ret) = block;
   26854         2101 :           OMP_TEAMS_COMBINED (ret) = 1;
   26855         2101 :           SET_EXPR_LOCATION (ret, loc);
   26856         2101 :           return add_stmt (ret);
   26857              :         }
   26858          228 :       else if (strcmp (p, "loop") == 0)
   26859              :         {
   26860           34 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   26861           34 :           if (cclauses == NULL)
   26862           16 :             cclauses = cclauses_buf;
   26863              : 
   26864           34 :           c_parser_consume_token (parser);
   26865           34 :           if (!flag_openmp)  /* flag_openmp_simd  */
   26866            2 :             return c_parser_omp_loop (loc, parser, p_name, mask, cclauses,
   26867            2 :                                       if_p);
   26868           32 :           block = c_begin_omp_parallel ();
   26869           32 :           ret = c_parser_omp_loop (loc, parser, p_name, mask, cclauses, if_p);
   26870           32 :           block = c_end_compound_stmt (loc, block, true);
   26871           32 :           if (ret == NULL)
   26872              :             return ret;
   26873           32 :           clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   26874           32 :           ret = make_node (OMP_TEAMS);
   26875           32 :           TREE_TYPE (ret) = void_type_node;
   26876           32 :           OMP_TEAMS_CLAUSES (ret) = clauses;
   26877           32 :           OMP_TEAMS_BODY (ret) = block;
   26878           32 :           OMP_TEAMS_COMBINED (ret) = 1;
   26879           32 :           SET_EXPR_LOCATION (ret, loc);
   26880           32 :           return add_stmt (ret);
   26881              :         }
   26882              :     }
   26883         1523 :   if (!flag_openmp)  /* flag_openmp_simd  */
   26884              :     {
   26885            2 :       c_parser_skip_to_pragma_eol (parser, false);
   26886            2 :       return NULL_TREE;
   26887              :     }
   26888              : 
   26889         1521 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   26890         1521 :   if (cclauses)
   26891              :     {
   26892          883 :       omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
   26893          883 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   26894              :     }
   26895              : 
   26896         1521 :   tree stmt = make_node (OMP_TEAMS);
   26897         1521 :   TREE_TYPE (stmt) = void_type_node;
   26898         1521 :   OMP_TEAMS_CLAUSES (stmt) = clauses;
   26899         1521 :   block = c_begin_omp_parallel ();
   26900         1521 :   add_stmt (c_parser_omp_structured_block (parser, if_p));
   26901         1521 :   OMP_TEAMS_BODY (stmt) = c_end_compound_stmt (loc, block, true);
   26902         1521 :   SET_EXPR_LOCATION (stmt, loc);
   26903              : 
   26904         1521 :   return add_stmt (stmt);
   26905              : }
   26906              : 
   26907              : /* OpenMP 4.0:
   26908              :    # pragma omp target data target-data-clause[optseq] new-line
   26909              :      structured-block  */
   26910              : 
   26911              : #define OMP_TARGET_DATA_CLAUSE_MASK                             \
   26912              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   26913              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   26914              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   26915              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
   26916              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
   26917              : 
   26918              : static tree
   26919          155 : c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
   26920              : {
   26921          155 :   if (flag_openmp)
   26922          155 :     omp_requires_mask
   26923          155 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   26924              : 
   26925          155 :   tree clauses
   26926          155 :     = c_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
   26927          155 :                                 "#pragma omp target data");
   26928          155 :   c_omp_adjust_map_clauses (clauses, false);
   26929          155 :   int map_seen = 0;
   26930          455 :   for (tree *pc = &clauses; *pc;)
   26931              :     {
   26932          300 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   26933          218 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   26934              :           {
   26935              :           case GOMP_MAP_TO:
   26936              :           case GOMP_MAP_ALWAYS_TO:
   26937              :           case GOMP_MAP_PRESENT_TO:
   26938              :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   26939              :           case GOMP_MAP_FROM:
   26940              :           case GOMP_MAP_ALWAYS_FROM:
   26941              :           case GOMP_MAP_PRESENT_FROM:
   26942              :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   26943              :           case GOMP_MAP_TOFROM:
   26944              :           case GOMP_MAP_ALWAYS_TOFROM:
   26945              :           case GOMP_MAP_PRESENT_TOFROM:
   26946              :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   26947              :           case GOMP_MAP_ALLOC:
   26948              :           case GOMP_MAP_PRESENT_ALLOC:
   26949          300 :             map_seen = 3;
   26950              :             break;
   26951              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   26952              :           case GOMP_MAP_ALWAYS_POINTER:
   26953              :           case GOMP_MAP_ATTACH_DETACH:
   26954              :           case GOMP_MAP_ATTACH:
   26955              :             break;
   26956            0 :           default:
   26957            0 :             map_seen |= 1;
   26958            0 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   26959              :                       "%<#pragma omp target data%> with map-type other "
   26960              :                       "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
   26961              :                       "on %<map%> clause");
   26962            0 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   26963            0 :             continue;
   26964              :           }
   26965           82 :       else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
   26966           82 :                || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
   26967              :         map_seen = 3;
   26968          300 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   26969              :     }
   26970              : 
   26971          155 :   if (map_seen != 3)
   26972              :     {
   26973            3 :       if (map_seen == 0)
   26974            3 :         error_at (loc,
   26975              :                   "%<#pragma omp target data%> must contain at least "
   26976              :                   "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
   26977              :                   "clause");
   26978            3 :       return NULL_TREE;
   26979              :     }
   26980              : 
   26981          152 :   tree stmt = make_node (OMP_TARGET_DATA);
   26982          152 :   TREE_TYPE (stmt) = void_type_node;
   26983          152 :   OMP_TARGET_DATA_CLAUSES (stmt) = clauses;
   26984          152 :   keep_next_level ();
   26985          152 :   tree block = c_begin_compound_stmt (true);
   26986          152 :   add_stmt (c_parser_omp_structured_block (parser, if_p));
   26987          152 :   OMP_TARGET_DATA_BODY (stmt) = c_end_compound_stmt (loc, block, true);
   26988              : 
   26989          152 :   SET_EXPR_LOCATION (stmt, loc);
   26990          152 :   return add_stmt (stmt);
   26991              : }
   26992              : 
   26993              : /* OpenMP 4.0:
   26994              :    # pragma omp target update target-update-clause[optseq] new-line */
   26995              : 
   26996              : #define OMP_TARGET_UPDATE_CLAUSE_MASK                           \
   26997              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM)           \
   26998              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)             \
   26999              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   27000              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   27001              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   27002              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   27003              : 
   27004              : static bool
   27005         2837 : c_parser_omp_target_update (location_t loc, c_parser *parser,
   27006              :                             enum pragma_context context)
   27007              : {
   27008         2837 :   if (context == pragma_stmt)
   27009              :     {
   27010            8 :       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
   27011              :                 "omp target update");
   27012            8 :       c_parser_skip_to_pragma_eol (parser, false);
   27013            8 :       return true;
   27014              :     }
   27015              : 
   27016         2829 :   tree clauses
   27017         2829 :     = c_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
   27018              :                                 "#pragma omp target update");
   27019         2829 :   if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
   27020         2829 :       && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
   27021              :     {
   27022            5 :       error_at (loc,
   27023              :                 "%<#pragma omp target update%> must contain at least one "
   27024              :                 "%<from%> or %<to%> clauses");
   27025            5 :       return false;
   27026              :     }
   27027              : 
   27028         2824 :   if (flag_openmp)
   27029         2824 :     omp_requires_mask
   27030         2824 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   27031              : 
   27032         2824 :   tree stmt = make_node (OMP_TARGET_UPDATE);
   27033         2824 :   TREE_TYPE (stmt) = void_type_node;
   27034         2824 :   OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
   27035         2824 :   SET_EXPR_LOCATION (stmt, loc);
   27036         2824 :   add_stmt (stmt);
   27037         2824 :   return false;
   27038              : }
   27039              : 
   27040              : /* OpenMP 4.5:
   27041              :    # pragma omp target enter data target-data-clause[optseq] new-line  */
   27042              : 
   27043              : #define OMP_TARGET_ENTER_DATA_CLAUSE_MASK                       \
   27044              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   27045              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   27046              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   27047              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   27048              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   27049              : 
   27050              : static bool
   27051          116 : c_parser_omp_target_enter_data (location_t loc, c_parser *parser,
   27052              :                                 enum pragma_context context)
   27053              : {
   27054          116 :   bool data_seen = false;
   27055          116 :   if (c_parser_next_token_is (parser, CPP_NAME))
   27056              :     {
   27057          116 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   27058          116 :       if (strcmp (p, "data") == 0)
   27059              :         {
   27060          116 :           c_parser_consume_token (parser);
   27061          116 :           data_seen = true;
   27062              :         }
   27063              :     }
   27064          116 :   if (!data_seen)
   27065              :     {
   27066            0 :       c_parser_error (parser, "expected %<data%>");
   27067            0 :       c_parser_skip_to_pragma_eol (parser);
   27068            0 :       return false;
   27069              :     }
   27070              : 
   27071          116 :   if (context == pragma_stmt)
   27072              :     {
   27073            8 :       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
   27074              :                 "omp target enter data");
   27075            8 :       c_parser_skip_to_pragma_eol (parser, false);
   27076            8 :       return true;
   27077              :     }
   27078              : 
   27079          108 :   if (flag_openmp)
   27080          108 :     omp_requires_mask
   27081          108 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   27082              : 
   27083          108 :   tree clauses
   27084          108 :     = c_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
   27085          108 :                                 "#pragma omp target enter data");
   27086          108 :   c_omp_adjust_map_clauses (clauses, false);
   27087          108 :   int map_seen = 0;
   27088          388 :   for (tree *pc = &clauses; *pc;)
   27089              :     {
   27090          280 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   27091          237 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   27092              :           {
   27093              :           case GOMP_MAP_TO:
   27094              :           case GOMP_MAP_ALWAYS_TO:
   27095              :           case GOMP_MAP_PRESENT_TO:
   27096              :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   27097              :           case GOMP_MAP_ALLOC:
   27098              :           case GOMP_MAP_PRESENT_ALLOC:
   27099          184 :             map_seen = 3;
   27100              :             break;
   27101           34 :           case GOMP_MAP_TOFROM:
   27102           34 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
   27103           34 :             map_seen = 3;
   27104           34 :             break;
   27105            3 :           case GOMP_MAP_ALWAYS_TOFROM:
   27106            3 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
   27107            3 :             map_seen = 3;
   27108            3 :             break;
   27109            2 :           case GOMP_MAP_PRESENT_TOFROM:
   27110            2 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_TO);
   27111            2 :             map_seen = 3;
   27112            2 :             break;
   27113            2 :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   27114            2 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_TO);
   27115            2 :             map_seen = 3;
   27116            2 :             break;
   27117              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   27118              :           case GOMP_MAP_ALWAYS_POINTER:
   27119              :           case GOMP_MAP_ATTACH_DETACH:
   27120              :           case GOMP_MAP_ATTACH:
   27121              :             break;
   27122            2 :           default:
   27123            2 :             map_seen |= 1;
   27124            2 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   27125              :                       "%<#pragma omp target enter data%> with map-type other "
   27126              :                       "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
   27127            2 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   27128            2 :             continue;
   27129              :           }
   27130          278 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   27131              :     }
   27132              : 
   27133          108 :   if (map_seen != 3)
   27134              :     {
   27135            4 :       if (map_seen == 0)
   27136            2 :         error_at (loc,
   27137              :                   "%<#pragma omp target enter data%> must contain at least "
   27138              :                   "one %<map%> clause");
   27139            4 :       return true;
   27140              :     }
   27141              : 
   27142          104 :   tree stmt = make_node (OMP_TARGET_ENTER_DATA);
   27143          104 :   TREE_TYPE (stmt) = void_type_node;
   27144          104 :   OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
   27145          104 :   SET_EXPR_LOCATION (stmt, loc);
   27146          104 :   add_stmt (stmt);
   27147          104 :   return true;
   27148              : }
   27149              : 
   27150              : /* OpenMP 4.5:
   27151              :    # pragma omp target exit data target-data-clause[optseq] new-line  */
   27152              : 
   27153              : #define OMP_TARGET_EXIT_DATA_CLAUSE_MASK                        \
   27154              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   27155              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   27156              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   27157              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   27158              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))
   27159              : 
   27160              : static bool
   27161          107 : c_parser_omp_target_exit_data (location_t loc, c_parser *parser,
   27162              :                                enum pragma_context context)
   27163              : {
   27164          107 :   bool data_seen = false;
   27165          107 :   if (c_parser_next_token_is (parser, CPP_NAME))
   27166              :     {
   27167          107 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   27168          107 :       if (strcmp (p, "data") == 0)
   27169              :         {
   27170          107 :           c_parser_consume_token (parser);
   27171          107 :           data_seen = true;
   27172              :         }
   27173              :     }
   27174          107 :   if (!data_seen)
   27175              :     {
   27176            0 :       c_parser_error (parser, "expected %<data%>");
   27177            0 :       c_parser_skip_to_pragma_eol (parser);
   27178            0 :       return false;
   27179              :     }
   27180              : 
   27181          107 :   if (context == pragma_stmt)
   27182              :     {
   27183            8 :       error_at (loc, "%<#pragma %s%> may only be used in compound statements",
   27184              :                 "omp target exit data");
   27185            8 :       c_parser_skip_to_pragma_eol (parser, false);
   27186            8 :       return true;
   27187              :     }
   27188              : 
   27189           99 :   if (flag_openmp)
   27190           99 :     omp_requires_mask
   27191           99 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   27192              : 
   27193           99 :   tree clauses
   27194           99 :     = c_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
   27195              :                                 "#pragma omp target exit data", false);
   27196           99 :   clauses = c_finish_omp_clauses (clauses, C_ORT_OMP_EXIT_DATA);
   27197           99 :   c_omp_adjust_map_clauses (clauses, false);
   27198           99 :   int map_seen = 0;
   27199          349 :   for (tree *pc = &clauses; *pc;)
   27200              :     {
   27201          250 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   27202          207 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   27203              :           {
   27204              :           case GOMP_MAP_FROM:
   27205              :           case GOMP_MAP_ALWAYS_FROM:
   27206              :           case GOMP_MAP_PRESENT_FROM:
   27207              :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   27208              :           case GOMP_MAP_RELEASE:
   27209              :           case GOMP_MAP_DELETE:
   27210          158 :             map_seen = 3;
   27211              :             break;
   27212           30 :           case GOMP_MAP_TOFROM:
   27213           30 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
   27214           30 :             map_seen = 3;
   27215           30 :             break;
   27216            1 :           case GOMP_MAP_ALWAYS_TOFROM:
   27217            1 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
   27218            1 :             map_seen = 3;
   27219            1 :             break;
   27220            0 :           case GOMP_MAP_PRESENT_TOFROM:
   27221            0 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_PRESENT_FROM);
   27222            0 :             map_seen = 3;
   27223            0 :             break;
   27224            0 :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   27225            0 :             OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_PRESENT_FROM);
   27226            0 :             map_seen = 3;
   27227            0 :             break;
   27228              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   27229              :           case GOMP_MAP_ALWAYS_POINTER:
   27230              :           case GOMP_MAP_ATTACH_DETACH:
   27231              :           case GOMP_MAP_DETACH:
   27232              :             break;
   27233            2 :           default:
   27234            2 :             map_seen |= 1;
   27235            2 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   27236              :                       "%<#pragma omp target exit data%> with map-type other "
   27237              :                       "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
   27238              :                       "on %<map%> clause");
   27239            2 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   27240            2 :             continue;
   27241              :           }
   27242          248 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   27243              :     }
   27244              : 
   27245           99 :   if (map_seen != 3)
   27246              :     {
   27247            2 :       if (map_seen == 0)
   27248            0 :         error_at (loc,
   27249              :                   "%<#pragma omp target exit data%> must contain at least one "
   27250              :                   "%<map%> clause");
   27251            2 :       return true;
   27252              :     }
   27253              : 
   27254           97 :   tree stmt = make_node (OMP_TARGET_EXIT_DATA);
   27255           97 :   TREE_TYPE (stmt) = void_type_node;
   27256           97 :   OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
   27257           97 :   SET_EXPR_LOCATION (stmt, loc);
   27258           97 :   add_stmt (stmt);
   27259           97 :   return true;
   27260              : }
   27261              : 
   27262              : /* OpenMP 4.0:
   27263              :    # pragma omp target target-clause[optseq] new-line
   27264              :      structured-block  */
   27265              : 
   27266              : #define OMP_TARGET_CLAUSE_MASK                                  \
   27267              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   27268              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP)     \
   27269              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND) \
   27270              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
   27271              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)    \
   27272              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DYN_GROUPPRIVATE) \
   27273              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   27274              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR) \
   27275              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   27276              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)   \
   27277              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
   27278              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)            \
   27279              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT) \
   27280              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   27281              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)   \
   27282              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USES_ALLOCATORS))
   27283              : 
   27284              : static bool
   27285         7549 : c_parser_omp_target (c_parser *parser, enum pragma_context context, bool *if_p)
   27286              : {
   27287         7549 :   location_t loc = c_parser_peek_token (parser)->location;
   27288         7549 :   c_parser_consume_pragma (parser);
   27289         7549 :   tree *pc = NULL, stmt, block, body, clauses;
   27290              : 
   27291         7549 :   if (context != pragma_stmt && context != pragma_compound)
   27292              :     {
   27293            2 :       c_parser_error (parser, "expected declaration specifiers");
   27294            2 :       c_parser_skip_to_pragma_eol (parser);
   27295            2 :       return false;
   27296              :     }
   27297              : 
   27298         7547 :   if (flag_openmp)
   27299         7533 :     omp_requires_mask
   27300         7533 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   27301              : 
   27302         7547 :   if (c_parser_next_token_is (parser, CPP_NAME))
   27303              :     {
   27304         6616 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   27305         6616 :       enum tree_code ccode = ERROR_MARK;
   27306              : 
   27307         6616 :       if (strcmp (p, "teams") == 0)
   27308              :         ccode = OMP_TEAMS;
   27309         4872 :       else if (strcmp (p, "parallel") == 0)
   27310              :         ccode = OMP_PARALLEL;
   27311         4382 :       else if (strcmp (p, "simd") == 0)
   27312              :         ccode = OMP_SIMD;
   27313         4322 :       if (ccode != ERROR_MARK)
   27314              :         {
   27315         2294 :           tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
   27316         2294 :           char p_name[sizeof ("#pragma omp target teams distribute "
   27317              :                               "parallel for simd")];
   27318              : 
   27319         2294 :           c_parser_consume_token (parser);
   27320         2294 :           strcpy (p_name, "#pragma omp target");
   27321         2294 :           if (!flag_openmp)  /* flag_openmp_simd  */
   27322              :             {
   27323           13 :               tree stmt;
   27324           13 :               switch (ccode)
   27325              :                 {
   27326            8 :                 case OMP_TEAMS:
   27327            8 :                   stmt = c_parser_omp_teams (loc, parser, p_name,
   27328            8 :                                              OMP_TARGET_CLAUSE_MASK,
   27329              :                                              cclauses, if_p);
   27330            8 :                   break;
   27331            4 :                 case OMP_PARALLEL:
   27332            4 :                   stmt = c_parser_omp_parallel (loc, parser, p_name,
   27333            4 :                                                 OMP_TARGET_CLAUSE_MASK,
   27334              :                                                 cclauses, if_p);
   27335            4 :                   break;
   27336            1 :                 case OMP_SIMD:
   27337            1 :                   stmt = c_parser_omp_simd (loc, parser, p_name,
   27338            1 :                                             OMP_TARGET_CLAUSE_MASK,
   27339              :                                             cclauses, if_p);
   27340            1 :                   break;
   27341            0 :                 default:
   27342            0 :                   gcc_unreachable ();
   27343              :                 }
   27344           21 :               return stmt != NULL_TREE;
   27345              :             }
   27346         2281 :           keep_next_level ();
   27347         2281 :           tree block = c_begin_compound_stmt (true), ret;
   27348         2281 :           switch (ccode)
   27349              :             {
   27350         1736 :             case OMP_TEAMS:
   27351         1736 :               ret = c_parser_omp_teams (loc, parser, p_name,
   27352         1736 :                                         OMP_TARGET_CLAUSE_MASK, cclauses,
   27353              :                                         if_p);
   27354         1736 :               break;
   27355          486 :             case OMP_PARALLEL:
   27356          486 :               ret = c_parser_omp_parallel (loc, parser, p_name,
   27357          486 :                                            OMP_TARGET_CLAUSE_MASK, cclauses,
   27358              :                                            if_p);
   27359          486 :               break;
   27360           59 :             case OMP_SIMD:
   27361           59 :               ret = c_parser_omp_simd (loc, parser, p_name,
   27362           59 :                                        OMP_TARGET_CLAUSE_MASK, cclauses,
   27363              :                                        if_p);
   27364           59 :               break;
   27365            0 :             default:
   27366            0 :               gcc_unreachable ();
   27367              :             }
   27368         2281 :           block = c_end_compound_stmt (loc, block, true);
   27369         2281 :           if (ret == NULL_TREE)
   27370              :             return false;
   27371         2273 :           if (ccode == OMP_TEAMS)
   27372              :             /* For combined target teams, ensure the num_teams and
   27373              :                thread_limit clause expressions are evaluated on the host,
   27374              :                before entering the target construct.  */
   27375         2217 :             for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
   27376         2217 :                  c; c = OMP_CLAUSE_CHAIN (c))
   27377          481 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
   27378          481 :                   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
   27379          202 :                 for (int i = 0;
   27380          332 :                      i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
   27381          202 :                   if (OMP_CLAUSE_OPERAND (c, i)
   27382          202 :                       && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
   27383              :                     {
   27384          129 :                       tree expr = OMP_CLAUSE_OPERAND (c, i);
   27385          129 :                       tree tmp = create_tmp_var_raw (TREE_TYPE (expr));
   27386          129 :                       expr = build4 (TARGET_EXPR, TREE_TYPE (expr), tmp,
   27387              :                                      expr, NULL_TREE, NULL_TREE);
   27388          129 :                       add_stmt (expr);
   27389          129 :                       OMP_CLAUSE_OPERAND (c, i) = expr;
   27390          129 :                       tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
   27391              :                                                   OMP_CLAUSE_FIRSTPRIVATE);
   27392          129 :                       OMP_CLAUSE_DECL (tc) = tmp;
   27393          129 :                       OMP_CLAUSE_CHAIN (tc)
   27394          129 :                         = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
   27395          129 :                       cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
   27396              :                     }
   27397         2273 :           tree stmt = make_node (OMP_TARGET);
   27398         2273 :           TREE_TYPE (stmt) = void_type_node;
   27399         2273 :           OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
   27400         2273 :           c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
   27401         2273 :           OMP_TARGET_BODY (stmt) = block;
   27402         2273 :           OMP_TARGET_COMBINED (stmt) = 1;
   27403         2273 :           SET_EXPR_LOCATION (stmt, loc);
   27404         2273 :           add_stmt (stmt);
   27405         2273 :           pc = &OMP_TARGET_CLAUSES (stmt);
   27406         2273 :           goto check_clauses;
   27407              :         }
   27408         4322 :       else if (!flag_openmp)  /* flag_openmp_simd  */
   27409              :         {
   27410            0 :           c_parser_skip_to_pragma_eol (parser, false);
   27411            0 :           return false;
   27412              :         }
   27413         4322 :       else if (strcmp (p, "data") == 0)
   27414              :         {
   27415          155 :           c_parser_consume_token (parser);
   27416          155 :           c_parser_omp_target_data (loc, parser, if_p);
   27417          155 :           return true;
   27418              :         }
   27419         4167 :       else if (strcmp (p, "enter") == 0)
   27420              :         {
   27421          116 :           c_parser_consume_token (parser);
   27422          116 :           return c_parser_omp_target_enter_data (loc, parser, context);
   27423              :         }
   27424         4051 :       else if (strcmp (p, "exit") == 0)
   27425              :         {
   27426          107 :           c_parser_consume_token (parser);
   27427          107 :           return c_parser_omp_target_exit_data (loc, parser, context);
   27428              :         }
   27429         3944 :       else if (strcmp (p, "update") == 0)
   27430              :         {
   27431         2837 :           c_parser_consume_token (parser);
   27432         2837 :           return c_parser_omp_target_update (loc, parser, context);
   27433              :         }
   27434              :     }
   27435         2038 :   if (!flag_openmp) /* flag_openmp_simd  */
   27436              :     {
   27437            1 :       c_parser_skip_to_pragma_eol (parser, false);
   27438            1 :       return false;
   27439              :     }
   27440              : 
   27441         2037 :   stmt = make_node (OMP_TARGET);
   27442         2037 :   TREE_TYPE (stmt) = void_type_node;
   27443              : 
   27444         2037 :   clauses = c_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
   27445              :                                       "#pragma omp target", false);
   27446         4010 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   27447         1973 :     if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
   27448              :       {
   27449           50 :         tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
   27450           50 :         OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
   27451           50 :         OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
   27452           50 :         OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
   27453           50 :         OMP_CLAUSE_CHAIN (c) = nc;
   27454              :       }
   27455         2037 :   clauses = c_omp_instantiate_mappers (clauses);
   27456         2037 :   clauses  = c_finish_omp_clauses (clauses, C_ORT_OMP_TARGET);
   27457         2037 :   c_omp_adjust_map_clauses (clauses, true);
   27458              : 
   27459         2037 :   keep_next_level ();
   27460         2037 :   block = c_begin_compound_stmt (true);
   27461         2037 :   body = c_parser_omp_structured_block (parser, if_p);
   27462              : 
   27463         2037 :   c_omp_scan_mapper_bindings (loc, &clauses, body);
   27464              : 
   27465         2037 :   add_stmt (body);
   27466         2037 :   OMP_TARGET_CLAUSES (stmt) = clauses;
   27467         2037 :   pc = &OMP_TARGET_CLAUSES (stmt);
   27468         2037 :   OMP_TARGET_BODY (stmt) = c_end_compound_stmt (loc, block, true);
   27469              : 
   27470         2037 :   SET_EXPR_LOCATION (stmt, loc);
   27471         2037 :   add_stmt (stmt);
   27472              : 
   27473              : check_clauses:
   27474         8061 :   while (*pc)
   27475              :     {
   27476         3751 :       if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
   27477         2085 :         switch (OMP_CLAUSE_MAP_KIND (*pc))
   27478              :           {
   27479              :           case GOMP_MAP_TO:
   27480              :           case GOMP_MAP_ALWAYS_TO:
   27481              :           case GOMP_MAP_PRESENT_TO:
   27482              :           case GOMP_MAP_ALWAYS_PRESENT_TO:
   27483              :           case GOMP_MAP_FROM:
   27484              :           case GOMP_MAP_ALWAYS_FROM:
   27485              :           case GOMP_MAP_PRESENT_FROM:
   27486              :           case GOMP_MAP_ALWAYS_PRESENT_FROM:
   27487              :           case GOMP_MAP_TOFROM:
   27488              :           case GOMP_MAP_ALWAYS_TOFROM:
   27489              :           case GOMP_MAP_PRESENT_TOFROM:
   27490              :           case GOMP_MAP_ALWAYS_PRESENT_TOFROM:
   27491              :           case GOMP_MAP_ALLOC:
   27492              :           case GOMP_MAP_PRESENT_ALLOC:
   27493              :           case GOMP_MAP_FIRSTPRIVATE_POINTER:
   27494              :           case GOMP_MAP_ALWAYS_POINTER:
   27495              :           case GOMP_MAP_POINTER:
   27496              :           case GOMP_MAP_ATTACH_DETACH:
   27497              :           case GOMP_MAP_ATTACH:
   27498              :             break;
   27499            1 :           default:
   27500            1 :             error_at (OMP_CLAUSE_LOCATION (*pc),
   27501              :                       "%<#pragma omp target%> with map-type other "
   27502              :                       "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
   27503              :                       "on %<map%> clause");
   27504            1 :             *pc = OMP_CLAUSE_CHAIN (*pc);
   27505            1 :             continue;
   27506              :           }
   27507         3750 :       pc = &OMP_CLAUSE_CHAIN (*pc);
   27508              :     }
   27509         4310 :   cfun->has_omp_target = true;
   27510         4310 :   return true;
   27511              : }
   27512              : 
   27513              : /* OpenMP 4.0:
   27514              :    # pragma omp declare simd declare-simd-clauses[optseq] new-line
   27515              : 
   27516              :    OpenMP 5.0:
   27517              :    # pragma omp declare variant (identifier) match(context-selector) new-line
   27518              : 
   27519              :    OpenMP 5.1
   27520              :    # pragma omp declare variant (identifier) match(context-selector) \
   27521              :       adjust_args(adjust-op:argument-list) append_args(interop-list) new-line
   27522              :    */
   27523              : 
   27524              : #define OMP_DECLARE_SIMD_CLAUSE_MASK                            \
   27525              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)        \
   27526              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR) \
   27527              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)        \
   27528              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)        \
   27529              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH)       \
   27530              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))
   27531              : 
   27532              : static void
   27533          781 : c_parser_omp_declare_simd (c_parser *parser, enum pragma_context context)
   27534              : {
   27535          781 :   c_token *token = c_parser_peek_token (parser);
   27536          781 :   gcc_assert (token->type == CPP_NAME);
   27537          781 :   tree kind = token->value;
   27538          781 :   gcc_assert (strcmp (IDENTIFIER_POINTER (kind), "simd") == 0
   27539              :               || strcmp (IDENTIFIER_POINTER (kind), "variant") == 0);
   27540              : 
   27541          781 :   auto_vec<c_token> clauses;
   27542        12670 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   27543              :     {
   27544        11889 :       c_token *token = c_parser_peek_token (parser);
   27545        11889 :       if (token->type == CPP_EOF)
   27546              :         {
   27547            0 :           c_parser_skip_to_pragma_eol (parser);
   27548            0 :           return;
   27549              :         }
   27550        11889 :       clauses.safe_push (*token);
   27551        11889 :       c_parser_consume_token (parser);
   27552              :     }
   27553          781 :   clauses.safe_push (*c_parser_peek_token (parser));
   27554          781 :   c_parser_skip_to_pragma_eol (parser);
   27555              : 
   27556         1851 :   while (c_parser_next_token_is (parser, CPP_PRAGMA))
   27557              :     {
   27558          291 :       if (c_parser_peek_token (parser)->pragma_kind != PRAGMA_OMP_DECLARE
   27559          289 :           || c_parser_peek_2nd_token (parser)->type != CPP_NAME
   27560          580 :           || c_parser_peek_2nd_token (parser)->value != kind)
   27561              :         {
   27562            2 :           error ("%<#pragma omp declare %s%> must be followed by "
   27563              :                  "function declaration or definition or another "
   27564              :                  "%<#pragma omp declare %s%>",
   27565            2 :                  IDENTIFIER_POINTER (kind), IDENTIFIER_POINTER (kind));
   27566            2 :           return;
   27567              :         }
   27568          289 :       c_parser_consume_pragma (parser);
   27569         6282 :       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   27570              :         {
   27571         5704 :           c_token *token = c_parser_peek_token (parser);
   27572         5704 :           if (token->type == CPP_EOF)
   27573              :             {
   27574            0 :               c_parser_skip_to_pragma_eol (parser);
   27575            0 :               return;
   27576              :             }
   27577         5704 :           clauses.safe_push (*token);
   27578         5704 :           c_parser_consume_token (parser);
   27579              :         }
   27580          289 :       clauses.safe_push (*c_parser_peek_token (parser));
   27581          289 :       c_parser_skip_to_pragma_eol (parser);
   27582              :     }
   27583              : 
   27584              :   /* Make sure nothing tries to read past the end of the tokens.  */
   27585          779 :   c_token eof_token;
   27586          779 :   memset (&eof_token, 0, sizeof (eof_token));
   27587          779 :   eof_token.type = CPP_EOF;
   27588          779 :   clauses.safe_push (eof_token);
   27589          779 :   clauses.safe_push (eof_token);
   27590              : 
   27591          779 :   switch (context)
   27592              :     {
   27593          762 :     case pragma_external:
   27594          762 :       if (c_parser_next_token_is (parser, CPP_KEYWORD)
   27595          762 :           && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
   27596              :         {
   27597            1 :           int ext = disable_extension_diagnostics ();
   27598            1 :           do
   27599            1 :             c_parser_consume_token (parser);
   27600            1 :           while (c_parser_next_token_is (parser, CPP_KEYWORD)
   27601            2 :                  && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
   27602            1 :           c_parser_declaration_or_fndef (parser, true, true, true, false, true,
   27603              :                                          false, NULL, &clauses);
   27604            1 :           restore_extension_diagnostics (ext);
   27605              :         }
   27606              :       else
   27607          761 :         c_parser_declaration_or_fndef (parser, true, true, true, false, true,
   27608              :                                        false, NULL, &clauses);
   27609              :       break;
   27610            6 :     case pragma_struct:
   27611            6 :     case pragma_param:
   27612            6 :     case pragma_stmt:
   27613            6 :       error ("%<#pragma omp declare %s%> must be followed by "
   27614              :              "function declaration or definition",
   27615            6 :              IDENTIFIER_POINTER (kind));
   27616            6 :       break;
   27617           11 :     case pragma_compound:
   27618           11 :       bool have_std_attrs;
   27619           11 :       tree std_attrs;
   27620           11 :       have_std_attrs = c_parser_nth_token_starts_std_attributes (parser, 1);
   27621           11 :       if (have_std_attrs)
   27622            1 :         std_attrs = c_parser_std_attribute_specifier_sequence (parser);
   27623              :       else
   27624              :         std_attrs = NULL_TREE;
   27625           11 :       if (c_parser_next_token_is (parser, CPP_KEYWORD)
   27626           11 :           && c_parser_peek_token (parser)->keyword == RID_EXTENSION)
   27627              :         {
   27628            1 :           int ext = disable_extension_diagnostics ();
   27629            3 :           do
   27630            3 :             c_parser_consume_token (parser);
   27631            3 :           while (c_parser_next_token_is (parser, CPP_KEYWORD)
   27632            4 :                  && c_parser_peek_token (parser)->keyword == RID_EXTENSION);
   27633            1 :           if (c_parser_next_tokens_start_declaration (parser)
   27634            1 :               || c_parser_nth_token_starts_std_attributes (parser, 1))
   27635              :             {
   27636            1 :               c_parser_declaration_or_fndef (parser, true, true, true, true,
   27637              :                                              true, false, NULL, &clauses,
   27638              :                                              have_std_attrs, std_attrs);
   27639            1 :               restore_extension_diagnostics (ext);
   27640            1 :               break;
   27641              :             }
   27642            0 :           restore_extension_diagnostics (ext);
   27643              :         }
   27644           10 :       else if (c_parser_next_tokens_start_declaration (parser))
   27645              :         {
   27646           10 :           c_parser_declaration_or_fndef (parser, true, true, true, true, true,
   27647              :                                          false, NULL, &clauses, have_std_attrs,
   27648              :                                          std_attrs);
   27649           10 :           break;
   27650              :         }
   27651            0 :       error ("%<#pragma omp declare %s%> must be followed by "
   27652              :              "function declaration or definition",
   27653            0 :              IDENTIFIER_POINTER (kind));
   27654            0 :       break;
   27655            0 :     default:
   27656            0 :       gcc_unreachable ();
   27657              :     }
   27658          781 : }
   27659              : 
   27660              : /* OpenMP 5.0:
   27661              : 
   27662              :    trait-selector:
   27663              :      trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]
   27664              : 
   27665              :    trait-score:
   27666              :      score(score-expression)
   27667              : 
   27668              :    Note that this function returns a list of trait selectors for the
   27669              :    trait-selector-set SET.  */
   27670              : 
   27671              : static tree
   27672         1256 : c_parser_omp_context_selector (c_parser *parser, enum omp_tss_code set,
   27673              :                                tree parms)
   27674              : {
   27675         1256 :   tree ret = NULL_TREE;
   27676         1438 :   do
   27677              :     {
   27678         1438 :       tree selector;
   27679         1438 :       if (c_parser_next_token_is (parser, CPP_KEYWORD)
   27680         2815 :           || c_parser_next_token_is (parser, CPP_NAME))
   27681         1436 :         selector = c_parser_peek_token (parser)->value;
   27682              :       else
   27683              :         {
   27684            2 :           c_parser_error (parser, "expected trait selector name");
   27685            2 :           return error_mark_node;
   27686              :         }
   27687         1436 :       enum omp_ts_code sel
   27688         1436 :         = omp_lookup_ts_code (set, IDENTIFIER_POINTER (selector));
   27689              : 
   27690         1436 :       if (sel == OMP_TRAIT_INVALID)
   27691              :         {
   27692              :           /* Per the spec, "Implementations can ignore specified selectors
   27693              :              that are not those described in this section"; however, we
   27694              :              must record such selectors because they cause match failures.  */
   27695           18 :           warning_at (c_parser_peek_token (parser)->location, OPT_Wopenmp,
   27696              :                       "unknown selector %qs for context selector set %qs",
   27697           18 :                       IDENTIFIER_POINTER (selector),  omp_tss_map[set]);
   27698           18 :           c_parser_consume_token (parser);
   27699           18 :           ret = make_trait_selector (sel, NULL_TREE, NULL_TREE, ret);
   27700           18 :           if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   27701            5 :             c_parser_balanced_token_sequence (parser);
   27702           18 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   27703              :             {
   27704            1 :               c_parser_consume_token (parser);
   27705            1 :               continue;
   27706              :             }
   27707              :           else
   27708              :             break;
   27709              :         }
   27710              : 
   27711         1418 :       c_parser_consume_token (parser);
   27712              : 
   27713         1418 :       tree properties = NULL_TREE;
   27714         1418 :       tree scoreval = NULL_TREE;
   27715         1418 :       enum omp_tp_type property_kind = omp_ts_map[sel].tp_type;
   27716         1418 :       bool allow_score = omp_ts_map[sel].allow_score;
   27717         1418 :       tree t;
   27718              : 
   27719         1418 :       if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   27720              :         {
   27721          810 :           if (property_kind == OMP_TRAIT_PROPERTY_NONE)
   27722              :             {
   27723           12 :               error_at (c_parser_peek_token (parser)->location,
   27724              :                         "selector %qs does not accept any properties",
   27725            6 :                         IDENTIFIER_POINTER (selector));
   27726           16 :               return error_mark_node;
   27727              :             }
   27728              : 
   27729          804 :           matching_parens parens;
   27730          804 :           parens.require_open (parser);
   27731              : 
   27732          804 :           c_token *token = c_parser_peek_token (parser);
   27733          804 :           if (c_parser_next_token_is (parser, CPP_NAME)
   27734          612 :               && strcmp (IDENTIFIER_POINTER (token->value), "score") == 0
   27735          897 :               && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN)
   27736              :             {
   27737           93 :               c_parser_consume_token (parser);
   27738              : 
   27739           93 :               matching_parens parens2;
   27740           93 :               parens2.require_open (parser);
   27741           93 :               tree score = c_parser_expr_no_commas (parser, NULL).value;
   27742           93 :               parens2.skip_until_found_close (parser);
   27743           93 :               c_parser_require (parser, CPP_COLON, "expected %<:%>");
   27744           93 :               if (!allow_score)
   27745           13 :                 error_at (token->location,
   27746              :                           "%<score%> cannot be specified in traits "
   27747              :                           "in the %qs trait-selector-set",
   27748              :                           omp_tss_map[set]);
   27749           80 :               else if (score != error_mark_node)
   27750              :                 {
   27751           80 :                   mark_exp_read (score);
   27752           80 :                   score = c_fully_fold (score, false, NULL);
   27753          160 :                   if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
   27754          159 :                       || TREE_CODE (score) != INTEGER_CST)
   27755            1 :                     error_at (token->location, "%<score%> argument must "
   27756              :                               "be constant integer expression");
   27757           79 :                   else if (tree_int_cst_sgn (score) < 0)
   27758            1 :                     error_at (token->location, "%<score%> argument must "
   27759              :                               "be non-negative");
   27760              :                   else
   27761              :                     scoreval = score;
   27762              :                 }
   27763           93 :               token = c_parser_peek_token (parser);
   27764              :             }
   27765              : 
   27766          804 :           switch (property_kind)
   27767              :             {
   27768           25 :             case OMP_TRAIT_PROPERTY_ID:
   27769           25 :               if (c_parser_next_token_is (parser, CPP_KEYWORD)
   27770           50 :                   || c_parser_next_token_is (parser, CPP_NAME))
   27771              :                 {
   27772           24 :                   tree prop = c_parser_peek_token (parser)->value;
   27773           24 :                   c_parser_consume_token (parser);
   27774           24 :                   properties = make_trait_property (prop, NULL_TREE,
   27775              :                                                     properties);
   27776              :                 }
   27777              :               else
   27778              :                 {
   27779            1 :                   c_parser_error (parser, "expected identifier");
   27780            1 :                   return error_mark_node;
   27781              :                 }
   27782           24 :               break;
   27783          688 :             case OMP_TRAIT_PROPERTY_NAME_LIST:
   27784          746 :               do
   27785              :                 {
   27786          688 :                   tree prop = OMP_TP_NAMELIST_NODE;
   27787          688 :                   tree value = NULL_TREE;
   27788          688 :                   if (c_parser_next_token_is (parser, CPP_KEYWORD)
   27789         1376 :                       || c_parser_next_token_is (parser, CPP_NAME))
   27790              :                     {
   27791          524 :                       value = c_parser_peek_token (parser)->value;
   27792          524 :                       c_parser_consume_token (parser);
   27793              :                     }
   27794          164 :                   else if (c_parser_next_token_is (parser, CPP_STRING))
   27795          159 :                     value = c_parser_string_literal (parser, false,
   27796              :                                                      false).value;
   27797              :                   else
   27798              :                     {
   27799            5 :                       c_parser_error (parser, "expected identifier or "
   27800              :                                               "string literal");
   27801            5 :                       return error_mark_node;
   27802              :                     }
   27803              : 
   27804          683 :                   properties = make_trait_property (prop, value, properties);
   27805              : 
   27806          683 :                   if (c_parser_next_token_is (parser, CPP_COMMA))
   27807           58 :                     c_parser_consume_token (parser);
   27808              :                   else
   27809              :                     break;
   27810           58 :                 }
   27811              :               while (1);
   27812              :               break;
   27813          126 :             case OMP_TRAIT_PROPERTY_DEV_NUM_EXPR:
   27814          126 :             case OMP_TRAIT_PROPERTY_BOOL_EXPR:
   27815          126 :               {
   27816          126 :                 c_expr texpr = c_parser_expr_no_commas (parser, NULL);
   27817          126 :                 texpr = convert_lvalue_to_rvalue (token->location, texpr,
   27818              :                                                   true, true);
   27819          126 :                 t = texpr.value;
   27820              :               }
   27821          126 :               if (t == error_mark_node)
   27822              :                 return error_mark_node;
   27823          124 :               mark_exp_read (t);
   27824          124 :               if (property_kind == OMP_TRAIT_PROPERTY_BOOL_EXPR)
   27825              :                 {
   27826          101 :                   t = c_objc_common_truthvalue_conversion (token->location,
   27827              :                                                            t,
   27828              :                                                            boolean_type_node);
   27829          101 :                   if (t == error_mark_node)
   27830              :                     return error_mark_node;
   27831              :                 }
   27832           23 :               else if (!INTEGRAL_TYPE_P (TREE_TYPE (t)))
   27833              :                 {
   27834            0 :                   error_at (token->location,
   27835              :                             "property must be integer expression");
   27836            0 :                   return error_mark_node;
   27837              :                 }
   27838          122 :               t = c_fully_fold (t, false, NULL);
   27839          122 :               properties = make_trait_property (NULL_TREE, t, properties);
   27840          122 :               break;
   27841           23 :             case OMP_TRAIT_PROPERTY_CLAUSE_LIST:
   27842           23 :               if (sel == OMP_TRAIT_CONSTRUCT_SIMD)
   27843              :                 {
   27844           23 :                   if (parms == NULL_TREE)
   27845              :                     {
   27846            0 :                       error_at (token->location, "properties for %<simd%> "
   27847              :                                 "selector may not be specified in "
   27848              :                                 "%<metadirective%>");
   27849            0 :                       return error_mark_node;
   27850              :                     }
   27851           23 :                   tree c;
   27852           46 :                   c = c_parser_omp_all_clauses (parser,
   27853           23 :                                                 OMP_DECLARE_SIMD_CLAUSE_MASK,
   27854              :                                                 "simd", true, 2);
   27855           46 :                   c = c_omp_declare_simd_clauses_to_numbers (parms
   27856           23 :                                                              == error_mark_node
   27857              :                                                              ? NULL_TREE : parms,
   27858              :                                                              c);
   27859           23 :                   properties = c;
   27860              :                 }
   27861            0 :               else if (sel == OMP_TRAIT_IMPLEMENTATION_REQUIRES)
   27862              :                 {
   27863              :                   /* FIXME: The "requires" selector was added in OpenMP 5.1.
   27864              :                      Currently only the now-deprecated syntax
   27865              :                      from OpenMP 5.0 is supported.  */
   27866            0 :                   sorry_at (token->location,
   27867              :                             "%<requires%> selector is not supported yet");
   27868            0 :                   return error_mark_node;
   27869              :                 }
   27870              :               else
   27871            0 :                 gcc_unreachable ();
   27872           23 :               break;
   27873            0 :             default:
   27874            0 :               gcc_unreachable ();
   27875              :             }
   27876              : 
   27877          794 :           parens.skip_until_found_close (parser);
   27878          794 :           properties = nreverse (properties);
   27879              :         }
   27880          608 :       else if (property_kind != OMP_TRAIT_PROPERTY_NONE
   27881          608 :                && property_kind != OMP_TRAIT_PROPERTY_CLAUSE_LIST
   27882            8 :                && property_kind != OMP_TRAIT_PROPERTY_EXTENSION)
   27883              :         {
   27884            8 :           c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>");
   27885            8 :           return error_mark_node;
   27886              :         }
   27887              : 
   27888         1394 :       ret = make_trait_selector (sel, scoreval, properties, ret);
   27889              : 
   27890         1394 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   27891          181 :         c_parser_consume_token (parser);
   27892              :       else
   27893              :         break;
   27894              :     }
   27895              :   while (1);
   27896              : 
   27897         1230 :   return nreverse (ret);
   27898              : }
   27899              : 
   27900              : /* OpenMP 5.0:
   27901              : 
   27902              :    trait-set-selector[,trait-set-selector[,...]]
   27903              : 
   27904              :    trait-set-selector:
   27905              :      trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }
   27906              : 
   27907              :    trait-set-selector-name:
   27908              :      constructor
   27909              :      device
   27910              :      implementation
   27911              :      user  */
   27912              : 
   27913              : static tree
   27914          912 : c_parser_omp_context_selector_specification (c_parser *parser, tree parms)
   27915              : {
   27916          912 :   tree ret = NULL_TREE;
   27917         1620 :   do
   27918              :     {
   27919         1266 :       const char *setp = "";
   27920         1266 :       if (c_parser_next_token_is (parser, CPP_NAME))
   27921         1264 :         setp = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   27922         1266 :       enum omp_tss_code set = omp_lookup_tss_code (setp);
   27923              : 
   27924         1266 :       if (set == OMP_TRAIT_SET_INVALID)
   27925              :         {
   27926            6 :           c_parser_error (parser, "expected context selector set name");
   27927           10 :           return error_mark_node;
   27928              :         }
   27929              : 
   27930         1260 :       c_parser_consume_token (parser);
   27931              : 
   27932         1260 :       if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   27933            1 :         return error_mark_node;
   27934              : 
   27935         1259 :       matching_braces braces;
   27936         1259 :       if (!braces.require_open (parser))
   27937            3 :         return error_mark_node;
   27938              : 
   27939         1256 :       tree selectors = c_parser_omp_context_selector (parser, set, parms);
   27940         1256 :       if (selectors == error_mark_node)
   27941              :         {
   27942           26 :           c_parser_skip_to_closing_brace (parser);
   27943           26 :           ret = error_mark_node;
   27944              :         }
   27945         1230 :       else if (ret != error_mark_node)
   27946         1230 :         ret = make_trait_set_selector (set, selectors, ret);
   27947              : 
   27948         1256 :       braces.require_close (parser);
   27949              : 
   27950         1256 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   27951          354 :         c_parser_consume_token (parser);
   27952              :       else
   27953              :         break;
   27954          354 :     }
   27955              :   while (1);
   27956              : 
   27957          902 :   if (ret == error_mark_node)
   27958              :     return ret;
   27959          876 :   return nreverse (ret);
   27960              : }
   27961              : 
   27962              : /* Finalize #pragma omp declare variant after FNDECL has been parsed, and put
   27963              :    that into "omp declare variant base" attribute.  */
   27964              : 
   27965              : static void
   27966          763 : c_finish_omp_declare_variant (c_parser *parser, tree fndecl, tree parms)
   27967              : {
   27968          763 :   matching_parens parens;
   27969          763 :   if (!parens.require_open (parser))
   27970              :     {
   27971            3 :      fail:
   27972           50 :       c_parser_skip_to_pragma_eol (parser, false);
   27973           50 :       return;
   27974              :     }
   27975              : 
   27976          760 :   if (c_parser_next_token_is_not (parser, CPP_NAME)
   27977          760 :       || c_parser_peek_token (parser)->id_kind != C_ID_ID)
   27978              :     {
   27979            3 :       c_parser_error (parser, "expected identifier");
   27980            3 :       goto fail;
   27981              :     }
   27982              : 
   27983          757 :   c_token *token = c_parser_peek_token (parser);
   27984          757 :   tree variant = lookup_name (token->value);
   27985              : 
   27986          757 :   if (variant == NULL_TREE)
   27987              :     {
   27988            3 :       undeclared_variable (token->location, token->value);
   27989            3 :       variant = error_mark_node;
   27990              :     }
   27991          754 :   else if (TREE_CODE (variant) != FUNCTION_DECL)
   27992              :     {
   27993            1 :       error_at (token->location, "variant %qD is not a function",
   27994              :                 variant);
   27995            1 :       variant = error_mark_node;
   27996              :     }
   27997          753 :   else if (fndecl_built_in_p (variant)
   27998          753 :            && (strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
   27999              :                         "__builtin_", strlen ("__builtin_")) == 0
   28000            0 :                || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
   28001              :                            "__sync_", strlen ("__sync_")) == 0
   28002            0 :                || strncmp (IDENTIFIER_POINTER (DECL_NAME (variant)),
   28003              :                            "__atomic_", strlen ("__atomic_")) == 0))
   28004              :     {
   28005            1 :       error_at (token->location, "variant %qD is a built-in",
   28006              :                 variant);
   28007            1 :       variant = error_mark_node;
   28008              :     }
   28009          752 :   else if (variant == fndecl)
   28010              :     {
   28011            2 :       error_at (token->location, "variant %qD is the same as base function",
   28012              :                 variant);
   28013            2 :       variant = error_mark_node;
   28014              :     }
   28015              : 
   28016          757 :   c_parser_consume_token (parser);
   28017              : 
   28018          757 :   parens.require_close (parser);
   28019              : 
   28020          757 :   tree append_args_tree = NULL_TREE;
   28021          757 :   tree append_args_last;
   28022          757 :   vec<tree> adjust_args_list = vNULL;
   28023          757 :   bool has_match = false, has_adjust_args = false;
   28024          757 :   location_t adjust_args_loc = UNKNOWN_LOCATION;
   28025          757 :   location_t append_args_loc = UNKNOWN_LOCATION;
   28026          757 :   location_t match_loc = UNKNOWN_LOCATION;
   28027          757 :   tree need_device_ptr_list = NULL_TREE;
   28028          757 :   tree ctx = error_mark_node;
   28029              : 
   28030          856 :   do
   28031              :     {
   28032          856 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   28033          856 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   28034            9 :         c_parser_consume_token (parser);
   28035              : 
   28036          856 :       const char *clause = "";
   28037          856 :       location_t loc = c_parser_peek_token (parser)->location;
   28038          856 :       if (c_parser_next_token_is (parser, CPP_NAME))
   28039          855 :         clause = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   28040              : 
   28041          856 :       enum clause
   28042              :       {
   28043              :         match,
   28044              :         adjust_args,
   28045              :         append_args
   28046              :       } ccode;
   28047              : 
   28048          856 :       if (strcmp (clause, "match") == 0)
   28049              :         {
   28050              :           ccode = match;
   28051              :           match_loc = loc;
   28052              :         }
   28053          102 :       else if (strcmp (clause, "adjust_args") == 0)
   28054              :         {
   28055              :           ccode = adjust_args;
   28056              :           adjust_args_loc = loc;
   28057              :         }
   28058           50 :       else if (strcmp (clause, "append_args") == 0)
   28059              :         {
   28060              :           ccode = append_args;
   28061              :           append_args_loc = loc;
   28062              :         }
   28063              :       else
   28064              :         {
   28065            2 :           c_parser_error (parser, "expected %<match%>, %<adjust_args%> or "
   28066              :                                   "%<append_args%> clause");
   28067            2 :           goto fail;
   28068              :         }
   28069              : 
   28070          854 :       c_parser_consume_token (parser);
   28071              : 
   28072          854 :       if (!parens.require_open (parser))
   28073            1 :         goto fail;
   28074              : 
   28075          853 :       if (parms == NULL_TREE)
   28076          594 :         parms = error_mark_node;
   28077              : 
   28078          853 :       if (ccode == match)
   28079              :         {
   28080          753 :           if (has_match)
   28081            1 :             error_at (match_loc, "too many %<match%> clauses");
   28082          753 :           has_match = true;
   28083          753 :           ctx  = c_parser_omp_context_selector_specification (parser, parms);
   28084          753 :           if (ctx == error_mark_node)
   28085           32 :             goto fail;
   28086          721 :           ctx = omp_check_context_selector (match_loc, ctx,
   28087              :                                             OMP_CTX_DECLARE_VARIANT);
   28088              : 
   28089              :           /* The OpenMP spec says the merging rules for enclosing
   28090              :              "begin declare variant" contexts apply to "declare variant
   28091              :              directives" -- the term it uses to refer to both directive
   28092              :              forms.  */
   28093          721 :           if (ctx != error_mark_node
   28094          721 :               && !vec_safe_is_empty (current_omp_declare_variant_attribute))
   28095              :             {
   28096            2 :               c_omp_declare_variant_attr a
   28097            2 :                 = current_omp_declare_variant_attribute->last ();
   28098            2 :               tree outer_ctx = a.selector;
   28099            2 :               ctx = omp_merge_context_selectors (match_loc, outer_ctx, ctx,
   28100              :                                                  OMP_CTX_DECLARE_VARIANT);
   28101              :             }
   28102              :         }
   28103          100 :       else if (ccode == adjust_args)
   28104              :         {
   28105           52 :           has_adjust_args = true;
   28106           52 :           if (c_parser_next_token_is (parser, CPP_NAME)
   28107           52 :               && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   28108              :             {
   28109           50 :               const char *p
   28110           50 :                 = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   28111           50 :               if (strcmp (p, "need_device_ptr") == 0
   28112           15 :                   || strcmp (p, "nothing") == 0)
   28113              :                 {
   28114           48 :                   c_parser_consume_token (parser); // need_device_ptr
   28115           48 :                   c_parser_consume_token (parser); // :
   28116              : 
   28117           48 :                   loc = c_parser_peek_token (parser)->location;
   28118           48 :                   tree list
   28119           48 :                     = c_parser_omp_variable_list (parser, loc, OMP_CLAUSE_ERROR,
   28120              :                                                   NULL_TREE);
   28121              : 
   28122           48 :                   tree arg;
   28123           48 :                   if (variant != error_mark_node)
   28124          103 :                     for (tree c = list; c != NULL_TREE; c = TREE_CHAIN (c))
   28125              :                       {
   28126           61 :                         tree decl = TREE_PURPOSE (c);
   28127           61 :                         location_t arg_loc = EXPR_LOCATION (TREE_VALUE (c));
   28128           61 :                         int idx;
   28129          111 :                         for (arg = parms, idx = 0; arg != NULL;
   28130           50 :                              arg = TREE_CHAIN (arg), idx++)
   28131          110 :                           if (arg == decl)
   28132              :                             break;
   28133           61 :                         if (arg == NULL_TREE)
   28134              :                           {
   28135            1 :                             error_at (arg_loc,
   28136              :                                       "%qD is not a function argument",
   28137              :                                       decl);
   28138            5 :                             goto fail;
   28139              :                           }
   28140           60 :                         if (adjust_args_list.contains (arg))
   28141              :                           {
   28142            3 :                             error_at (arg_loc,
   28143              :                                       "%qD is specified more than once",
   28144              :                                       decl);
   28145            3 :                             goto fail;
   28146              :                           }
   28147           57 :                         if (strcmp (p, "need_device_ptr") == 0
   28148           57 :                             && TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
   28149              :                           {
   28150            1 :                             error_at (loc, "%qD is not of pointer type", decl);
   28151            1 :                             goto fail;
   28152              :                           }
   28153           56 :                         adjust_args_list.safe_push (arg);
   28154           56 :                         if (strcmp (p, "need_device_ptr") == 0)
   28155              :                           {
   28156           46 :                             need_device_ptr_list = chainon (
   28157              :                               need_device_ptr_list,
   28158              :                               build_tree_list (
   28159              :                                 NULL_TREE,
   28160              :                                 build_int_cst (
   28161              :                                   integer_type_node,
   28162           46 :                                   idx))); // Store 0-based argument index,
   28163              :                                           // as in gimplify_call_expr
   28164              :                           }
   28165              :                       }
   28166           43 :                 }
   28167              :               else
   28168              :                 {
   28169            2 :                   error_at (c_parser_peek_token (parser)->location,
   28170              :                             "expected %<nothing%> or %<need_device_ptr%>");
   28171            2 :                   if (strcmp (p, "need_device_addr") == 0)
   28172            1 :                     inform (c_parser_peek_token (parser)->location,
   28173              :                             "%<need_device_addr%> is not valid for C");
   28174            2 :                   goto fail;
   28175              :                 }
   28176              :             }
   28177              :           else
   28178              :             {
   28179            2 :               error_at (c_parser_peek_token (parser)->location,
   28180              :                         "expected %<nothing%> or %<need_device_ptr%> "
   28181              :                         "followed by %<:%>");
   28182            2 :               goto fail;
   28183              :             }
   28184              :         }
   28185           48 :       else if (ccode == append_args)
   28186              :         {
   28187           48 :           if (append_args_tree)
   28188              :             {
   28189            1 :               error_at (append_args_loc, "too many %qs clauses", "append_args");
   28190            1 :               append_args_tree = NULL_TREE;
   28191              :             }
   28192           86 :           do
   28193              :             {
   28194           67 :               location_t loc = c_parser_peek_token (parser)->location;
   28195           67 :               if (!c_parser_next_token_is (parser, CPP_NAME)
   28196           67 :                   || strcmp ("interop",
   28197           67 :                              IDENTIFIER_POINTER (
   28198              :                                c_parser_peek_token (parser)->value)))
   28199              :                 {
   28200            0 :                   error_at (loc, "expected %<interop%>");
   28201            0 :                   goto fail;
   28202              :                 }
   28203           67 :               c_parser_consume_token (parser);
   28204              : 
   28205           67 :               if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   28206            0 :                 goto fail;
   28207           67 :               bool target = false;
   28208           67 :               bool targetsync = false;
   28209           67 :               tree prefer_type_tree = NULL_TREE;
   28210           67 :               if (!c_parser_omp_clause_init_modifiers (parser, &target,
   28211              :                                                        &targetsync,
   28212              :                                                        &prefer_type_tree)
   28213           67 :                   || !c_parser_require (parser, CPP_CLOSE_PAREN,
   28214              :                                         "expected %<)%> or %<,%>"))
   28215            0 :                 goto fail;
   28216           67 :               if (!target && !targetsync)
   28217            3 :                 error_at (loc,
   28218              :                           "missing required %<target%> and/or "
   28219              :                           "%<targetsync%> modifier");
   28220           67 :               tree t = build_tree_list (target ? boolean_true_node
   28221              :                                                : boolean_false_node,
   28222              :                                         targetsync ? boolean_true_node
   28223              :                                                    : boolean_false_node);
   28224           67 :               t = build1_loc (loc, NOP_EXPR, void_type_node, t);
   28225           67 :               t = build_tree_list (t, prefer_type_tree);
   28226           67 :               if (append_args_tree)
   28227              :                 {
   28228           19 :                   TREE_CHAIN (append_args_last) = t;
   28229           19 :                   append_args_last = t;
   28230              :                 }
   28231              :               else
   28232              :                 append_args_tree = append_args_last = t;
   28233           67 :               if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
   28234              :                 break;
   28235           19 :               if (!c_parser_require (parser, CPP_COMMA, "expected %<)%> or %<,%>"))
   28236            0 :                 goto fail;
   28237           19 :             }
   28238              :           while (true);
   28239              :         }
   28240              : 
   28241          812 :       parens.require_close (parser);
   28242          812 :   } while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL));
   28243          713 :   if (variant != error_mark_node && !has_match)
   28244              :     {
   28245            1 :       c_parser_error (parser, "expected %<match%> clause");
   28246            1 :       variant = error_mark_node;
   28247              :     }
   28248          713 :   c_parser_skip_to_pragma_eol (parser);
   28249              : 
   28250              :   /* At this point, we have completed parsing of the pragma, now it's
   28251              :      on to error checking.  */
   28252          713 :   if (variant == error_mark_node || ctx == error_mark_node)
   28253              :     /* Previously diagnosed error.  */
   28254              :     return;
   28255              : 
   28256          683 :   if ((has_adjust_args || append_args_tree)
   28257          683 :       && !omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
   28258              :                                     OMP_TRAIT_CONSTRUCT_DISPATCH))
   28259              :     {
   28260            1 :       error_at (has_adjust_args ? adjust_args_loc : append_args_loc,
   28261              :                 "an %qs clause can only be specified if the "
   28262              :                 "%<dispatch%> selector of the %<construct%> selector "
   28263              :                 "set appears in the %<match%> clause",
   28264              :                 has_adjust_args ? "adjust_args" : "append_args");
   28265            1 :       return;
   28266              :     }
   28267              : 
   28268          682 :   if (!omp_get_context_selector (ctx, OMP_TRAIT_SET_CONSTRUCT,
   28269              :                                  OMP_TRAIT_CONSTRUCT_SIMD))
   28270              :     /* Check that the base and variant have compatible types.  */
   28271              :     {
   28272          659 :       tree base_type = TREE_TYPE (fndecl);
   28273          659 :       tree variant_type = TREE_TYPE (variant);
   28274          659 :       bool unprototyped_variant
   28275          659 :         = (TYPE_ARG_TYPES (variant_type) == NULL_TREE
   28276          659 :            && !TYPE_NO_NAMED_ARGS_STDARG_P (variant_type));
   28277              : 
   28278          659 :       if (append_args_tree
   28279           47 :           && TYPE_ARG_TYPES (base_type) == NULL_TREE
   28280          667 :           && !TYPE_NO_NAMED_ARGS_STDARG_P (base_type))
   28281              :         {
   28282              :           /* The base function is a pre-C23 unprototyped function.  Without
   28283              :              a prototype, we don't know the offset where the append_args go.
   28284              :              That offset needs to be stored with the append_args in the
   28285              :              variant function attributes, so we cannot presently handle
   28286              :              this case.  */
   28287            6 :           sorry_at (append_args_loc,
   28288              :                     "%<append_args%> with unprototyped base function "
   28289              :                     "is not supported yet");
   28290            6 :           inform (DECL_SOURCE_LOCATION (fndecl),
   28291              :                   "base function %qD declared here", fndecl);
   28292            6 :           return;
   28293              :         }
   28294          653 :       else if (append_args_tree)
   28295              :         {
   28296              :           /* Find nbase_args, the number of fixed arguments in the base
   28297              :              function.  */
   28298           41 :           int nappend_args = 0;
   28299           41 :           int nbase_args = 0;
   28300           41 :           for (tree t = TYPE_ARG_TYPES (base_type);
   28301          183 :                t && TREE_VALUE (t) != void_type_node; t = TREE_CHAIN (t))
   28302           55 :             nbase_args++;
   28303          101 :           for (tree t = append_args_tree; t; t = TREE_CHAIN (t))
   28304           60 :             nappend_args++;
   28305              : 
   28306              :           /* Store as purpose = arg number after which to append
   28307              :              and value = list of interop items.  */
   28308           41 :           append_args_tree = build_tree_list (build_int_cst (integer_type_node,
   28309           41 :                                                              nbase_args),
   28310              :                                               append_args_tree);
   28311              : 
   28312              :           /* Give a specific diagnostic if the append_args parameters
   28313              :              of the variant are of the wrong type, or missing.  The
   28314              :              compatible types test below could fail to detect this if
   28315              :              the variant is a varargs function.  */
   28316           41 :           if (!unprototyped_variant)
   28317              :             {
   28318           39 :               tree args = TYPE_ARG_TYPES (variant_type);
   28319           90 :               for (int i = 0; args && i < nbase_args;
   28320           51 :                    i++, args = TREE_CHAIN (args))
   28321              :                 ;
   28322           89 :               for (int i = 0; i < nappend_args; i++, args = TREE_CHAIN (args))
   28323          109 :                 if (!args || !c_omp_interop_t_p (TREE_VALUE (args)))
   28324              :                   {
   28325            5 :                     error_at (DECL_SOURCE_LOCATION (variant),
   28326              :                               "argument %d of %qD must be of "
   28327              :                               "%<omp_interop_t%>",
   28328            5 :                               nbase_args + i + 1, variant);
   28329            5 :                     inform (append_args_loc,
   28330              :                             "%<append_args%> specified here");
   28331          100 :                     return;
   28332              :                   }
   28333              :             }
   28334              : 
   28335              :           /* Perform the "implementation defined transformation" on the type
   28336              :              of the base function to add the append_args before checking it
   28337              :              for compatibility with the function variant's type.  */
   28338           36 :           tree args = TYPE_ARG_TYPES (base_type);
   28339           36 :           tree newargs = NULL_TREE;
   28340           36 :           tree lastarg = NULL_TREE;
   28341           89 :           for (int j = 0; j < nbase_args; j++, args = TREE_CHAIN (args))
   28342              :             {
   28343           53 :               tree t = tree_cons (TREE_PURPOSE (args),
   28344           53 :                                   TREE_VALUE (args), NULL_TREE);
   28345           53 :               if (lastarg)
   28346           31 :                 TREE_CHAIN (lastarg) = t;
   28347              :               else
   28348              :                 newargs = t;
   28349           53 :               lastarg = t;
   28350              :             }
   28351           36 :           tree type = lookup_name (get_identifier ("omp_interop_t"));
   28352           36 :           type = type ? TREE_TYPE (type) : pointer_sized_int_node;
   28353           87 :           for (int j = 0; j < nappend_args; j++)
   28354              :             {
   28355           51 :               tree t = tree_cons (NULL_TREE, type, NULL_TREE);
   28356           51 :               if (lastarg)
   28357           37 :                 TREE_CHAIN (lastarg) = t;
   28358              :               else
   28359              :                 newargs = t;
   28360           51 :               lastarg = t;
   28361              :             }
   28362           36 :           TREE_CHAIN (lastarg) = args;
   28363              : 
   28364              :           /* Temporarily stuff newargs into the original base_type.  */
   28365           36 :           tree saveargs = TYPE_ARG_TYPES (base_type);
   28366           36 :           TYPE_ARG_TYPES (base_type) = newargs;
   28367           36 :           bool fail = !comptypes (base_type, variant_type);
   28368           36 :           TYPE_ARG_TYPES (base_type) = saveargs;
   28369              : 
   28370           36 :           if (fail)
   28371              :             {
   28372            2 :               error_at (token->location,
   28373              :                         "variant %qD and base %qD have incompatible types "
   28374              :                         "after %<append_args%> adjustment",
   28375              :                         variant, fndecl);
   28376            2 :               inform (DECL_SOURCE_LOCATION (variant),
   28377              :                       "%<declare variant%> candidate %qD declared here",
   28378              :                       variant);
   28379            2 :               return;
   28380              :             }
   28381           34 :           else if (unprototyped_variant)
   28382              :             /* If we've got an unprototyped variant, copy the transformed
   28383              :                base arg types to the variant.  This is needed later by
   28384              :                modify_call_for_omp_dispatch.  */
   28385            2 :             TYPE_ARG_TYPES (variant_type) = newargs;
   28386              :         }
   28387              :       else  /* No append_args present.  */
   28388              :         {
   28389          612 :           if (!comptypes (base_type, variant_type))
   28390              :             {
   28391            1 :               error_at (token->location,
   28392              :                         "variant %qD and base %qD have incompatible types",
   28393              :                         variant, fndecl);
   28394            1 :               inform (DECL_SOURCE_LOCATION (variant),
   28395              :                       "%<declare variant%> candidate %qD declared here",
   28396              :                       variant);
   28397            1 :               return;
   28398              :             }
   28399          611 :           else if (TYPE_ARG_TYPES (variant_type) == NULL_TREE
   28400            3 :                    && !TYPE_NO_NAMED_ARGS_STDARG_P (variant_type)
   28401          613 :                    && TYPE_ARG_TYPES (base_type) != NULL_TREE)
   28402              :             /* If we've got an unprototyped variant but the base has
   28403              :                a prototype, copy the base arg types to the variant.  */
   28404            1 :             TYPE_ARG_TYPES (variant_type) = TYPE_ARG_TYPES (base_type);
   28405              :         }
   28406              :     }
   28407              : 
   28408              :   /* If we made it here, store the parsed information.  */
   28409          668 :   C_DECL_USED (variant) = 1;
   28410          668 :   tree construct = omp_get_context_selector_list (ctx,
   28411              :                                                   OMP_TRAIT_SET_CONSTRUCT);
   28412          668 :   omp_mark_declare_variant (match_loc, variant, construct);
   28413          668 :   if (omp_context_selector_matches (ctx, NULL_TREE, false))
   28414              :     {
   28415          245 :       tree attr = tree_cons (get_identifier ("omp declare variant base"),
   28416              :                              build_tree_list (variant, ctx),
   28417          245 :                              DECL_ATTRIBUTES (fndecl));
   28418          245 :       DECL_ATTRIBUTES (fndecl) = attr;
   28419              :     }
   28420              : 
   28421          668 :   if (need_device_ptr_list || append_args_tree)
   28422              :     {
   28423           49 :       tree variant_decl = tree_strip_nop_conversions (variant);
   28424           49 :       tree t = build_tree_list (need_device_ptr_list,
   28425              :                                 NULL_TREE /* need_device_addr */);
   28426           49 :       TREE_CHAIN (t) = append_args_tree;
   28427           49 :       DECL_ATTRIBUTES (variant_decl)
   28428           98 :         = tree_cons (get_identifier ("omp declare variant variant args"), t,
   28429           49 :                      DECL_ATTRIBUTES (variant_decl));
   28430              :     }
   28431              : }
   28432              : 
   28433              : /* Finalize #pragma omp declare simd or #pragma omp declare variant
   28434              :    clauses after FNDECL has been parsed, and put that into "omp declare simd"
   28435              :    or "omp declare variant base" attribute.  */
   28436              : 
   28437              : static void
   28438          853 : c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
   28439              :                            vec<c_token> *pclauses)
   28440              : {
   28441          853 :   vec<c_token> &clauses = *pclauses;
   28442              : 
   28443              :   /* Normally first token is CPP_NAME "simd" or "variant".  CPP_EOF there
   28444              :      indicates error has been reported and CPP_PRAGMA that
   28445              :      c_finish_omp_declare_simd has already processed the tokens.  */
   28446         1706 :   if (clauses.exists () && clauses[0].type == CPP_EOF)
   28447              :     return;
   28448          849 :   const char *kind = "simd";
   28449          849 :   if (clauses.exists ()
   28450         1698 :       && (clauses[0].type == CPP_NAME || clauses[0].type == CPP_PRAGMA))
   28451          849 :     kind = IDENTIFIER_POINTER (clauses[0].value);
   28452          849 :   gcc_assert (strcmp (kind, "simd") == 0 || strcmp (kind, "variant") == 0);
   28453          849 :   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
   28454              :     {
   28455           15 :       error ("%<#pragma omp declare %s%> not immediately followed by "
   28456              :              "a function declaration or definition", kind);
   28457           15 :       clauses[0].type = CPP_EOF;
   28458           15 :       return;
   28459              :     }
   28460         1668 :   if (clauses.exists () && clauses[0].type != CPP_NAME)
   28461              :     {
   28462            2 :       error_at (DECL_SOURCE_LOCATION (fndecl),
   28463              :                 "%<#pragma omp declare %s%> not immediately followed by "
   28464              :                 "a single function declaration or definition", kind);
   28465            2 :       clauses[0].type = CPP_EOF;
   28466            2 :       return;
   28467              :     }
   28468          832 :   if (DECL_FUNCTION_VERSIONED (fndecl))
   28469              :     {
   28470            0 :       error_at (DECL_SOURCE_LOCATION (fndecl),
   28471              :                 "%<#pragma omp declare %s%> cannot be used with function "
   28472              :                 "multi-versioning", kind);
   28473            0 :       return;
   28474              :     }
   28475              : 
   28476          832 :   if (parms == NULL_TREE)
   28477          587 :     parms = DECL_ARGUMENTS (fndecl);
   28478              : 
   28479          832 :   unsigned int tokens_avail = parser->tokens_avail;
   28480          832 :   gcc_assert (parser->tokens == &parser->tokens_buf[0]);
   28481              : 
   28482          832 :   parser->tokens = clauses.address ();
   28483          832 :   parser->tokens_avail = clauses.length ();
   28484              : 
   28485              :   /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end.  */
   28486         1971 :   while (parser->tokens_avail > 3)
   28487              :     {
   28488         1139 :       c_token *token = c_parser_peek_token (parser);
   28489         1139 :       gcc_assert (token->type == CPP_NAME);
   28490         1139 :       kind = IDENTIFIER_POINTER (token->value);
   28491         1139 :       c_parser_consume_token (parser);
   28492         1139 :       parser->in_pragma = true;
   28493              : 
   28494         1139 :       if (strcmp (kind, "simd") == 0)
   28495              :         {
   28496          376 :           tree c;
   28497          376 :           c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
   28498              :                                         "#pragma omp declare simd");
   28499          376 :           c = c_omp_declare_simd_clauses_to_numbers (parms, c);
   28500          376 :           if (c != NULL_TREE)
   28501          267 :             c = tree_cons (NULL_TREE, c, NULL_TREE);
   28502          376 :           c = build_tree_list (get_identifier ("omp declare simd"), c);
   28503          376 :           TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
   28504          376 :           DECL_ATTRIBUTES (fndecl) = c;
   28505              :         }
   28506              :       else
   28507              :         {
   28508          763 :           gcc_assert (strcmp (kind, "variant") == 0);
   28509          763 :           c_finish_omp_declare_variant (parser, fndecl, parms);
   28510              :         }
   28511              :     }
   28512              : 
   28513          832 :   parser->tokens = &parser->tokens_buf[0];
   28514          832 :   parser->tokens_avail = tokens_avail;
   28515          832 :   if (clauses.exists ())
   28516          832 :     clauses[0].type = CPP_PRAGMA;
   28517              : }
   28518              : 
   28519              : /* This is consistent with the C++ front end.  */
   28520              : 
   28521              : #if !defined (NO_DOT_IN_LABEL)
   28522              : #define JOIN_STR "."
   28523              : #elif !defined (NO_DOLLAR_IN_LABEL)
   28524              : #define JOIN_STR "$"
   28525              : #else
   28526              : #define JOIN_STR "_"
   28527              : #endif
   28528              : 
   28529              : /* Helper function for OpenMP "begin declare variant" directives.
   28530              :    Function definitions inside the construct need to have their names
   28531              :    mangled according to the context selector CTX.  The DECLARATOR is
   28532              :    modified in place to point to a new identifier; the original name of
   28533              :    the function is returned.  */
   28534              : static tree
   28535           24 : omp_start_variant_function (c_declarator *declarator, tree ctx)
   28536              : {
   28537           24 :   c_declarator *id = declarator;
   28538           48 :   while (id->kind != cdk_id)
   28539              :     {
   28540           24 :       id = id->declarator;
   28541           24 :       gcc_assert (id);
   28542              :     }
   28543           24 :   tree name = id->u.id.id;
   28544           24 :   id->u.id.id = omp_mangle_variant_name (name, ctx, JOIN_STR);
   28545           24 :   return name;
   28546              : }
   28547              : 
   28548              : /* Helper function for OpenMP "begin declare variant" directives.  Now
   28549              :    that we have a DECL for the variant function, and BASE_NAME for the
   28550              :    base function, add an "omp declare variant base" attribute pointing
   28551              :    at CTX to the base decl, and an "omp declare variant variant"
   28552              :    attribute to the variant DECL.  */
   28553              : static void
   28554           24 : omp_finish_variant_function (tree decl, tree base_name, tree ctx)
   28555              : {
   28556              :   /* First look up BASE_NAME and ensure it matches DECL.  */
   28557           24 :   tree base_decl = lookup_name (base_name);
   28558           24 :   if (base_decl == error_mark_node)
   28559              :     base_decl = NULL_TREE;
   28560           24 :   if (!base_decl)
   28561              :     {
   28562            1 :       error_at (DECL_SOURCE_LOCATION (decl),
   28563              :                 "no declaration of base function %qs",
   28564            1 :                 IDENTIFIER_POINTER (base_name));
   28565            1 :       return;
   28566              :     }
   28567              : 
   28568           23 :   if (!comptypes (TREE_TYPE (decl), TREE_TYPE (base_decl)))
   28569              :     {
   28570            2 :       error_at (DECL_SOURCE_LOCATION (decl),
   28571              :                 "variant function definition does not match "
   28572              :                 "declaration of %qE", base_decl);
   28573            2 :       inform (DECL_SOURCE_LOCATION (base_decl),
   28574              :               "%qE declared here", base_decl);
   28575            2 :       return;
   28576              :     }
   28577              : 
   28578              :   /* Now set the attributes on the base and variant decls for the middle
   28579              :      end.  */
   28580           21 :   omp_check_for_duplicate_variant (DECL_SOURCE_LOCATION (decl),
   28581              :                                    base_decl, ctx);
   28582           21 :   tree construct
   28583           21 :     = omp_get_context_selector_list (ctx, OMP_TRAIT_SET_CONSTRUCT);
   28584           21 :   omp_mark_declare_variant (DECL_SOURCE_LOCATION (decl), decl, construct);
   28585           21 :   tree attrs = DECL_ATTRIBUTES (base_decl);
   28586           21 :   tree match_loc_node
   28587           21 :     = maybe_wrap_with_location (integer_zero_node,
   28588           21 :                                 DECL_SOURCE_LOCATION (base_decl));
   28589           21 :   tree loc_node = tree_cons (match_loc_node, integer_zero_node,
   28590              :                              build_tree_list (match_loc_node,
   28591              :                                               integer_zero_node));
   28592           21 :   attrs = tree_cons (get_identifier ("omp declare variant base"),
   28593              :                      tree_cons (decl, ctx, loc_node), attrs);
   28594           21 :   DECL_ATTRIBUTES (base_decl) = attrs;
   28595              : 
   28596              :   /* Variant functions are essentially anonymous and cannot be referenced
   28597              :      outside the compilation unit.  */
   28598           21 :   TREE_PUBLIC (decl) = 0;
   28599           21 :   DECL_COMDAT (decl) = 0;
   28600              : }
   28601              : 
   28602              : 
   28603              : /* D should be C_TOKEN_VEC from omp::decl attribute.  If it contains
   28604              :    a threadprivate, groupprivate, allocate or declare target directive,
   28605              :    return true and parse it for DECL.  */
   28606              : 
   28607              : bool
   28608           43 : c_maybe_parse_omp_decl (tree decl, tree d)
   28609              : {
   28610           43 :   gcc_assert (TREE_CODE (d) == C_TOKEN_VEC);
   28611           43 :   vec<c_token, va_gc> *toks = C_TOKEN_VEC_TOKENS (d);
   28612           43 :   c_token *first = toks->address ();
   28613           43 :   c_token *last = first + toks->length ();
   28614           43 :   const char *directive[3] = {};
   28615          119 :   for (int j = 0; j < 3; j++)
   28616              :     {
   28617          107 :       tree id = NULL_TREE;
   28618          107 :       if (first + j == last)
   28619              :         break;
   28620           86 :       if (first[j].type == CPP_NAME)
   28621           76 :         id = first[j].value;
   28622           10 :       else if (first[j].type == CPP_KEYWORD)
   28623            0 :         id = ridpointers[(int) first[j].keyword];
   28624              :       else
   28625              :         break;
   28626           76 :       directive[j] = IDENTIFIER_POINTER (id);
   28627              :     }
   28628           43 :   const c_omp_directive *dir = NULL;
   28629           43 :   if (directive[0])
   28630           43 :     dir = c_omp_categorize_directive (directive[0], directive[1],
   28631              :                                       directive[2]);
   28632           43 :   if (dir == NULL)
   28633              :     {
   28634            0 :       error_at (first->location,
   28635              :                 "unknown OpenMP directive name in "
   28636              :                 "%qs attribute argument", "omp::decl");
   28637            0 :       return false;
   28638              :     }
   28639           43 :   if (dir->id != PRAGMA_OMP_THREADPRIVATE
   28640           28 :       && dir->id != PRAGMA_OMP_GROUPPRIVATE
   28641           23 :       && dir->id != PRAGMA_OMP_ALLOCATE
   28642           21 :       && (dir->id != PRAGMA_OMP_DECLARE
   28643           21 :           || strcmp (directive[1], "target") != 0))
   28644              :     return false;
   28645              : 
   28646           43 :   if (!flag_openmp && !dir->simd)
   28647              :     return true;
   28648              : 
   28649           43 :   c_parser *parser = the_parser;
   28650           43 :   unsigned int tokens_avail = parser->tokens_avail;
   28651           43 :   gcc_assert (parser->tokens == &parser->tokens_buf[0]);
   28652           43 :   toks = NULL;
   28653           43 :   vec_safe_reserve (toks, last - first + 2, true);
   28654           43 :   c_token tok = {};
   28655           43 :   tok.type = CPP_PRAGMA;
   28656           43 :   tok.keyword = RID_MAX;
   28657           43 :   tok.pragma_kind = pragma_kind (dir->id);
   28658           43 :   tok.location = first->location;
   28659           43 :   toks->quick_push (tok);
   28660          201 :   while (++first < last)
   28661          115 :     toks->quick_push (*first);
   28662           43 :   tok = {};
   28663           43 :   tok.type = CPP_PRAGMA_EOL;
   28664           43 :   tok.keyword = RID_MAX;
   28665           43 :   tok.location = last[-1].location;
   28666           43 :   toks->quick_push (tok);
   28667           43 :   tok = {};
   28668           43 :   tok.type = CPP_EOF;
   28669           43 :   tok.keyword = RID_MAX;
   28670           43 :   tok.location = last[-1].location;
   28671           43 :   toks->quick_push (tok);
   28672           43 :   parser->in_omp_decl_attribute = decl;
   28673           43 :   gcc_assert (!parser->in_omp_attribute_pragma);
   28674           43 :   parser->in_omp_attribute_pragma = ggc_alloc<omp_attribute_pragma_state> ();
   28675           43 :   parser->in_omp_attribute_pragma->token_vec = toks;
   28676           43 :   parser->in_omp_attribute_pragma->save_tokens = parser->tokens;
   28677           43 :   parser->in_omp_attribute_pragma->save_tokens_avail = tokens_avail;
   28678           43 :   parser->tokens = toks->address ();
   28679           43 :   parser->tokens_avail = toks->length ();
   28680           43 :   c_parser_pragma (parser, pragma_external, NULL, NULL_TREE);
   28681           43 :   parser->in_omp_decl_attribute = NULL_TREE;
   28682           43 :   return true;
   28683              : }
   28684              : 
   28685              : /* OpenMP 4.0:
   28686              :    # pragma omp declare target new-line
   28687              :    declarations and definitions
   28688              :    # pragma omp end declare target new-line
   28689              : 
   28690              :    OpenMP 4.5:
   28691              :    # pragma omp declare target ( extended-list ) new-line
   28692              : 
   28693              :    # pragma omp declare target declare-target-clauses[seq] new-line  */
   28694              : 
   28695              : #define OMP_DECLARE_TARGET_CLAUSE_MASK                          \
   28696              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)             \
   28697              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER)  \
   28698              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)           \
   28699              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)    \
   28700              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
   28701              : 
   28702              : static void
   28703          270 : c_parser_omp_declare_target (c_parser *parser)
   28704              : {
   28705          270 :   tree clauses = NULL_TREE;
   28706          270 :   int device_type = 0;
   28707          270 :   bool indirect = false;
   28708          270 :   bool only_device_type_or_indirect = true;
   28709          270 :   if (flag_openmp)
   28710          270 :     omp_requires_mask
   28711          270 :       = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);
   28712          270 :   if (c_parser_next_token_is (parser, CPP_NAME)
   28713          396 :       || (c_parser_next_token_is (parser, CPP_COMMA)
   28714            5 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME))
   28715          148 :     clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
   28716              :                                         "#pragma omp declare target");
   28717          122 :   else if (parser->in_omp_decl_attribute
   28718          238 :            || c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   28719              :     {
   28720           20 :       clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ENTER,
   28721              :                                               clauses);
   28722           20 :       clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
   28723           20 :       c_parser_skip_to_pragma_eol (parser);
   28724              :     }
   28725              :   else
   28726              :     {
   28727          102 :       warning_at (c_parser_peek_token (parser)->location,
   28728          102 :                   OPT_Wdeprecated_openmp,
   28729              :                   "use of %<omp declare target%> as a synonym for "
   28730              :                   "%<omp begin declare target%> has been deprecated since "
   28731              :                   "OpenMP 5.2");
   28732          102 :       bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   28733          102 :       c_parser_skip_to_pragma_eol (parser);
   28734          102 :       c_omp_declare_target_attr attr = { attr_syntax, -1, 0 };
   28735          102 :       vec_safe_push (current_omp_declare_target_attribute, attr);
   28736          102 :       return;
   28737              :     }
   28738          420 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   28739              :     {
   28740          252 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
   28741           27 :         device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   28742          252 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
   28743           16 :         indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
   28744              :     }
   28745          420 :   for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   28746              :     {
   28747          252 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE
   28748          252 :           || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
   28749          252 :         continue;
   28750          209 :       tree t = OMP_CLAUSE_DECL (c), id;
   28751          209 :       tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
   28752          209 :       tree at2 = lookup_attribute ("omp declare target link",
   28753          209 :                                    DECL_ATTRIBUTES (t));
   28754          209 :       only_device_type_or_indirect = false;
   28755          209 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
   28756              :         {
   28757           30 :           id = get_identifier ("omp declare target link");
   28758           30 :           std::swap (at1, at2);
   28759              :         }
   28760              :       else
   28761          179 :         id = get_identifier ("omp declare target");
   28762          209 :       if (at2)
   28763              :         {
   28764            6 :           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
   28765            3 :             error_at (OMP_CLAUSE_LOCATION (c),
   28766              :                       "%qD specified both in declare target %<link%> and %qs"
   28767            3 :                       " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
   28768              :           else
   28769            3 :             error_at (OMP_CLAUSE_LOCATION (c),
   28770              :                       "%qD specified both in declare target %<link%> and "
   28771              :                       "%<to%> or %<enter%> clauses", t);
   28772            6 :           continue;
   28773              :         }
   28774          203 :       if (!at1)
   28775              :         {
   28776          174 :           DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   28777          174 :           if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
   28778            1 :             continue;
   28779              : 
   28780          173 :           symtab_node *node = symtab_node::get (t);
   28781          173 :           if (node != NULL)
   28782              :             {
   28783          126 :               node->offloadable = 1;
   28784          126 :               if (ENABLE_OFFLOADING)
   28785              :                 {
   28786              :                   g->have_offload = true;
   28787              :                   if (is_a <varpool_node *> (node))
   28788              :                     vec_safe_push (offload_vars, t);
   28789              :                 }
   28790              :             }
   28791              :         }
   28792          202 :       if (TREE_CODE (t) != FUNCTION_DECL)
   28793          121 :         continue;
   28794           81 :       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
   28795              :         {
   28796           13 :           tree at3 = lookup_attribute ("omp declare target host",
   28797           13 :                                        DECL_ATTRIBUTES (t));
   28798           13 :           if (at3 == NULL_TREE)
   28799              :             {
   28800           11 :               id = get_identifier ("omp declare target host");
   28801           11 :               DECL_ATTRIBUTES (t)
   28802           22 :                 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   28803              :             }
   28804              :         }
   28805           81 :       if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
   28806              :         {
   28807           13 :           tree at3 = lookup_attribute ("omp declare target nohost",
   28808           13 :                                        DECL_ATTRIBUTES (t));
   28809           13 :           if (at3 == NULL_TREE)
   28810              :             {
   28811           11 :               id = get_identifier ("omp declare target nohost");
   28812           11 :               DECL_ATTRIBUTES (t)
   28813           22 :                 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   28814              :             }
   28815              :         }
   28816           81 :       if (indirect)
   28817              :         {
   28818            9 :           tree at4 = lookup_attribute ("omp declare target indirect",
   28819            9 :                                        DECL_ATTRIBUTES (t));
   28820            9 :           if (at4 == NULL_TREE)
   28821              :             {
   28822            9 :               id = get_identifier ("omp declare target indirect");
   28823            9 :               DECL_ATTRIBUTES (t)
   28824           18 :                 = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
   28825              :             }
   28826              :         }
   28827              :     }
   28828          168 :   if ((device_type || indirect) && only_device_type_or_indirect)
   28829            3 :     error_at (OMP_CLAUSE_LOCATION (clauses),
   28830              :               "directive with only %<device_type%> or %<indirect%> clauses");
   28831          168 :   if (indirect && device_type && device_type != OMP_CLAUSE_DEVICE_TYPE_ANY)
   28832            1 :     error_at (OMP_CLAUSE_LOCATION (clauses),
   28833              :               "%<device_type%> clause must specify 'any' when used with "
   28834              :               "an %<indirect%> clause");
   28835              : }
   28836              : 
   28837              : /* OpenMP 5.1
   28838              :    #pragma omp begin assumes clauses[optseq] new-line
   28839              : 
   28840              :    #pragma omp begin declare target clauses[optseq] new-line
   28841              : 
   28842              :    #pragma omp begin declare variant match (context-selector) new-line  */
   28843              : 
   28844              : #define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK                    \
   28845              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)    \
   28846              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INDIRECT))
   28847              : 
   28848              : static void
   28849          128 : c_parser_omp_begin (c_parser *parser)
   28850              : {
   28851          128 :   const char *p = "";
   28852          128 :   c_parser_consume_pragma (parser);
   28853          128 :   if (c_parser_next_token_is (parser, CPP_NAME))
   28854          128 :     p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   28855          128 :   if (strcmp (p, "declare") == 0)
   28856              :     {
   28857           82 :       c_parser_consume_token (parser);
   28858           82 :       p = "";
   28859           82 :       if (c_parser_next_token_is (parser, CPP_NAME))
   28860           82 :         p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   28861           82 :       if (strcmp (p, "target") == 0)
   28862              :         {
   28863           52 :           c_parser_consume_token (parser);
   28864           52 :           bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   28865           52 :           tree clauses
   28866           52 :             = c_parser_omp_all_clauses (parser,
   28867           52 :                                         OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
   28868              :                                         "#pragma omp begin declare target");
   28869           52 :           int device_type = 0;
   28870           52 :           int indirect = 0;
   28871           76 :           for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
   28872              :             {
   28873           24 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
   28874           15 :                 device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
   28875           24 :               if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_INDIRECT)
   28876            9 :                 indirect |= !integer_zerop (OMP_CLAUSE_INDIRECT_EXPR (c));
   28877              :             }
   28878           52 :           c_omp_declare_target_attr attr = { attr_syntax, device_type,
   28879           52 :                                              indirect };
   28880           52 :           vec_safe_push (current_omp_declare_target_attribute, attr);
   28881              :         }
   28882           30 :       else if (strcmp (p, "variant") == 0)
   28883              :         {
   28884           30 :           c_parser_consume_token (parser);
   28885           30 :           const char *clause = "";
   28886           30 :           matching_parens parens;
   28887           30 :           location_t match_loc = c_parser_peek_token (parser)->location;
   28888           30 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   28889            1 :             c_parser_consume_token (parser);
   28890           30 :           if (c_parser_next_token_is (parser, CPP_NAME))
   28891              :             {
   28892           30 :               tree id = c_parser_peek_token (parser)->value;
   28893           30 :               clause = IDENTIFIER_POINTER (id);
   28894              :             }
   28895           30 :           if (strcmp (clause, "match") != 0)
   28896              :             {
   28897            0 :               c_parser_error (parser, "expected %<match%>");
   28898            0 :               c_parser_skip_to_pragma_eol (parser);
   28899            6 :               return;
   28900              :             }
   28901              : 
   28902           30 :           c_parser_consume_token (parser);
   28903              : 
   28904           30 :           if (!parens.require_open (parser))
   28905              :             {
   28906            0 :               c_parser_skip_to_pragma_eol (parser, false);
   28907            0 :               return;
   28908              :             }
   28909              : 
   28910           30 :           tree ctx =
   28911           30 :             c_parser_omp_context_selector_specification (parser, NULL_TREE);
   28912           30 :           if (ctx != error_mark_node)
   28913           28 :             ctx = omp_check_context_selector (match_loc, ctx,
   28914              :                                               OMP_CTX_BEGIN_DECLARE_VARIANT);
   28915              : 
   28916           30 :           if (ctx != error_mark_node
   28917           30 :               && !vec_safe_is_empty (current_omp_declare_variant_attribute))
   28918              :             {
   28919            7 :               c_omp_declare_variant_attr a
   28920            7 :                 = current_omp_declare_variant_attribute->last ();
   28921            7 :               tree outer_ctx = a.selector;
   28922            7 :               ctx = omp_merge_context_selectors (match_loc, outer_ctx, ctx,
   28923              :                                                  OMP_CTX_BEGIN_DECLARE_VARIANT);
   28924              :             }
   28925              : 
   28926           30 :           if (ctx == error_mark_node
   28927           30 :               || !omp_context_selector_matches (ctx, NULL_TREE, false, true))
   28928              :             {
   28929              :               /* The context is either invalid or cannot possibly match.
   28930              :                  In the latter case the spec says all code in the begin/end
   28931              :                  sequence will be elided.  In the former case we'll get bogus
   28932              :                  errors from trying to parse it without a valid context to
   28933              :                  use for name-mangling, so elide that too.  */
   28934            6 :               c_parser_skip_to_pragma_eol (parser, false);
   28935            6 :               c_parser_skip_to_pragma_omp_end_declare_variant (parser);
   28936            6 :               return;
   28937              :             }
   28938              :           else
   28939              :             {
   28940           24 :               bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   28941           24 :               c_omp_declare_variant_attr a = { attr_syntax, ctx };
   28942           24 :               vec_safe_push (current_omp_declare_variant_attribute, a);
   28943              :             }
   28944              : 
   28945           24 :           parens.require_close (parser);
   28946           24 :           c_parser_skip_to_pragma_eol (parser);
   28947              :         }
   28948              :       else
   28949              :         {
   28950            0 :           c_parser_error (parser, "expected %<target%> or %<variant%>");
   28951            0 :           c_parser_skip_to_pragma_eol (parser, false);
   28952              :         }
   28953              :     }
   28954           46 :   else if (strcmp (p, "assumes") == 0)
   28955              :     {
   28956           46 :       c_parser_consume_token (parser);
   28957           46 :       bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   28958           46 :       c_parser_omp_assumption_clauses (parser, false);
   28959           46 :       struct c_omp_begin_assumes_data a = { attr_syntax };
   28960           46 :       vec_safe_push (current_omp_begin_assumes, a);
   28961              :     }
   28962              :   else
   28963              :     {
   28964            0 :       c_parser_error (parser, "expected %<declare target%>, "
   28965              :                       "%<declare variant%>, or %<assumes%>");
   28966            0 :       c_parser_skip_to_pragma_eol (parser);
   28967              :     }
   28968              : }
   28969              : 
   28970              : /* OpenMP 4.0
   28971              :    #pragma omp end declare target
   28972              : 
   28973              :    OpenMP 5.1
   28974              :    #pragma omp end assumes
   28975              :    #pragma omp end declare variant  */
   28976              : 
   28977              : static void
   28978          222 : c_parser_omp_end (c_parser *parser)
   28979              : {
   28980          222 :   location_t loc = c_parser_peek_token (parser)->location;
   28981          222 :   const char *p = "";
   28982          222 :   c_parser_consume_pragma (parser);
   28983          222 :   if (c_parser_next_token_is (parser, CPP_NAME))
   28984          222 :     p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   28985          222 :   if (strcmp (p, "declare") == 0)
   28986              :     {
   28987          176 :       c_parser_consume_token (parser);
   28988          176 :       p = "";
   28989          176 :       if (c_parser_next_token_is (parser, CPP_NAME))
   28990          176 :         p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   28991          176 :       if (strcmp (p, "target") == 0)
   28992              :         {
   28993          152 :           c_parser_consume_token (parser);
   28994          152 :           bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   28995          152 :           c_parser_skip_to_pragma_eol (parser);
   28996          152 :           if (!vec_safe_length (current_omp_declare_target_attribute))
   28997            2 :             error_at (loc, "%<#pragma omp end declare target%> without "
   28998              :                       "corresponding %<#pragma omp declare target%> or "
   28999              :                       "%<#pragma omp begin declare target%>");
   29000              :           else
   29001              :             {
   29002          150 :               c_omp_declare_target_attr
   29003          150 :                 a = current_omp_declare_target_attribute->pop ();
   29004          150 :               if (a.attr_syntax != attr_syntax)
   29005              :                 {
   29006           16 :                   if (a.attr_syntax)
   29007           12 :                     error_at (loc,
   29008              :                               "%qs in attribute syntax terminated "
   29009              :                               "with %qs in pragma syntax",
   29010              :                               a.device_type >= 0 ? "begin declare target"
   29011              :                                                  : "declare target",
   29012              :                               "end declare target");
   29013              :                   else
   29014           12 :                     error_at (loc,
   29015              :                               "%qs in pragma syntax terminated "
   29016              :                               "with %qs in attribute syntax",
   29017              :                               a.device_type >= 0 ? "begin declare target"
   29018              :                                                  : "declare target",
   29019              :                               "end declare target");
   29020              :                 }
   29021              :             }
   29022              :         }
   29023           24 :       else if (strcmp (p, "variant") == 0)
   29024              :         {
   29025           24 :           c_parser_consume_token (parser);
   29026           24 :           bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   29027           24 :           c_parser_skip_to_pragma_eol (parser);
   29028           24 :           if (!vec_safe_length (current_omp_declare_variant_attribute))
   29029            0 :             error_at (loc, "%<#pragma omp end declare variant%> without "
   29030              :                       "corresponding %<#pragma omp begin declare variant%>");
   29031              :           else
   29032              :             {
   29033           24 :               c_omp_declare_variant_attr
   29034           24 :                 a = current_omp_declare_variant_attribute->pop ();
   29035           24 :               if (a.attr_syntax != attr_syntax)
   29036              :                 {
   29037            2 :                   if (a.attr_syntax)
   29038            1 :                     error_at (loc,
   29039              :                               "%<begin declare variant%> in attribute syntax "
   29040              :                               "terminated with "
   29041              :                               "%<end declare variant%> in pragma syntax");
   29042              :                   else
   29043            1 :                     error_at (loc,
   29044              :                               "%<begin declare variant%> in pragma syntax "
   29045              :                               "terminated with "
   29046              :                               "%<end declare variant%> in attribute syntax");
   29047              :                 }
   29048              :             }
   29049              :         }
   29050              :       else
   29051              :         {
   29052            0 :           c_parser_error (parser, "expected %<target%> or %<variant%>");
   29053            0 :           c_parser_skip_to_pragma_eol (parser);
   29054            0 :           return;
   29055              :         }
   29056              :     }
   29057           46 :   else if (strcmp (p, "assumes") == 0)
   29058              :     {
   29059           46 :       c_parser_consume_token (parser);
   29060           46 :       bool attr_syntax = parser->in_omp_attribute_pragma != NULL;
   29061           46 :       c_parser_skip_to_pragma_eol (parser);
   29062           46 :       if (!vec_safe_length (current_omp_begin_assumes))
   29063            1 :         error_at (loc, "%qs without corresponding %qs",
   29064              :                   "#pragma omp end assumes", "#pragma omp begin assumes");
   29065              :       else
   29066              :         {
   29067           45 :           c_omp_begin_assumes_data
   29068           45 :             a = current_omp_begin_assumes->pop ();
   29069           45 :           if (a.attr_syntax != attr_syntax)
   29070              :             {
   29071            8 :               if (a.attr_syntax)
   29072            4 :                 error_at (loc,
   29073              :                           "%qs in attribute syntax terminated "
   29074              :                           "with %qs in pragma syntax",
   29075              :                           "begin assumes", "end assumes");
   29076              :               else
   29077            4 :                 error_at (loc,
   29078              :                           "%qs in pragma syntax terminated "
   29079              :                           "with %qs in attribute syntax",
   29080              :                           "begin assumes", "end assumes");
   29081              :             }
   29082              :         }
   29083              :     }
   29084              :   else
   29085              :     {
   29086            0 :       c_parser_error (parser, "expected %<declare%> or %<assumes%>");
   29087            0 :       c_parser_skip_to_pragma_eol (parser);
   29088              :     }
   29089              : }
   29090              : 
   29091              : /* OpenMP 5.0
   29092              :    #pragma omp declare mapper ([mapper-identifier :] type var) \
   29093              :                               [clause [ [,] clause ] ... ] new-line  */
   29094              : 
   29095              : static void
   29096           65 : c_parser_omp_declare_mapper (c_parser *parser, enum pragma_context context)
   29097              : {
   29098           65 :   tree type, mapper_name = NULL_TREE, var = NULL_TREE, stmt, stmtlist;
   29099           65 :   tree maplist = NULL_TREE, mapper_id, mapper_decl, t;
   29100           65 :   c_token *token;
   29101              : 
   29102           65 :   if (context == pragma_struct || context == pragma_param)
   29103              :     {
   29104            2 :       error ("%<#pragma omp declare mapper%> not at file or block scope");
   29105            2 :       goto fail;
   29106              :     }
   29107              : 
   29108           63 :   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   29109            0 :     goto fail;
   29110              : 
   29111           63 :   token = c_parser_peek_token (parser);
   29112              : 
   29113           63 :   if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   29114              :     {
   29115           22 :       switch (token->type)
   29116              :         {
   29117           15 :         case CPP_NAME:
   29118           15 :           mapper_name = token->value;
   29119           15 :           c_parser_consume_token (parser);
   29120           15 :           break;
   29121            7 :         case CPP_KEYWORD:
   29122            7 :           if (token->keyword == RID_DEFAULT)
   29123              :             {
   29124            6 :               mapper_name = NULL_TREE;
   29125            6 :               c_parser_consume_token (parser);
   29126            6 :               break;
   29127              :             }
   29128              :           /* Fallthrough.  */
   29129            1 :         default:
   29130            1 :           error_at (token->location, "expected identifier or %<default%>");
   29131            1 :           c_parser_skip_to_pragma_eol (parser, false);
   29132            1 :           return;
   29133              :         }
   29134              : 
   29135           21 :       if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   29136            0 :         goto fail;
   29137              :     }
   29138              : 
   29139           62 :   mapper_id = c_omp_mapper_id (mapper_name);
   29140           62 :   mapper_decl = c_omp_mapper_decl (mapper_id);
   29141              : 
   29142           62 :   {
   29143           62 :     location_t loc = c_parser_peek_token (parser)->location;
   29144           62 :     struct c_type_name *ctype = c_parser_type_name (parser);
   29145           62 :     type = groktypename (ctype, NULL, NULL);
   29146           62 :     if (type == error_mark_node)
   29147            3 :       goto fail;
   29148           59 :     if (!RECORD_OR_UNION_TYPE_P (type))
   29149              :       {
   29150            4 :         error_at (loc, "%qT is not a struct or union type in "
   29151              :                   "%<#pragma omp declare mapper%>", type);
   29152            4 :         c_parser_skip_to_pragma_eol (parser, false);
   29153            4 :         return;
   29154              :       }
   29155           65 :     for (tree t = DECL_INITIAL (mapper_decl); t; t = TREE_CHAIN (t))
   29156           17 :       if (comptypes (TREE_PURPOSE (t), type))
   29157              :         {
   29158            7 :           error_at (loc, "redeclaration of %qs %<#pragma omp declare "
   29159            7 :                     "mapper%> for type %qT", IDENTIFIER_POINTER (mapper_id)
   29160              :                       + sizeof ("omp declare mapper ") - 1,
   29161              :                     type);
   29162            7 :           tree prevmapper = TREE_VALUE (t);
   29163              :           /* Hmm, this location might not be very accurate.  */
   29164            7 :           location_t ploc
   29165            7 :             = DECL_SOURCE_LOCATION (OMP_DECLARE_MAPPER_DECL (prevmapper));
   29166            7 :           inform (ploc, "%<#pragma omp declare mapper%> "
   29167              :                         "previously declared here");
   29168            7 :           c_parser_skip_to_pragma_eol (parser, false);
   29169            7 :           return;
   29170              :         }
   29171              :   }
   29172              : 
   29173           48 :   token = c_parser_peek_token (parser);
   29174           48 :   if (token->type == CPP_NAME)
   29175              :     {
   29176           46 :       var = build_decl (token->location, VAR_DECL, token->value, type);
   29177           46 :       c_parser_consume_token (parser);
   29178           46 :       DECL_ARTIFICIAL (var) = 1;
   29179              :     }
   29180              :   else
   29181              :     {
   29182            2 :       error_at (token->location, "expected identifier");
   29183            2 :       goto fail;
   29184              :     }
   29185              : 
   29186           46 :   if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   29187            0 :     goto fail;
   29188              : 
   29189           46 :   push_scope ();
   29190           46 :   stmtlist = push_stmt_list ();
   29191           46 :   pushdecl (var);
   29192           46 :   DECL_CONTEXT (var) = current_function_decl;
   29193              : 
   29194          115 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   29195              :     {
   29196           70 :       location_t here;
   29197           70 :       pragma_omp_clause c_kind;
   29198           70 :       here = c_parser_peek_token (parser)->location;
   29199           70 :       c_kind = c_parser_omp_clause_name (parser);
   29200           70 :       if (c_kind != PRAGMA_OMP_CLAUSE_MAP)
   29201              :         {
   29202            1 :           error_at (here, "unexpected clause");
   29203            1 :           goto fail;
   29204              :         }
   29205           69 :       maplist = c_parser_omp_clause_map (parser, maplist, true);
   29206              :     }
   29207              : 
   29208           45 :   if (maplist == NULL_TREE)
   29209              :     {
   29210            1 :       error_at (input_location, "missing %<map%> clause");
   29211            1 :       goto fail;
   29212              :     }
   29213              : 
   29214           44 :   stmt = make_node (OMP_DECLARE_MAPPER);
   29215           44 :   TREE_TYPE (stmt) = type;
   29216           44 :   OMP_DECLARE_MAPPER_ID (stmt) = mapper_name;
   29217           44 :   OMP_DECLARE_MAPPER_DECL (stmt) = var;
   29218           44 :   OMP_DECLARE_MAPPER_CLAUSES (stmt) = maplist;
   29219              : 
   29220           44 :   add_stmt (stmt);
   29221              : 
   29222           44 :   pop_stmt_list (stmtlist);
   29223           44 :   pop_scope ();
   29224              : 
   29225           44 :   c_parser_skip_to_pragma_eol (parser);
   29226              : 
   29227           44 :   t = tree_cons (type, stmt, DECL_INITIAL (mapper_decl));
   29228           44 :   DECL_INITIAL (mapper_decl) = t;
   29229              : 
   29230           44 :   return;
   29231              : 
   29232            9 :  fail:
   29233            9 :   c_parser_skip_to_pragma_eol (parser);
   29234              : }
   29235              : 
   29236              : /* OpenMP 4.0
   29237              :    #pragma omp declare reduction (reduction-id : typename-list : expression) \
   29238              :       initializer-clause[opt] new-line
   29239              : 
   29240              :    initializer-clause:
   29241              :       initializer (omp_priv = initializer)
   29242              :       initializer (function-name (argument-list))  */
   29243              : 
   29244              : static void
   29245          164 : c_parser_omp_declare_reduction (c_parser *parser, enum pragma_context context)
   29246              : {
   29247          164 :   unsigned int tokens_avail = 0, i;
   29248          164 :   c_token *saved_tokens = NULL;
   29249          164 :   vec<tree> types = vNULL;
   29250          164 :   vec<c_token> clauses = vNULL;
   29251          164 :   enum tree_code reduc_code = ERROR_MARK;
   29252          164 :   tree reduc_id = NULL_TREE;
   29253          164 :   tree type;
   29254          164 :   location_t rloc = c_parser_peek_token (parser)->location;
   29255              : 
   29256          164 :   if (context == pragma_struct || context == pragma_param)
   29257              :     {
   29258            2 :       error ("%<#pragma omp declare reduction%> not at file or block scope");
   29259            2 :       goto fail;
   29260              :     }
   29261              : 
   29262          162 :   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   29263            1 :     goto fail;
   29264              : 
   29265          161 :   switch (c_parser_peek_token (parser)->type)
   29266              :     {
   29267              :     case CPP_PLUS:
   29268              :       reduc_code = PLUS_EXPR;
   29269              :       break;
   29270           14 :     case CPP_MULT:
   29271           14 :       reduc_code = MULT_EXPR;
   29272           14 :       break;
   29273            0 :     case CPP_MINUS:
   29274            0 :       reduc_code = MINUS_EXPR;
   29275            0 :       break;
   29276            4 :     case CPP_AND:
   29277            4 :       reduc_code = BIT_AND_EXPR;
   29278            4 :       break;
   29279            0 :     case CPP_XOR:
   29280            0 :       reduc_code = BIT_XOR_EXPR;
   29281            0 :       break;
   29282           10 :     case CPP_OR:
   29283           10 :       reduc_code = BIT_IOR_EXPR;
   29284           10 :       break;
   29285            0 :     case CPP_AND_AND:
   29286            0 :       reduc_code = TRUTH_ANDIF_EXPR;
   29287            0 :       break;
   29288            0 :     case CPP_OR_OR:
   29289            0 :       reduc_code = TRUTH_ORIF_EXPR;
   29290            0 :       break;
   29291           89 :     case CPP_NAME:
   29292           89 :       const char *p;
   29293           89 :       p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   29294           89 :       if (strcmp (p, "min") == 0)
   29295              :         {
   29296              :           reduc_code = MIN_EXPR;
   29297              :           break;
   29298              :         }
   29299           83 :       if (strcmp (p, "max") == 0)
   29300              :         {
   29301              :           reduc_code = MAX_EXPR;
   29302              :           break;
   29303              :         }
   29304           83 :       reduc_id = c_parser_peek_token (parser)->value;
   29305           83 :       break;
   29306            0 :     default:
   29307            0 :       c_parser_error (parser,
   29308              :                       "expected %<+%>, %<*%>, %<-%>, %<&%>, "
   29309              :                       "%<^%>, %<|%>, %<&&%>, %<||%> or identifier");
   29310            0 :       goto fail;
   29311              :     }
   29312              : 
   29313          161 :   tree orig_reduc_id, reduc_decl;
   29314          161 :   orig_reduc_id = reduc_id;
   29315          161 :   reduc_id = c_omp_reduction_id (reduc_code, reduc_id);
   29316          161 :   reduc_decl = c_omp_reduction_decl (reduc_id);
   29317          161 :   c_parser_consume_token (parser);
   29318              : 
   29319          161 :   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>"))
   29320            0 :     goto fail;
   29321              : 
   29322          165 :   while (true)
   29323              :     {
   29324          163 :       location_t loc = c_parser_peek_token (parser)->location;
   29325          163 :       struct c_type_name *ctype = c_parser_type_name (parser);
   29326          163 :       if (ctype != NULL)
   29327              :         {
   29328          163 :           type = groktypename (ctype, NULL, NULL);
   29329          163 :           if (type == error_mark_node)
   29330              :             ;
   29331          163 :           else if ((INTEGRAL_TYPE_P (type)
   29332          163 :                     || SCALAR_FLOAT_TYPE_P (type)
   29333           98 :                     || TREE_CODE (type) == COMPLEX_TYPE)
   29334           69 :                    && orig_reduc_id == NULL_TREE)
   29335            8 :             error_at (loc, "predeclared arithmetic type in "
   29336              :                            "%<#pragma omp declare reduction%>");
   29337          155 :           else if (TREE_CODE (type) == FUNCTION_TYPE
   29338          150 :                    || TREE_CODE (type) == ARRAY_TYPE)
   29339            8 :             error_at (loc, "function or array type in "
   29340              :                       "%<#pragma omp declare reduction%>");
   29341          147 :           else if (TYPE_ATOMIC (type))
   29342            1 :             error_at (loc, "%<_Atomic%> qualified type in "
   29343              :                            "%<#pragma omp declare reduction%>");
   29344          146 :           else if (TYPE_QUALS_NO_ADDR_SPACE (type))
   29345            8 :             error_at (loc, "const, volatile or restrict qualified type in "
   29346              :                            "%<#pragma omp declare reduction%>");
   29347              :           else
   29348              :             {
   29349          138 :               tree t;
   29350          200 :               for (t = DECL_INITIAL (reduc_decl); t; t = TREE_CHAIN (t))
   29351           66 :                 if (comptypes (TREE_PURPOSE (t), type))
   29352              :                   {
   29353            4 :                     error_at (loc, "redeclaration of %qs "
   29354              :                                    "%<#pragma omp declare reduction%> for "
   29355              :                                    "type %qT",
   29356            4 :                                    IDENTIFIER_POINTER (reduc_id)
   29357              :                                    + sizeof ("omp declare reduction ") - 1,
   29358              :                                    type);
   29359            4 :                     location_t ploc
   29360            4 :                       = DECL_SOURCE_LOCATION (TREE_VEC_ELT (TREE_VALUE (t),
   29361              :                                                             0));
   29362            4 :                     inform (ploc, "%<#pragma omp declare reduction%> "
   29363              :                                   "previously declared here");
   29364            4 :                     break;
   29365              :                   }
   29366            4 :               if (t == NULL_TREE)
   29367          134 :                 types.safe_push (type);
   29368              :             }
   29369          163 :           if (c_parser_next_token_is (parser, CPP_COMMA))
   29370            2 :             c_parser_consume_token (parser);
   29371              :           else
   29372              :             break;
   29373              :         }
   29374              :       else
   29375              :         break;
   29376            2 :     }
   29377              : 
   29378          161 :   if (!c_parser_require (parser, CPP_COLON, "expected %<:%>")
   29379          161 :       || types.is_empty ())
   29380              :     {
   29381           34 :      fail:
   29382           34 :       clauses.release ();
   29383           34 :       types.release ();
   29384          460 :       while (true)
   29385              :         {
   29386          247 :           c_token *token = c_parser_peek_token (parser);
   29387          247 :           if (token->type == CPP_EOF || token->type == CPP_PRAGMA_EOL)
   29388              :             break;
   29389          213 :           c_parser_consume_token (parser);
   29390          213 :         }
   29391           34 :       c_parser_skip_to_pragma_eol (parser);
   29392           34 :       return;
   29393              :     }
   29394              : 
   29395          132 :   if (types.length () > 1)
   29396              :     {
   29397           13 :       while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   29398              :         {
   29399           12 :           c_token *token = c_parser_peek_token (parser);
   29400           12 :           if (token->type == CPP_EOF)
   29401            0 :             goto fail;
   29402           12 :           clauses.safe_push (*token);
   29403           12 :           c_parser_consume_token (parser);
   29404              :         }
   29405            1 :       clauses.safe_push (*c_parser_peek_token (parser));
   29406            1 :       c_parser_skip_to_pragma_eol (parser);
   29407              : 
   29408              :       /* Make sure nothing tries to read past the end of the tokens.  */
   29409            1 :       c_token eof_token;
   29410            1 :       memset (&eof_token, 0, sizeof (eof_token));
   29411            1 :       eof_token.type = CPP_EOF;
   29412            1 :       clauses.safe_push (eof_token);
   29413            1 :       clauses.safe_push (eof_token);
   29414              :     }
   29415              : 
   29416          132 :   int errs = errorcount;
   29417          238 :   FOR_EACH_VEC_ELT (types, i, type)
   29418              :     {
   29419          134 :       saved_tokens = parser->tokens;
   29420          134 :       tokens_avail = parser->tokens_avail;
   29421          134 :       if (!clauses.is_empty ())
   29422              :         {
   29423            3 :           parser->tokens = clauses.address ();
   29424            3 :           parser->tokens_avail = clauses.length ();
   29425            3 :           parser->in_pragma = true;
   29426              :         }
   29427              : 
   29428          134 :       bool nested = current_function_decl != NULL_TREE;
   29429          134 :       if (nested)
   29430           27 :         c_push_function_context ();
   29431          134 :       tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
   29432              :                                 reduc_id, default_function_type);
   29433          134 :       current_function_decl = fndecl;
   29434          134 :       allocate_struct_function (fndecl, true);
   29435          134 :       push_scope ();
   29436          134 :       tree stmt = push_stmt_list ();
   29437              :       /* Intentionally BUILTINS_LOCATION, so that -Wshadow doesn't
   29438              :          warn about these.  */
   29439          134 :       tree omp_out = build_decl (BUILTINS_LOCATION, VAR_DECL,
   29440              :                                  get_identifier ("omp_out"), type);
   29441          134 :       DECL_ARTIFICIAL (omp_out) = 1;
   29442          134 :       DECL_CONTEXT (omp_out) = fndecl;
   29443          134 :       pushdecl (omp_out);
   29444          134 :       tree omp_in = build_decl (BUILTINS_LOCATION, VAR_DECL,
   29445              :                                 get_identifier ("omp_in"), type);
   29446          134 :       DECL_ARTIFICIAL (omp_in) = 1;
   29447          134 :       DECL_CONTEXT (omp_in) = fndecl;
   29448          134 :       pushdecl (omp_in);
   29449          134 :       struct c_expr combiner = c_parser_expression (parser);
   29450          134 :       struct c_expr initializer;
   29451          134 :       tree omp_priv = NULL_TREE, omp_orig = NULL_TREE;
   29452          134 :       bool bad = false;
   29453          134 :       initializer.set_error ();
   29454          134 :       if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   29455              :         bad = true;
   29456          134 :       else if (c_parser_next_token_is (parser, CPP_COMMA)
   29457          134 :                && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   29458            2 :         c_parser_consume_token (parser);
   29459            2 :       if (!bad
   29460          134 :           && (c_parser_next_token_is (parser, CPP_NAME)
   29461           77 :               && strcmp (IDENTIFIER_POINTER
   29462              :                                 (c_parser_peek_token (parser)->value),
   29463              :                           "initializer") == 0))
   29464              :         {
   29465           77 :           c_parser_consume_token (parser);
   29466           77 :           pop_scope ();
   29467           77 :           push_scope ();
   29468           77 :           omp_priv = build_decl (BUILTINS_LOCATION, VAR_DECL,
   29469              :                                  get_identifier ("omp_priv"), type);
   29470           77 :           DECL_ARTIFICIAL (omp_priv) = 1;
   29471           77 :           DECL_INITIAL (omp_priv) = error_mark_node;
   29472           77 :           DECL_CONTEXT (omp_priv) = fndecl;
   29473           77 :           pushdecl (omp_priv);
   29474           77 :           omp_orig = build_decl (BUILTINS_LOCATION, VAR_DECL,
   29475              :                                  get_identifier ("omp_orig"), type);
   29476           77 :           DECL_ARTIFICIAL (omp_orig) = 1;
   29477           77 :           DECL_CONTEXT (omp_orig) = fndecl;
   29478           77 :           pushdecl (omp_orig);
   29479           77 :           if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
   29480              :             bad = true;
   29481           77 :           else if (!c_parser_next_token_is (parser, CPP_NAME))
   29482              :             {
   29483            0 :               c_parser_error (parser, "expected %<omp_priv%> or "
   29484              :                                       "function-name");
   29485            0 :               bad = true;
   29486              :             }
   29487           77 :           else if (strcmp (IDENTIFIER_POINTER
   29488              :                                 (c_parser_peek_token (parser)->value),
   29489              :                            "omp_priv") != 0)
   29490              :             {
   29491           20 :               if (c_parser_peek_2nd_token (parser)->type != CPP_OPEN_PAREN
   29492           20 :                   || c_parser_peek_token (parser)->id_kind != C_ID_ID)
   29493              :                 {
   29494            0 :                   c_parser_error (parser, "expected function-name %<(%>");
   29495            0 :                   bad = true;
   29496              :                 }
   29497              :               else
   29498           20 :                 initializer = c_parser_postfix_expression (parser);
   29499           20 :               if (initializer.value
   29500           20 :                   && TREE_CODE (initializer.value) == CALL_EXPR)
   29501              :                 {
   29502              :                   int j;
   29503              :                   tree c = initializer.value;
   29504           21 :                   for (j = 0; j < call_expr_nargs (c); j++)
   29505              :                     {
   29506           20 :                       tree a = CALL_EXPR_ARG (c, j);
   29507           20 :                       STRIP_NOPS (a);
   29508           20 :                       if (TREE_CODE (a) == ADDR_EXPR
   29509           20 :                           && TREE_OPERAND (a, 0) == omp_priv)
   29510              :                         break;
   29511              :                     }
   29512           20 :                   if (j == call_expr_nargs (c))
   29513            1 :                     error ("one of the initializer call arguments should be "
   29514              :                            "%<&omp_priv%>");
   29515              :                 }
   29516              :             }
   29517              :           else
   29518              :             {
   29519           57 :               c_parser_consume_token (parser);
   29520           57 :               if (!c_parser_require (parser, CPP_EQ, "expected %<=%>"))
   29521              :                 bad = true;
   29522              :               else
   29523              :                 {
   29524           55 :                   tree st = push_stmt_list ();
   29525           55 :                   location_t loc = c_parser_peek_token (parser)->location;
   29526           55 :                   rich_location richloc (line_table, loc);
   29527           55 :                   start_init (omp_priv, NULL_TREE, false, false, &richloc);
   29528           55 :                   struct c_expr init = c_parser_initializer (parser, omp_priv);
   29529           55 :                   finish_init ();
   29530           55 :                   finish_decl (omp_priv, loc, init.value,
   29531              :                                init.original_type, NULL_TREE);
   29532           55 :                   pop_stmt_list (st);
   29533           55 :                 }
   29534              :             }
   29535            0 :           if (!bad
   29536           75 :               && !c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
   29537              :             bad = true;
   29538              :         }
   29539              : 
   29540          134 :       if (!bad)
   29541              :         {
   29542          132 :           c_parser_skip_to_pragma_eol (parser);
   29543              : 
   29544          189 :           tree t = tree_cons (type, make_tree_vec (omp_priv ? 6 : 3),
   29545          132 :                               DECL_INITIAL (reduc_decl));
   29546          132 :           DECL_INITIAL (reduc_decl) = t;
   29547          132 :           DECL_SOURCE_LOCATION (omp_out) = rloc;
   29548          132 :           TREE_VEC_ELT (TREE_VALUE (t), 0) = omp_out;
   29549          132 :           TREE_VEC_ELT (TREE_VALUE (t), 1) = omp_in;
   29550          132 :           TREE_VEC_ELT (TREE_VALUE (t), 2) = combiner.value;
   29551          132 :           walk_tree (&combiner.value, c_check_omp_declare_reduction_r,
   29552              :                      &TREE_VEC_ELT (TREE_VALUE (t), 0), NULL);
   29553          132 :           if (omp_priv)
   29554              :             {
   29555           75 :               DECL_SOURCE_LOCATION (omp_priv) = rloc;
   29556           75 :               TREE_VEC_ELT (TREE_VALUE (t), 3) = omp_priv;
   29557           75 :               TREE_VEC_ELT (TREE_VALUE (t), 4) = omp_orig;
   29558           75 :               TREE_VEC_ELT (TREE_VALUE (t), 5) = initializer.value;
   29559           75 :               walk_tree (&initializer.value, c_check_omp_declare_reduction_r,
   29560              :                          &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
   29561           75 :               walk_tree (&DECL_INITIAL (omp_priv),
   29562              :                          c_check_omp_declare_reduction_r,
   29563              :                          &TREE_VEC_ELT (TREE_VALUE (t), 3), NULL);
   29564              :             }
   29565              :         }
   29566              : 
   29567          134 :       pop_stmt_list (stmt);
   29568          134 :       pop_scope ();
   29569          134 :       if (cfun->language != NULL)
   29570              :         {
   29571            0 :           ggc_free (cfun->language);
   29572            0 :           cfun->language = NULL;
   29573              :         }
   29574          134 :       set_cfun (NULL);
   29575          134 :       current_function_decl = NULL_TREE;
   29576          134 :       if (nested)
   29577           27 :         c_pop_function_context ();
   29578              : 
   29579          134 :       if (!clauses.is_empty ())
   29580              :         {
   29581            3 :           parser->tokens = saved_tokens;
   29582            3 :           parser->tokens_avail = tokens_avail;
   29583              :         }
   29584          134 :       if (bad)
   29585            2 :         goto fail;
   29586          132 :       if (errs != errorcount)
   29587              :         break;
   29588              :     }
   29589              : 
   29590          130 :   clauses.release ();
   29591          130 :   types.release ();
   29592              : }
   29593              : 
   29594              : /* OpenMP 4.0
   29595              :    #pragma omp declare simd declare-simd-clauses[optseq] new-line
   29596              :    #pragma omp declare reduction (reduction-id : typename-list : expression) \
   29597              :       initializer-clause[opt] new-line
   29598              :    #pragma omp declare target new-line
   29599              : 
   29600              :    OpenMP 5.0
   29601              :    #pragma omp declare variant (identifier) match (context-selector)
   29602              : 
   29603              :    OpenMP 5.1
   29604              :    #pragma omp declare variant (identifier) match (context-selector) \
   29605              :       adjust_args(adjust-op:argument-list)  */
   29606              : 
   29607              : static bool
   29608         1280 : c_parser_omp_declare (c_parser *parser, enum pragma_context context)
   29609              : {
   29610         1280 :   c_parser_consume_pragma (parser);
   29611         1280 :   if (c_parser_next_token_is (parser, CPP_NAME))
   29612              :     {
   29613         1280 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   29614         1280 :       if (strcmp (p, "simd") == 0)
   29615              :         {
   29616              :           /* c_parser_consume_token (parser); done in
   29617              :              c_parser_omp_declare_simd.  */
   29618          280 :           c_parser_omp_declare_simd (parser, context);
   29619          280 :           return true;
   29620              :         }
   29621         1000 :       if (strcmp (p, "reduction") == 0)
   29622              :         {
   29623          164 :           c_parser_consume_token (parser);
   29624          164 :           c_parser_omp_declare_reduction (parser, context);
   29625          164 :           return false;
   29626              :         }
   29627          836 :       if (strcmp (p, "mapper") == 0)
   29628              :         {
   29629           65 :           c_parser_consume_token (parser);
   29630           65 :           c_parser_omp_declare_mapper (parser, context);
   29631           65 :           return false;
   29632              :         }
   29633          771 :       if (!flag_openmp)  /* flag_openmp_simd  */
   29634              :         {
   29635            0 :           c_parser_skip_to_pragma_eol (parser, false);
   29636            0 :           return false;
   29637              :         }
   29638          771 :       if (strcmp (p, "target") == 0)
   29639              :         {
   29640          270 :           c_parser_consume_token (parser);
   29641          270 :           c_parser_omp_declare_target (parser);
   29642          270 :           return false;
   29643              :         }
   29644          501 :       if (strcmp (p, "variant") == 0)
   29645              :         {
   29646              :           /* c_parser_consume_token (parser); done in
   29647              :              c_parser_omp_declare_simd.  */
   29648          501 :           c_parser_omp_declare_simd (parser, context);
   29649          501 :           return true;
   29650              :         }
   29651              :     }
   29652              : 
   29653            0 :   c_parser_error (parser, "expected %<simd%>, %<reduction%>, "
   29654              :                           "%<target%> or %<variant%>");
   29655            0 :   c_parser_skip_to_pragma_eol (parser);
   29656            0 :   return false;
   29657              : }
   29658              : 
   29659              : /* OpenMP 5.0
   29660              :    #pragma omp requires clauses[optseq] new-line  */
   29661              : 
   29662              : static void
   29663           59 : c_parser_omp_requires (c_parser *parser)
   29664              : {
   29665           59 :   enum omp_requires new_req = (enum omp_requires) 0;
   29666              : 
   29667           59 :   c_parser_consume_pragma (parser);
   29668              : 
   29669           59 :   location_t loc = c_parser_peek_token (parser)->location;
   29670          132 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   29671              :     {
   29672           77 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   29673           77 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   29674           14 :         c_parser_consume_token (parser);
   29675              : 
   29676           77 :       if (c_parser_next_token_is (parser, CPP_NAME))
   29677              :         {
   29678           76 :           const char *p
   29679           76 :             = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   29680           76 :           location_t cloc = c_parser_peek_token (parser)->location;
   29681           76 :           enum omp_requires this_req = (enum omp_requires) 0;
   29682              : 
   29683           76 :           if (!strcmp (p, "unified_address"))
   29684              :             this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
   29685           62 :           else if (!strcmp (p, "unified_shared_memory"))
   29686              :             this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
   29687           50 :           else if (!strcmp (p, "self_maps"))
   29688              :             this_req = OMP_REQUIRES_SELF_MAPS;
   29689           49 :           else if (!strcmp (p, "dynamic_allocators"))
   29690              :             this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
   29691           38 :           else if (!strcmp (p, "reverse_offload"))
   29692              :             this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
   29693           21 :           else if (!strcmp (p, "atomic_default_mem_order"))
   29694              :             {
   29695           20 :               c_parser_consume_token (parser);
   29696              : 
   29697           20 :               matching_parens parens;
   29698           20 :               if (parens.require_open (parser))
   29699              :                 {
   29700           20 :                   if (c_parser_next_token_is (parser, CPP_NAME))
   29701              :                     {
   29702           19 :                       tree v = c_parser_peek_token (parser)->value;
   29703           19 :                       p = IDENTIFIER_POINTER (v);
   29704              : 
   29705           19 :                       if (!strcmp (p, "seq_cst"))
   29706              :                         this_req
   29707              :                           = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
   29708           10 :                       else if (!strcmp (p, "relaxed"))
   29709              :                         this_req
   29710              :                           = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
   29711            9 :                       else if (!strcmp (p, "release"))
   29712              :                         this_req
   29713              :                           = (enum omp_requires) OMP_MEMORY_ORDER_RELEASE;
   29714            7 :                       else if (!strcmp (p, "acq_rel"))
   29715              :                         this_req
   29716              :                           = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
   29717            4 :                       else if (!strcmp (p, "acquire"))
   29718              :                         this_req
   29719              :                           = (enum omp_requires) OMP_MEMORY_ORDER_ACQUIRE;
   29720              :                     }
   29721              :                   if (this_req == 0)
   29722              :                     {
   29723            2 :                       error_at (c_parser_peek_token (parser)->location,
   29724              :                                 "expected %<acq_rel%>, %<acquire%>, "
   29725              :                                 "%<relaxed%>, %<release%> or %<seq_cst%>");
   29726            2 :                       switch (c_parser_peek_token (parser)->type)
   29727              :                         {
   29728              :                         case CPP_EOF:
   29729              :                         case CPP_PRAGMA_EOL:
   29730              :                         case CPP_CLOSE_PAREN:
   29731              :                           break;
   29732            1 :                         default:
   29733            1 :                           if (c_parser_peek_2nd_token (parser)->type
   29734              :                               == CPP_CLOSE_PAREN)
   29735            1 :                             c_parser_consume_token (parser);
   29736              :                           break;
   29737              :                         }
   29738              :                     }
   29739              :                   else
   29740           18 :                     c_parser_consume_token (parser);
   29741              : 
   29742           20 :                   parens.skip_until_found_close (parser);
   29743           20 :                   if (this_req == 0)
   29744              :                     {
   29745            2 :                       c_parser_skip_to_pragma_eol (parser, false);
   29746            2 :                       return;
   29747              :                     }
   29748              :                 }
   29749           18 :               p = NULL;
   29750              :             }
   29751              :           else
   29752              :             {
   29753            1 :               error_at (cloc, "expected %<unified_address%>, "
   29754              :                               "%<unified_shared_memory%>, "
   29755              :                               "%<self_maps%>, "
   29756              :                               "%<dynamic_allocators%>, "
   29757              :                                "%<reverse_offload%> "
   29758              :                                "or %<atomic_default_mem_order%> clause");
   29759            1 :               c_parser_skip_to_pragma_eol (parser, false);
   29760            1 :               return;
   29761              :             }
   29762           18 :           if (p)
   29763           55 :             c_parser_consume_token (parser);
   29764           73 :           if (this_req)
   29765              :             {
   29766           73 :               if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
   29767              :                 {
   29768           55 :                   if ((this_req & new_req) != 0)
   29769            4 :                     error_at (cloc, "too many %qs clauses", p);
   29770           55 :                   if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
   29771           44 :                       && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
   29772            4 :                     error_at (cloc, "%qs clause used lexically after first "
   29773              :                                     "target construct or offloading API", p);
   29774              :                 }
   29775           18 :               else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
   29776              :                 {
   29777            1 :                   error_at (cloc, "too many %qs clauses",
   29778              :                             "atomic_default_mem_order");
   29779            1 :                   this_req = (enum omp_requires) 0;
   29780              :                 }
   29781           17 :               else if ((omp_requires_mask
   29782              :                         & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
   29783              :                 {
   29784            2 :                   error_at (cloc, "more than one %<atomic_default_mem_order%>"
   29785              :                                   " clause in a single compilation unit");
   29786            2 :                   this_req
   29787            2 :                     = (enum omp_requires)
   29788            2 :                        (omp_requires_mask
   29789              :                         & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
   29790              :                 }
   29791           15 :               else if ((omp_requires_mask
   29792              :                         & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
   29793            1 :                 error_at (cloc, "%<atomic_default_mem_order%> clause used "
   29794              :                                 "lexically after first %<atomic%> construct "
   29795              :                                 "without memory order clause");
   29796           73 :               new_req = (enum omp_requires) (new_req | this_req);
   29797           73 :               omp_requires_mask
   29798           73 :                 = (enum omp_requires) (omp_requires_mask | this_req);
   29799           73 :               continue;
   29800              :             }
   29801              :         }
   29802              :       break;
   29803              :     }
   29804           56 :   c_parser_skip_to_pragma_eol (parser);
   29805              : 
   29806           56 :   if (new_req == 0)
   29807            1 :     error_at (loc, "%<pragma omp requires%> requires at least one clause");
   29808              : }
   29809              : 
   29810              : /* Helper function for c_parser_omp_taskloop.
   29811              :    Disallow zero sized or potentially zero sized task reductions.  */
   29812              : 
   29813              : static tree
   29814          413 : c_finish_taskloop_clauses (tree clauses)
   29815              : {
   29816          413 :   tree *pc = &clauses;
   29817         2064 :   for (tree c = clauses; c; c = *pc)
   29818              :     {
   29819         1651 :       bool remove = false;
   29820         1651 :       if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
   29821              :         {
   29822          143 :           tree type = strip_array_types (TREE_TYPE (OMP_CLAUSE_DECL (c)));
   29823          143 :           if (integer_zerop (TYPE_SIZE_UNIT (type)))
   29824              :             {
   29825            2 :               error_at (OMP_CLAUSE_LOCATION (c),
   29826              :                         "zero sized type %qT in %<reduction%> clause", type);
   29827            2 :               remove = true;
   29828              :             }
   29829          141 :           else if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST)
   29830              :             {
   29831            0 :               error_at (OMP_CLAUSE_LOCATION (c),
   29832              :                         "variable sized type %qT in %<reduction%> clause",
   29833              :                         type);
   29834            0 :               remove = true;
   29835              :             }
   29836              :         }
   29837            2 :       if (remove)
   29838            2 :         *pc = OMP_CLAUSE_CHAIN (c);
   29839              :       else
   29840         1649 :         pc = &OMP_CLAUSE_CHAIN (c);
   29841              :     }
   29842          413 :   return clauses;
   29843              : }
   29844              : 
   29845              : /* OpenMP 4.5:
   29846              :    #pragma omp taskloop taskloop-clause[optseq] new-line
   29847              :      for-loop
   29848              : 
   29849              :    #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
   29850              :      for-loop  */
   29851              : 
   29852              : #define OMP_TASKLOOP_CLAUSE_MASK                                \
   29853              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED) \
   29854              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)        \
   29855              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)   \
   29856              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)    \
   29857              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)        \
   29858              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)      \
   29859              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)      \
   29860              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)       \
   29861              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED) \
   29862              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)             \
   29863              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)  \
   29864              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)      \
   29865              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)        \
   29866              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)       \
   29867              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)       \
   29868              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)      \
   29869              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))
   29870              : 
   29871              : static tree
   29872          418 : c_parser_omp_taskloop (location_t loc, c_parser *parser,
   29873              :                        char *p_name, omp_clause_mask mask, tree *cclauses,
   29874              :                        bool *if_p)
   29875              : {
   29876          418 :   tree clauses, block, ret;
   29877              : 
   29878          418 :   strcat (p_name, " taskloop");
   29879          418 :   mask |= OMP_TASKLOOP_CLAUSE_MASK;
   29880              :   /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
   29881              :      clause.  */
   29882          418 :   if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
   29883           94 :     mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);
   29884              : 
   29885          418 :   if (c_parser_next_token_is (parser, CPP_NAME))
   29886              :     {
   29887          342 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   29888              : 
   29889          342 :       if (strcmp (p, "simd") == 0)
   29890              :         {
   29891          178 :           tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
   29892          178 :           if (cclauses == NULL)
   29893           84 :             cclauses = cclauses_buf;
   29894          178 :           c_parser_consume_token (parser);
   29895          178 :           if (!flag_openmp)  /* flag_openmp_simd  */
   29896            3 :             return c_parser_omp_simd (loc, parser, p_name, mask, cclauses,
   29897            3 :                                       if_p);
   29898          175 :           block = c_begin_compound_stmt (true);
   29899          175 :           ret = c_parser_omp_simd (loc, parser, p_name, mask, cclauses, if_p);
   29900          175 :           block = c_end_compound_stmt (loc, block, true);
   29901          175 :           if (ret == NULL)
   29902              :             return ret;
   29903          175 :           ret = make_node (OMP_TASKLOOP);
   29904          175 :           TREE_TYPE (ret) = void_type_node;
   29905          175 :           OMP_FOR_BODY (ret) = block;
   29906          175 :           OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
   29907          175 :           OMP_FOR_CLAUSES (ret)
   29908          175 :             = c_finish_taskloop_clauses (OMP_FOR_CLAUSES (ret));
   29909          175 :           SET_EXPR_LOCATION (ret, loc);
   29910          175 :           add_stmt (ret);
   29911          175 :           return ret;
   29912              :         }
   29913              :     }
   29914          240 :   if (!flag_openmp)  /* flag_openmp_simd  */
   29915              :     {
   29916            2 :       c_parser_skip_to_pragma_eol (parser, false);
   29917            2 :       return NULL_TREE;
   29918              :     }
   29919              : 
   29920          238 :   clauses = c_parser_omp_all_clauses (parser, mask, p_name, cclauses == NULL);
   29921          238 :   if (cclauses)
   29922              :     {
   29923           66 :       omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
   29924           66 :       clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
   29925              :     }
   29926              : 
   29927          238 :   clauses = c_finish_taskloop_clauses (clauses);
   29928          238 :   block = c_begin_compound_stmt (true);
   29929          238 :   ret = c_parser_omp_for_loop (loc, parser, OMP_TASKLOOP, clauses, NULL, if_p);
   29930          238 :   block = c_end_compound_stmt (loc, block, true);
   29931          238 :   add_stmt (block);
   29932              : 
   29933          238 :   return ret;
   29934              : }
   29935              : 
   29936              : /* OpenMP 5.1: Parse sizes list for "omp tile sizes"
   29937              :    sizes ( size-expr-list ) */
   29938              : static tree
   29939          476 : c_parser_omp_tile_sizes (c_parser *parser, location_t loc)
   29940              : {
   29941          476 :   tree sizes = NULL_TREE;
   29942              : 
   29943          476 :   if (c_parser_next_token_is (parser, CPP_COMMA))
   29944            2 :     c_parser_consume_token (parser);
   29945              : 
   29946          476 :   c_token *tok = c_parser_peek_token (parser);
   29947          476 :   if (tok->type != CPP_NAME
   29948          476 :       || strcmp ("sizes", IDENTIFIER_POINTER (tok->value)))
   29949              :     {
   29950            1 :       c_parser_error (parser, "expected %<sizes%>");
   29951            1 :       return error_mark_node;
   29952              :     }
   29953          475 :   c_parser_consume_token (parser);
   29954              : 
   29955          475 :   matching_parens parens;
   29956          475 :   if (!parens.require_open (parser))
   29957            4 :     return error_mark_node;
   29958              : 
   29959          471 :   vec<tree, va_gc> *sizes_vec
   29960          471 :     = c_parser_expr_list (parser, true, true, NULL, NULL, NULL, NULL);
   29961          471 :   sizes = build_tree_list_vec (sizes_vec);
   29962          471 :   release_tree_vector (sizes_vec);
   29963              : 
   29964         1198 :   for (tree s = sizes; s; s = TREE_CHAIN (s))
   29965              :     {
   29966          734 :       tree expr = TREE_VALUE (s);
   29967          734 :       if (expr == error_mark_node)
   29968              :         {
   29969            7 :           parens.skip_until_found_close (parser);
   29970            7 :           return error_mark_node;
   29971              :         }
   29972              : 
   29973          727 :       HOST_WIDE_INT n;
   29974         1454 :       if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
   29975          724 :           || !tree_fits_shwi_p (expr)
   29976          722 :           || (n = tree_to_shwi (expr)) <= 0
   29977         1440 :           || (int) n != n)
   29978              :         {
   29979           14 :           c_parser_error (parser, "%<sizes%> argument needs positive"
   29980              :                                   " integral constant");
   29981           14 :           TREE_VALUE (s) = integer_one_node;
   29982              :         }
   29983              :     }
   29984          464 :   parens.require_close (parser);
   29985              : 
   29986          464 :   gcc_assert (sizes);
   29987          464 :   tree c = build_omp_clause (loc, OMP_CLAUSE_SIZES);
   29988          464 :   OMP_CLAUSE_SIZES_LIST (c) = sizes;
   29989              : 
   29990          464 :   return c;
   29991              : }
   29992              : 
   29993              : /* OpenMP 5.1:
   29994              :    #pragma omp tile sizes ( size-expr-list ) new-line
   29995              :      for-loop
   29996              : 
   29997              :    LOC is the location of the #pragma token.  */
   29998              : 
   29999              : static tree
   30000          476 : c_parser_omp_tile (location_t loc, c_parser *parser, bool *if_p)
   30001              : {
   30002          476 :   tree clauses = c_parser_omp_tile_sizes (parser, loc);
   30003          476 :   c_parser_skip_to_pragma_eol (parser);
   30004              : 
   30005          476 :   if (!clauses || clauses == error_mark_node)
   30006           12 :     return error_mark_node;
   30007              : 
   30008          464 :   tree block = c_begin_compound_stmt (true);
   30009          464 :   tree ret = c_parser_omp_for_loop (loc, parser, OMP_TILE, clauses,
   30010              :                                     NULL, if_p);
   30011          464 :   block = c_end_compound_stmt (loc, block, true);
   30012          464 :   add_stmt (block);
   30013              : 
   30014          464 :   return ret;
   30015              : }
   30016              : 
   30017              : #define OMP_UNROLL_CLAUSE_MASK                                  \
   30018              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARTIAL)        \
   30019              :         | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FULL))
   30020              : 
   30021              : /* OpenMP 5.1
   30022              :    #pragma omp unroll unroll-clause[optseq] new-line
   30023              :      for-loop
   30024              : 
   30025              :    LOC is the location of the #pragma token.  */
   30026              : 
   30027              : static tree
   30028          313 : c_parser_omp_unroll (location_t loc, c_parser *parser, bool *if_p)
   30029              : {
   30030          313 :   tree clauses = c_parser_omp_all_clauses (parser, OMP_UNROLL_CLAUSE_MASK,
   30031              :                                            "#pragma omp unroll", true);
   30032              : 
   30033          313 :   tree block = c_begin_compound_stmt (true);
   30034          313 :   tree ret = c_parser_omp_for_loop (loc, parser, OMP_UNROLL, clauses,
   30035              :                                     NULL, if_p);
   30036          313 :   block = c_end_compound_stmt (loc, block, true);
   30037          313 :   add_stmt (block);
   30038              : 
   30039          313 :   return ret;
   30040              : }
   30041              : 
   30042              : /* OpenMP 5.1
   30043              :    #pragma omp nothing new-line  */
   30044              : 
   30045              : static void
   30046           79 : c_parser_omp_nothing (c_parser *parser)
   30047              : {
   30048           79 :   c_parser_consume_pragma (parser);
   30049           79 :   c_parser_skip_to_pragma_eol (parser);
   30050           79 : }
   30051              : 
   30052              : /* OpenMP 5.1
   30053              :    #pragma omp error clauses[optseq] new-line  */
   30054              : 
   30055              : static bool
   30056          126 : c_parser_omp_error (c_parser *parser, enum pragma_context context)
   30057              : {
   30058          126 :   int at_compilation = -1;
   30059          126 :   int severity_fatal = -1;
   30060          126 :   tree message = NULL_TREE;
   30061          126 :   bool bad = false;
   30062          126 :   location_t loc = c_parser_peek_token (parser)->location;
   30063              : 
   30064          126 :   c_parser_consume_pragma (parser);
   30065              : 
   30066          463 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   30067              :     {
   30068          214 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   30069          214 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   30070           21 :         c_parser_consume_token (parser);
   30071              : 
   30072          214 :       if (!c_parser_next_token_is (parser, CPP_NAME))
   30073              :         break;
   30074              : 
   30075          213 :       const char *p
   30076          213 :         = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   30077          213 :       location_t cloc = c_parser_peek_token (parser)->location;
   30078          213 :       static const char *args[] = {
   30079              :         "execution", "compilation", "warning", "fatal"
   30080              :       };
   30081          213 :       int *v = NULL;
   30082          213 :       int idx = 0, n = -1;
   30083          213 :       tree m = NULL_TREE;
   30084              : 
   30085          213 :       if (!strcmp (p, "at"))
   30086              :         v = &at_compilation;
   30087          127 :       else if (!strcmp (p, "severity"))
   30088              :         {
   30089              :           v = &severity_fatal;
   30090              :           idx += 2;
   30091              :         }
   30092           82 :       else if (strcmp (p, "message"))
   30093              :         {
   30094            2 :           error_at (cloc,
   30095              :                     "expected %<at%>, %<severity%> or %<message%> clause");
   30096            2 :           c_parser_skip_to_pragma_eol (parser, false);
   30097            2 :           return false;
   30098              :         }
   30099              : 
   30100          211 :       c_parser_consume_token (parser);
   30101              : 
   30102          211 :       matching_parens parens;
   30103          211 :       if (parens.require_open (parser))
   30104              :         {
   30105          208 :           if (v == NULL)
   30106              :             {
   30107           79 :               location_t expr_loc = c_parser_peek_token (parser)->location;
   30108           79 :               c_expr expr = c_parser_expr_no_commas (parser, NULL);
   30109           79 :               expr = convert_lvalue_to_rvalue (expr_loc, expr, true, true);
   30110           79 :               m = convert (const_string_type_node, expr.value);
   30111           79 :               m = c_fully_fold (m, false, NULL);
   30112              :             }
   30113              :           else
   30114              :             {
   30115          129 :               if (c_parser_next_token_is (parser, CPP_NAME))
   30116              :                 {
   30117          125 :                   tree val = c_parser_peek_token (parser)->value;
   30118          125 :                   const char *q = IDENTIFIER_POINTER (val);
   30119              : 
   30120          125 :                   if (!strcmp (q, args[idx]))
   30121              :                     n = 0;
   30122           41 :                   else if (!strcmp (q, args[idx + 1]))
   30123              :                     n = 1;
   30124              :                 }
   30125              :               if (n == -1)
   30126              :                 {
   30127            6 :                   error_at (c_parser_peek_token (parser)->location,
   30128            6 :                             "expected %qs or %qs", args[idx], args[idx + 1]);
   30129            6 :                   bad = true;
   30130            6 :                   switch (c_parser_peek_token (parser)->type)
   30131              :                     {
   30132              :                     case CPP_EOF:
   30133              :                     case CPP_PRAGMA_EOL:
   30134              :                     case CPP_CLOSE_PAREN:
   30135              :                       break;
   30136            4 :                     default:
   30137            4 :                       if (c_parser_peek_2nd_token (parser)->type
   30138              :                           == CPP_CLOSE_PAREN)
   30139            2 :                         c_parser_consume_token (parser);
   30140              :                       break;
   30141              :                     }
   30142              :                 }
   30143              :               else
   30144          123 :                 c_parser_consume_token (parser);
   30145              :             }
   30146              : 
   30147          208 :           parens.skip_until_found_close (parser);
   30148              : 
   30149          208 :           if (v == NULL)
   30150              :             {
   30151           79 :               if (message)
   30152              :                 {
   30153            1 :                   error_at (cloc, "too many %qs clauses", p);
   30154            1 :                   bad = true;
   30155              :                 }
   30156              :               else
   30157              :                 message = m;
   30158              :             }
   30159          129 :           else if (n != -1)
   30160              :             {
   30161          123 :               if (*v != -1)
   30162              :                 {
   30163            2 :                   error_at (cloc, "too many %qs clauses", p);
   30164            2 :                   bad = true;
   30165              :                 }
   30166              :               else
   30167          121 :                 *v = n;
   30168              :             }
   30169              :         }
   30170              :       else
   30171              :         bad = true;
   30172              :     }
   30173          124 :   c_parser_skip_to_pragma_eol (parser);
   30174          124 :   if (bad)
   30175              :     return true;
   30176              : 
   30177          112 :   if (at_compilation == -1)
   30178           33 :     at_compilation = 1;
   30179          112 :   if (severity_fatal == -1)
   30180           74 :     severity_fatal = 1;
   30181          112 :   if (!at_compilation)
   30182              :     {
   30183           58 :       if (context != pragma_compound)
   30184              :         {
   30185            7 :           error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
   30186              :                          "may only be used in compound statements");
   30187            7 :           return true;
   30188              :         }
   30189           51 :       if (parser->omp_for_parse_state
   30190            1 :           && parser->omp_for_parse_state->in_intervening_code)
   30191              :         {
   30192            1 :           error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
   30193              :                          "may not be used in intervening code");
   30194            1 :           parser->omp_for_parse_state->fail = true;
   30195            1 :           return true;
   30196              :         }
   30197           50 :       tree fndecl
   30198           58 :         = builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
   30199              :                                                 : BUILT_IN_GOMP_WARNING);
   30200           50 :       if (!message)
   30201            4 :         message = build_zero_cst (const_string_type_node);
   30202           50 :       tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
   30203              :                                        build_all_ones_cst (size_type_node));
   30204           50 :       add_stmt (stmt);
   30205           50 :       return true;
   30206              :     }
   30207           54 :   const char *msg = NULL;
   30208           54 :   if (message)
   30209              :     {
   30210           27 :       msg = c_getstr (message);
   30211           27 :       if (msg == NULL)
   30212            6 :         msg = _("<message unknown at compile time>");
   30213              :     }
   30214           15 :   const enum diagnostics::kind diag_kind = (severity_fatal
   30215           54 :                                             ? diagnostics::kind::error
   30216              :                                             : diagnostics::kind::warning);
   30217           54 :   if (msg)
   30218           27 :     emit_diagnostic (diag_kind, loc, 0,
   30219              :                      "%<pragma omp error%> encountered: %s", msg);
   30220              :   else
   30221           27 :     emit_diagnostic (diag_kind, loc, 0,
   30222              :                      "%<pragma omp error%> encountered");
   30223              :   return false;
   30224              : }
   30225              : 
   30226              : /* Assumption clauses
   30227              :    OpenMP 5.1:
   30228              :    absent (directive-name-list)
   30229              :    contains (directive-name-list)
   30230              :    holds (expression)
   30231              :    no_openmp
   30232              :    no_openmp_routines
   30233              :    no_parallelism
   30234              : 
   30235              :    OpenMP 6.0:
   30236              :    no_openmp_constructs  */
   30237              : 
   30238              : static void
   30239          130 : c_parser_omp_assumption_clauses (c_parser *parser, bool is_assume)
   30240              : {
   30241          130 :   bool no_openmp = false;
   30242          130 :   bool no_openmp_constructs = false;
   30243          130 :   bool no_openmp_routines = false;
   30244          130 :   bool no_parallelism = false;
   30245          130 :   bitmap_head absent_head, contains_head;
   30246              : 
   30247          130 :   bitmap_obstack_initialize (NULL);
   30248          130 :   bitmap_initialize (&absent_head, &bitmap_default_obstack);
   30249          130 :   bitmap_initialize (&contains_head, &bitmap_default_obstack);
   30250              : 
   30251          130 :   if (c_parser_next_token_is (parser, CPP_PRAGMA_EOL))
   30252            3 :     error_at (c_parser_peek_token (parser)->location,
   30253              :               "expected at least one assumption clause");
   30254              : 
   30255          359 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   30256              :     {
   30257          233 :       if (c_parser_next_token_is (parser, CPP_COMMA)
   30258          233 :           && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
   30259           53 :         c_parser_consume_token (parser);
   30260              : 
   30261          233 :       if (!c_parser_next_token_is (parser, CPP_NAME))
   30262              :         break;
   30263              : 
   30264          233 :       const char *p
   30265          233 :         = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   30266          233 :       location_t cloc = c_parser_peek_token (parser)->location;
   30267              : 
   30268          233 :       if (!strcmp (p, "no_openmp"))
   30269              :         {
   30270           18 :           c_parser_consume_token (parser);
   30271           18 :           if (no_openmp)
   30272            3 :             error_at (cloc, "too many %qs clauses", "no_openmp");
   30273              :           no_openmp = true;
   30274              :         }
   30275          215 :       else if (!strcmp (p, "no_openmp_constructs"))
   30276              :         {
   30277            4 :           c_parser_consume_token (parser);
   30278            4 :           if (no_openmp_constructs)
   30279            1 :             error_at (cloc, "too many %qs clauses", "no_openmp_constructs");
   30280              :           no_openmp_constructs = true;
   30281              :         }
   30282          211 :       else if (!strcmp (p, "no_openmp_routines"))
   30283              :         {
   30284           17 :           c_parser_consume_token (parser);
   30285           17 :           if (no_openmp_routines)
   30286            3 :             error_at (cloc, "too many %qs clauses", "no_openmp_routines");
   30287              :           no_openmp_routines = true;
   30288              :         }
   30289          194 :       else if (!strcmp (p, "no_parallelism"))
   30290              :         {
   30291           19 :           c_parser_consume_token (parser);
   30292           19 :           if (no_parallelism)
   30293            3 :             error_at (cloc, "too many %qs clauses", "no_parallelism");
   30294              :           no_parallelism = true;
   30295              :         }
   30296          175 :       else if (!strcmp (p, "holds"))
   30297              :         {
   30298           19 :           c_parser_consume_token (parser);
   30299           19 :           matching_parens parens;
   30300           19 :           if (parens.require_open (parser))
   30301              :             {
   30302           19 :               location_t eloc = c_parser_peek_token (parser)->location;
   30303           19 :               c_expr expr = c_parser_expr_no_commas (parser, NULL);
   30304           19 :               tree t = convert_lvalue_to_rvalue (eloc, expr, true, true).value;
   30305           19 :               t = c_objc_common_truthvalue_conversion (eloc, t);
   30306           19 :               t = c_fully_fold (t, false, NULL);
   30307           19 :               if (is_assume && t != error_mark_node)
   30308              :                 {
   30309           11 :                   tree fn = build_call_expr_internal_loc (eloc, IFN_ASSUME,
   30310              :                                                           void_type_node, 1,
   30311              :                                                           t);
   30312           11 :                   add_stmt (fn);
   30313              :                 }
   30314           19 :               parens.skip_until_found_close (parser);
   30315              :             }
   30316              :         }
   30317          156 :       else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
   30318              :         {
   30319          146 :           c_parser_consume_token (parser);
   30320          146 :           matching_parens parens;
   30321          146 :           if (parens.require_open (parser))
   30322              :             {
   30323          604 :               do
   30324              :                 {
   30325          375 :                   const char *directive[3] = {};
   30326          375 :                   int i;
   30327          375 :                   location_t dloc = c_parser_peek_token (parser)->location;
   30328          844 :                   for (i = 0; i < 3; i++)
   30329              :                     {
   30330          811 :                       tree id;
   30331          811 :                       if (c_parser_peek_nth_token (parser, i + 1)->type
   30332              :                           == CPP_NAME)
   30333          457 :                         id = c_parser_peek_nth_token (parser, i + 1)->value;
   30334          354 :                       else if (c_parser_peek_nth_token (parser, i + 1)->keyword
   30335              :                                != RID_MAX)
   30336              :                         {
   30337           12 :                           enum rid rid
   30338           12 :                             = c_parser_peek_nth_token (parser, i + 1)->keyword;
   30339           12 :                           id = ridpointers[rid];
   30340              :                         }
   30341              :                       else
   30342              :                         break;
   30343          469 :                       directive[i] = IDENTIFIER_POINTER (id);
   30344              :                     }
   30345          375 :                   if (i == 0)
   30346            0 :                     error_at (dloc, "expected directive name");
   30347              :                   else
   30348              :                     {
   30349          375 :                       const struct c_omp_directive *dir
   30350          375 :                         = c_omp_categorize_directive (directive[0],
   30351              :                                                       directive[1],
   30352              :                                                       directive[2]);
   30353          375 :                       if (dir
   30354          372 :                           && dir->id != PRAGMA_OMP_END
   30355          369 :                           && (dir->kind == C_OMP_DIR_DECLARATIVE
   30356          365 :                               || dir->kind == C_OMP_DIR_INFORMATIONAL
   30357          356 :                               || dir->kind == C_OMP_DIR_META))
   30358           13 :                         error_at (dloc, "invalid OpenMP directive name in "
   30359              :                                         "%qs clause argument: declarative, "
   30360              :                                         "informational, and meta directives "
   30361              :                                         "not permitted", p);
   30362              :                       else if (dir == NULL
   30363          359 :                                || dir->id == PRAGMA_OMP_END
   30364          356 :                                || (!dir->second && directive[1])
   30365          347 :                                || (!dir->third && directive[2]))
   30366           15 :                         error_at (dloc, "unknown OpenMP directive name in "
   30367              :                                         "%qs clause argument", p);
   30368              :                       else
   30369              :                         {
   30370          347 :                           int id = dir - c_omp_directives;
   30371          392 :                           if (bitmap_bit_p (p[0] == 'a' ? &contains_head
   30372              :                                                         : &absent_head, id))
   30373           18 :                             error_at (dloc, "%<%s%s%s%s%s%> directive "
   30374              :                                             "mentioned in both %<absent%> and "
   30375              :                                             "%<contains%> clauses",
   30376              :                                       directive[0],
   30377              :                                       directive[1] ? " " : "",
   30378              :                                       directive[1] ? directive[1] : "",
   30379              :                                       directive[2] ? " " : "",
   30380              :                                       directive[2] ? directive[2] : "");
   30381          383 :                           else if (!bitmap_set_bit (p[0] == 'a'
   30382              :                                                     ? &absent_head
   30383              :                                                     : &contains_head, id))
   30384           36 :                             error_at (dloc, "%<%s%s%s%s%s%> directive "
   30385              :                                             "mentioned multiple times in %qs "
   30386              :                                             "clauses",
   30387              :                                       directive[0],
   30388              :                                       directive[1] ? " " : "",
   30389              :                                       directive[1] ? directive[1] : "",
   30390              :                                       directive[2] ? " " : "",
   30391              :                                       directive[2] ? directive[2] : "", p);
   30392              :                         }
   30393          844 :                       for (; i; --i)
   30394          469 :                         c_parser_consume_token (parser);
   30395              :                     }
   30396          375 :                   if (c_parser_next_token_is (parser, CPP_COMMA))
   30397          229 :                     c_parser_consume_token (parser);
   30398              :                   else
   30399              :                     break;
   30400          229 :                 }
   30401              :               while (1);
   30402          146 :               parens.skip_until_found_close (parser);
   30403              :             }
   30404          146 :         }
   30405           10 :       else if (startswith (p, "ext_"))
   30406              :         {
   30407            6 :           warning_at (cloc, OPT_Wopenmp, "unknown assumption clause %qs", p);
   30408            6 :           c_parser_consume_token (parser);
   30409            6 :           if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
   30410              :             {
   30411            3 :               matching_parens parens;
   30412            3 :               parens.consume_open (parser);
   30413            3 :               c_parser_balanced_token_sequence (parser);
   30414            3 :               parens.require_close (parser);
   30415              :             }
   30416              :         }
   30417              :       else
   30418              :         {
   30419            4 :           c_parser_consume_token (parser);
   30420            4 :           error_at (cloc, "expected assumption clause");
   30421            4 :           break;
   30422              :         }
   30423              :     }
   30424          130 :   c_parser_skip_to_pragma_eol (parser);
   30425          130 : }
   30426              : 
   30427              : /* OpenMP 5.1
   30428              :    #pragma omp assume clauses[optseq] new-line  */
   30429              : 
   30430              : static void
   30431           46 : c_parser_omp_assume (c_parser *parser, bool *if_p)
   30432              : {
   30433           46 :   c_parser_omp_assumption_clauses (parser, true);
   30434           46 :   add_stmt (c_parser_omp_structured_block (parser, if_p));
   30435           46 : }
   30436              : 
   30437              : /* OpenMP 5.1
   30438              :    #pragma omp assumes clauses[optseq] new-line  */
   30439              : 
   30440              : static void
   30441           38 : c_parser_omp_assumes (c_parser *parser)
   30442              : {
   30443           38 :   c_parser_consume_pragma (parser);
   30444           38 :   c_parser_omp_assumption_clauses (parser, false);
   30445           38 : }
   30446              : 
   30447              : /* Helper function for c_parser_omp_metadirective.  */
   30448              : 
   30449              : static void
   30450           58 : analyze_metadirective_body (c_parser *parser,
   30451              :                             vec<c_token> &tokens,
   30452              :                             vec<tree> &labels)
   30453              : {
   30454           58 :   int nesting_depth = 0;
   30455           58 :   int bracket_depth = 0;
   30456           58 :   bool ignore_label = false;
   30457              : 
   30458              :   /* Read in the body tokens to the tokens for each candidate directive.  */
   30459         3242 :   while (1)
   30460              :     {
   30461         1650 :       c_token *token = c_parser_peek_token (parser);
   30462         1650 :       bool stop = false;
   30463              : 
   30464         1650 :       if (c_parser_next_token_is_keyword (parser, RID_CASE))
   30465            0 :         ignore_label = true;
   30466              : 
   30467         1650 :       switch (token->type)
   30468              :         {
   30469              :         case CPP_EOF:
   30470              :           break;
   30471          531 :         case CPP_NAME:
   30472          531 :           if (!ignore_label
   30473          531 :               && c_parser_peek_2nd_token (parser)->type == CPP_COLON)
   30474            0 :             labels.safe_push (token->value);
   30475          531 :           goto add;
   30476           21 :         case CPP_OPEN_BRACE:
   30477           21 :           ++nesting_depth;
   30478           21 :           goto add;
   30479           21 :         case CPP_CLOSE_BRACE:
   30480           21 :           if (--nesting_depth == 0 && bracket_depth == 0)
   30481           21 :             stop = true;
   30482           21 :           goto add;
   30483           85 :         case CPP_OPEN_PAREN:
   30484           85 :           ++bracket_depth;
   30485           85 :           goto add;
   30486           85 :         case CPP_CLOSE_PAREN:
   30487           85 :           --bracket_depth;
   30488           85 :           goto add;
   30489            9 :         case CPP_COLON:
   30490            9 :           ignore_label = false;
   30491            9 :           goto add;
   30492          185 :         case CPP_SEMICOLON:
   30493          185 :           if (nesting_depth == 0 && bracket_depth == 0)
   30494           50 :             stop = true;
   30495          185 :           goto add;
   30496         1650 :         default:
   30497         1650 :         add:
   30498         1650 :           tokens.safe_push (*token);
   30499         1650 :           if (token->type == CPP_PRAGMA)
   30500            5 :             c_parser_consume_pragma (parser);
   30501         1645 :           else if (token->type == CPP_PRAGMA_EOL)
   30502            5 :             c_parser_skip_to_pragma_eol (parser);
   30503              :           else
   30504         1640 :             c_parser_consume_token (parser);
   30505         1650 :           if (stop)
   30506              :             break;
   30507         1592 :           continue;
   30508              :         }
   30509           58 :       break;
   30510         1592 :     }
   30511           58 : }
   30512              : 
   30513              : /* OpenMP 5.0:
   30514              : 
   30515              :   # pragma omp metadirective [clause[, clause]]
   30516              : */
   30517              : 
   30518              : static void
   30519          110 : c_parser_omp_metadirective (c_parser *parser, bool *if_p)
   30520              : {
   30521          110 :   static unsigned int metadirective_region_count = 0;
   30522              : 
   30523          110 :   tree ret;
   30524          110 :   auto_vec<c_token> directive_tokens;
   30525          110 :   auto_vec<c_token> body_tokens;
   30526          110 :   auto_vec<tree> body_labels;
   30527          110 :   auto_vec<const struct c_omp_directive *> directives;
   30528          110 :   auto_vec<tree> ctxs;
   30529          110 :   vec<struct omp_variant> candidates;
   30530          110 :   bool default_seen = false;
   30531          110 :   int directive_token_idx = 0;
   30532          110 :   tree standalone_body = NULL_TREE;
   30533          110 :   location_t pragma_loc = c_parser_peek_token (parser)->location;
   30534          110 :   bool requires_body = false;
   30535              : 
   30536          110 :   ret = make_node (OMP_METADIRECTIVE);
   30537          110 :   SET_EXPR_LOCATION (ret, pragma_loc);
   30538          110 :   TREE_TYPE (ret) = void_type_node;
   30539          110 :   OMP_METADIRECTIVE_VARIANTS (ret) = NULL_TREE;
   30540              : 
   30541          110 :   c_parser_consume_pragma (parser);
   30542          418 :   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
   30543              :     {
   30544          214 :       if (c_parser_next_token_is (parser, CPP_COMMA))
   30545           15 :         c_parser_consume_token (parser);
   30546          214 :       if (c_parser_next_token_is_not (parser, CPP_NAME)
   30547          278 :           && c_parser_next_token_is_not (parser, CPP_KEYWORD))
   30548              :         {
   30549            0 :           c_parser_error (parser, "expected %<when%>, "
   30550              :                           "%<otherwise%>, or %<default%> clause");
   30551            0 :           goto error;
   30552              :         }
   30553              : 
   30554          214 :       location_t match_loc = c_parser_peek_token (parser)->location;
   30555          214 :       const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
   30556          214 :       if (strcmp (p, "default") == 0)
   30557              :         {
   30558           64 :           gcc_rich_location richloc (pragma_loc);
   30559           64 :           richloc.add_fixit_replace (match_loc, "otherwise");
   30560           64 :           warning_at (&richloc, OPT_Wdeprecated_openmp,
   30561              :                       "%<default%> clause on metadirectives deprecated since "
   30562              :                       "OpenMP 5.2, use %<otherwise%>");
   30563           64 :         }
   30564          214 :       c_parser_consume_token (parser);
   30565          428 :       bool default_p
   30566          214 :         = strcmp (p, "default") == 0 || strcmp (p, "otherwise") == 0;
   30567          133 :       if (default_p)
   30568              :         {
   30569           81 :           if (default_seen)
   30570              :             {
   30571            4 :               error_at (match_loc, "too many %<otherwise%> or %<default%> "
   30572              :                         "clauses in %<metadirective%>");
   30573            4 :               goto error;
   30574              :             }
   30575              :           default_seen = true;
   30576              :         }
   30577          133 :       else if (default_seen)
   30578              :         {
   30579            2 :           error_at (match_loc, "%<otherwise%> or %<default%> clause "
   30580              :                     "must appear last in %<metadirective%>");
   30581            2 :           goto error;
   30582              :         }
   30583          208 :       if (!default_p && strcmp (p, "when") != 0)
   30584              :         {
   30585            2 :           error_at (match_loc, "%qs is not valid for %qs",
   30586              :                     p, "metadirective");
   30587            2 :           goto error;
   30588              :         }
   30589              : 
   30590          206 :       matching_parens parens;
   30591          206 :       tree ctx = NULL_TREE;
   30592          206 :       bool skip = false;
   30593              : 
   30594          206 :       if (!parens.require_open (parser))
   30595            0 :         goto error;
   30596              : 
   30597          206 :       if (!default_p)
   30598              :         {
   30599          129 :           ctx = c_parser_omp_context_selector_specification (parser,
   30600              :                                                              NULL_TREE);
   30601          129 :           if (ctx == error_mark_node)
   30602            2 :             goto error;
   30603          127 :           ctx = omp_check_context_selector (match_loc, ctx,
   30604              :                                             OMP_CTX_METADIRECTIVE);
   30605          127 :           if (ctx == error_mark_node)
   30606            0 :             goto error;
   30607              : 
   30608              :           /* Remove the selector from further consideration if it can be
   30609              :              evaluated as a non-match at this point.  */
   30610          127 :           skip = (omp_context_selector_matches (ctx, NULL_TREE, false) == 0);
   30611              : 
   30612          127 :           if (c_parser_next_token_is_not (parser, CPP_COLON))
   30613              :             {
   30614            2 :               c_parser_require (parser, CPP_COLON, "expected %<:%>");
   30615            2 :               goto error;
   30616              :             }
   30617          125 :           c_parser_consume_token (parser);
   30618              :         }
   30619              : 
   30620              :       /* Read in the directive type and create a dummy pragma token for
   30621              :          it.  */
   30622          202 :       location_t loc = c_parser_peek_token (parser)->location;
   30623              : 
   30624          202 :       const char *directive[3] = {};
   30625          202 :       int i;
   30626          561 :       for (i = 0; i < 3; i++)
   30627              :         {
   30628          541 :           tree id;
   30629          541 :           if (c_parser_peek_nth_token (parser, i + 1)->type
   30630              :               == CPP_CLOSE_PAREN)
   30631              :             {
   30632          118 :               if (i == 0)
   30633            2 :                 directive[i++] = "nothing";
   30634              :               break;
   30635              :             }
   30636          423 :           else if (c_parser_peek_nth_token (parser, i + 1)->type
   30637              :                    == CPP_NAME)
   30638          282 :             id = c_parser_peek_nth_token (parser, i + 1)->value;
   30639          141 :           else if (c_parser_peek_nth_token (parser, i + 1)->keyword
   30640              :                    != RID_MAX)
   30641              :             {
   30642           77 :               enum rid rid
   30643           77 :                 = c_parser_peek_nth_token (parser, i + 1)->keyword;
   30644           77 :               id = ridpointers[rid];
   30645              :             }
   30646              :           else
   30647              :             break;
   30648              : 
   30649          359 :           directive[i] = IDENTIFIER_POINTER (id);
   30650              :         }
   30651           86 :       if (i == 0)
   30652              :         {
   30653            0 :           error_at (loc, "expected directive name");
   30654            0 :           goto error;
   30655              :         }
   30656              : 
   30657          202 :       const struct c_omp_directive *omp_directive
   30658          202 :         = c_omp_categorize_directive (directive[0],
   30659              :                                       directive[1],
   30660          202 :                                       directive[2]);
   30661              : 
   30662          202 :       if (omp_directive == NULL)
   30663              :         {
   30664            4 :           for (int j = 0; j < i; j++)
   30665            2 :             c_parser_consume_token (parser);
   30666            2 :           c_parser_error (parser, "unknown directive name");
   30667            2 :           goto error;
   30668              :         }
   30669              :       else
   30670              :         {
   30671          200 :           int token_count = 0;
   30672          200 :           if (omp_directive->first) token_count++;
   30673          200 :           if (omp_directive->second) token_count++;
   30674          200 :           if (omp_directive->third) token_count++;
   30675          400 :           for (int j = 0; j < token_count; j++)
   30676          200 :             c_parser_consume_token (parser);
   30677              :         }
   30678          200 :       if (omp_directive->id == PRAGMA_OMP_METADIRECTIVE)
   30679              :         {
   30680            2 :           c_parser_error (parser,
   30681              :                           "metadirectives cannot be used as variants of a "
   30682              :                           "%<metadirective%>");
   30683            2 :           goto error;
   30684              :         }
   30685          198 :       if (omp_directive->kind == C_OMP_DIR_DECLARATIVE)
   30686              :         {
   30687            0 :           sorry_at (loc, "declarative directive variants of a "
   30688              :                          "%<metadirective%> are not supported");
   30689            0 :           goto error;
   30690              :         }
   30691          198 :       if (omp_directive->kind == C_OMP_DIR_CONSTRUCT)
   30692          117 :         requires_body = true;
   30693              : 
   30694          198 :       if (!skip)
   30695              :         {
   30696          163 :           c_token pragma_token;
   30697          163 :           pragma_token.type = CPP_PRAGMA;
   30698          163 :           pragma_token.location = loc;
   30699          163 :           pragma_token.pragma_kind = (enum pragma_kind) omp_directive->id;
   30700              : 
   30701          163 :           directives.safe_push (omp_directive);
   30702          163 :           directive_tokens.safe_push (pragma_token);
   30703          163 :           ctxs.safe_push (ctx);
   30704              :         }
   30705              : 
   30706              :       /* Read in tokens for the directive clauses.  */
   30707              :       int nesting_depth = 0;
   30708         1484 :       while (1)
   30709              :         {
   30710          841 :           c_token *token = c_parser_peek_token (parser);
   30711          841 :           switch (token->type)
   30712              :             {
   30713              :             case CPP_EOF:
   30714              :             case CPP_PRAGMA_EOL:
   30715              :               break;
   30716          117 :             case CPP_OPEN_PAREN:
   30717          117 :               ++nesting_depth;
   30718          117 :               goto add;
   30719          313 :             case CPP_CLOSE_PAREN:
   30720          313 :               if (nesting_depth-- == 0)
   30721              :                 {
   30722          196 :                   c_parser_consume_token (parser);
   30723          196 :                   break;
   30724              :                 }
   30725          117 :               goto add;
   30726          643 :             default:
   30727          643 :             add:
   30728          643 :               if (!skip)
   30729          550 :                 directive_tokens.safe_push (*token);
   30730          643 :               c_parser_consume_token (parser);
   30731          643 :               continue;
   30732              :             }
   30733          198 :           break;
   30734          643 :         }
   30735              : 
   30736          198 :       if (!skip)
   30737              :         {
   30738          163 :           c_token eol_token;
   30739          163 :           memset (&eol_token, 0, sizeof (eol_token));
   30740          163 :           eol_token.type = CPP_PRAGMA_EOL;
   30741          163 :           directive_tokens.safe_push (eol_token);
   30742              :         }
   30743              :     }
   30744           94 :   c_parser_skip_to_pragma_eol (parser);
   30745              : 
   30746              :   /* If only one selector matches and it evaluates to 'omp nothing', no need to
   30747              :      proceed.  */
   30748           94 :   if (ctxs.length () == 1)
   30749              :     {
   30750           37 :       tree ctx = ctxs[0];
   30751           37 :       if (ctx == NULL_TREE
   30752           37 :           || (omp_context_selector_matches (ctx, NULL_TREE, false) == 1
   30753           13 :               && directive_tokens[0].pragma_kind == PRAGMA_OMP_NOTHING))
   30754           22 :         return;
   30755              :     }
   30756              : 
   30757           72 :   if (!default_seen)
   30758              :     {
   30759              :       /* Add a default clause that evaluates to 'omp nothing'.  */
   30760           27 :       const struct c_omp_directive *omp_directive
   30761           27 :         = c_omp_categorize_directive ("nothing", NULL, NULL);
   30762              : 
   30763           27 :       c_token pragma_token;
   30764           27 :       pragma_token.type = CPP_PRAGMA;
   30765           27 :       pragma_token.location = UNKNOWN_LOCATION;
   30766           27 :       pragma_token.pragma_kind = PRAGMA_OMP_NOTHING;
   30767              : 
   30768           27 :       directives.safe_push (omp_directive);
   30769           27 :       directive_tokens.safe_push (pragma_token);
   30770           27 :       ctxs.safe_push (NULL_TREE);
   30771              : 
   30772           27 :       c_token eol_token;
   30773           27 :       memset (&eol_token, 0, sizeof (eol_token));
   30774           27 :       eol_token.type = CPP_PRAGMA_EOL;
   30775           27 :       directive_tokens.safe_push (eol_token);
   30776              :     }
   30777              : 
   30778           72 :   if (requires_body)
   30779           58 :     analyze_metadirective_body (parser, body_tokens, body_labels);
   30780              : 
   30781              :   /* Process each candidate directive.  */
   30782              :   unsigned i;
   30783              :   tree ctx;
   30784              : 
   30785          234 :   FOR_EACH_VEC_ELT (ctxs, i, ctx)
   30786              :     {
   30787          162 :       auto_vec<c_token> tokens;
   30788              : 
   30789              :       /* Add the directive tokens.  */
   30790          842 :       do
   30791          842 :         tokens.safe_push (directive_tokens [directive_token_idx++]);
   30792          842 :       while (tokens.last ().type != CPP_PRAGMA_EOL);
   30793              : 
   30794              :       /* Add the body tokens.  */
   30795          162 :       gcc_assert (requires_body || body_tokens.is_empty ());
   30796         3670 :       for (unsigned j = 0; j < body_tokens.length (); j++)
   30797         3508 :         tokens.safe_push (body_tokens[j]);
   30798              : 
   30799              :       /* Make sure nothing tries to read past the end of the tokens.  */
   30800          162 :       c_token eof_token;
   30801          162 :       memset (&eof_token, 0, sizeof (eof_token));
   30802          162 :       eof_token.type = CPP_EOF;
   30803          162 :       tokens.safe_push (eof_token);
   30804          162 :       tokens.safe_push (eof_token);
   30805              : 
   30806          162 :       unsigned int old_tokens_avail = parser->tokens_avail;
   30807          162 :       c_token *old_tokens = parser->tokens;
   30808          162 :       struct omp_attribute_pragma_state *old_in_omp_attribute_pragma
   30809              :         = parser->in_omp_attribute_pragma;
   30810          162 :       struct omp_metadirective_parse_data *old_state
   30811              :         = parser->omp_metadirective_state;
   30812              : 
   30813          162 :       struct omp_metadirective_parse_data new_state;
   30814          162 :       new_state.body_labels = &body_labels;
   30815          162 :       new_state.region_num = ++metadirective_region_count;
   30816              : 
   30817          162 :       parser->tokens = tokens.address ();
   30818          162 :       parser->tokens_avail = tokens.length ();
   30819          162 :       parser->in_omp_attribute_pragma = NULL;
   30820          162 :       parser->omp_metadirective_state = &new_state;
   30821              : 
   30822          162 :       int prev_errorcount = errorcount;
   30823          162 :       tree directive = c_begin_compound_stmt (true);
   30824              : 
   30825          162 :       c_parser_pragma (parser, pragma_compound, if_p, NULL_TREE);
   30826          162 :       directive = c_end_compound_stmt (pragma_loc, directive, true);
   30827          162 :       bool standalone_p
   30828          162 :         = directives[i]->kind == C_OMP_DIR_STANDALONE
   30829          162 :           || directives[i]->kind == C_OMP_DIR_UTILITY;
   30830           89 :       if (standalone_p && requires_body)
   30831              :         {
   30832              :           /* Parsing standalone directives will not consume the body
   30833              :              tokens, so do that here.  */
   30834           53 :           if (standalone_body == NULL_TREE)
   30835              :             {
   30836           51 :               standalone_body = push_stmt_list ();
   30837           51 :               c_parser_statement (parser, if_p); // TODO skip this
   30838           51 :               standalone_body = pop_stmt_list (standalone_body);
   30839              :             }
   30840              :           else
   30841            2 :             c_parser_skip_to_end_of_block_or_statement (parser, true);
   30842              :         }
   30843              : 
   30844          162 :       tree body = standalone_p ? standalone_body : NULL_TREE;
   30845          162 :       tree variant = make_omp_metadirective_variant (ctx, directive, body);
   30846          324 :       OMP_METADIRECTIVE_VARIANTS (ret)
   30847          162 :         = chainon (OMP_METADIRECTIVE_VARIANTS (ret), variant);
   30848              : 
   30849              :       /* Check that all valid tokens have been consumed if no parse errors
   30850              :          encountered.  */
   30851          162 :       if (errorcount == prev_errorcount)
   30852              :         {
   30853          160 :           gcc_assert (parser->tokens_avail == 2);
   30854          160 :           gcc_assert (c_parser_next_token_is (parser, CPP_EOF));
   30855          160 :           gcc_assert (c_parser_peek_2nd_token (parser)->type == CPP_EOF);
   30856              :         }
   30857              : 
   30858          162 :       parser->tokens = old_tokens;
   30859          162 :       parser->tokens_avail = old_tokens_avail;
   30860          162 :       parser->in_omp_attribute_pragma = old_in_omp_attribute_pragma;
   30861          162 :       parser->omp_metadirective_state = old_state;
   30862          162 :     }
   30863              : 
   30864              :   /* Try to resolve the metadirective early.  */
   30865           72 :   candidates = omp_early_resolve_metadirective (ret);
   30866           72 :   if (!candidates.is_empty ())
   30867           48 :     ret = c_omp_expand_variant_construct (candidates);
   30868              : 
   30869           72 :   add_stmt (ret);
   30870           72 :   return;
   30871              : 
   30872           16 : error:
   30873              :   /* Skip the metadirective pragma.  Do not skip the metadirective body.  */
   30874           16 :   if (parser->in_pragma)
   30875           16 :     c_parser_skip_to_pragma_eol (parser, false);
   30876          110 : }
   30877              : 
   30878              : /* Main entry point to parsing most OpenMP pragmas.  */
   30879              : 
   30880              : static void
   30881        17271 : c_parser_omp_construct (c_parser *parser, bool *if_p)
   30882              : {
   30883        17271 :   enum pragma_kind p_kind;
   30884        17271 :   location_t loc;
   30885        17271 :   tree stmt;
   30886        17271 :   char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
   30887        17271 :   omp_clause_mask mask (0);
   30888              : 
   30889        17271 :   loc = c_parser_peek_token (parser)->location;
   30890        17271 :   p_kind = c_parser_peek_token (parser)->pragma_kind;
   30891        17271 :   c_parser_consume_pragma (parser);
   30892              : 
   30893        17271 :   switch (p_kind)
   30894              :     {
   30895          309 :     case PRAGMA_OACC_ATOMIC:
   30896          309 :       c_parser_omp_atomic (loc, parser, true);
   30897         2074 :       return;
   30898          137 :     case PRAGMA_OACC_CACHE:
   30899          137 :       strcpy (p_name, "#pragma acc");
   30900          137 :       stmt = c_parser_oacc_cache (loc, parser);
   30901          137 :       break;
   30902          497 :     case PRAGMA_OACC_DATA:
   30903          497 :       stmt = c_parser_oacc_data (loc, parser, if_p);
   30904          497 :       break;
   30905           23 :     case PRAGMA_OACC_HOST_DATA:
   30906           23 :       stmt = c_parser_oacc_host_data (loc, parser, if_p);
   30907           23 :       break;
   30908         2154 :     case PRAGMA_OACC_KERNELS:
   30909         2154 :     case PRAGMA_OACC_PARALLEL:
   30910         2154 :     case PRAGMA_OACC_SERIAL:
   30911         2154 :       strcpy (p_name, "#pragma acc");
   30912         2154 :       stmt = c_parser_oacc_compute (loc, parser, p_kind, p_name, if_p);
   30913         2154 :       break;
   30914         1771 :     case PRAGMA_OACC_LOOP:
   30915         1771 :       strcpy (p_name, "#pragma acc");
   30916         1771 :       stmt = c_parser_oacc_loop (loc, parser, p_name, mask, NULL, if_p);
   30917         1771 :       break;
   30918           86 :     case PRAGMA_OACC_WAIT:
   30919           86 :       strcpy (p_name, "#pragma wait");
   30920           86 :       stmt = c_parser_oacc_wait (loc, parser, p_name);
   30921           86 :       break;
   30922         1410 :     case PRAGMA_OMP_ATOMIC:
   30923         1410 :       c_parser_omp_atomic (loc, parser, false);
   30924         1410 :       return;
   30925          144 :     case PRAGMA_OMP_CRITICAL:
   30926          144 :       stmt = c_parser_omp_critical (loc, parser, if_p);
   30927          144 :       break;
   30928         1314 :     case PRAGMA_OMP_DISTRIBUTE:
   30929         1314 :       strcpy (p_name, "#pragma omp");
   30930         1314 :       stmt = c_parser_omp_distribute (loc, parser, p_name, mask, NULL, if_p);
   30931         1314 :       break;
   30932         1817 :     case PRAGMA_OMP_FOR:
   30933         1817 :       strcpy (p_name, "#pragma omp");
   30934         1817 :       stmt = c_parser_omp_for (loc, parser, p_name, mask, NULL, if_p);
   30935         1817 :       break;
   30936          158 :     case PRAGMA_OMP_LOOP:
   30937          158 :       strcpy (p_name, "#pragma omp");
   30938          158 :       stmt = c_parser_omp_loop (loc, parser, p_name, mask, NULL, if_p);
   30939          158 :       break;
   30940           70 :     case PRAGMA_OMP_MASKED:
   30941           70 :       strcpy (p_name, "#pragma omp");
   30942           70 :       stmt = c_parser_omp_masked (loc, parser, p_name, mask, NULL, if_p);
   30943           70 :       break;
   30944          137 :     case PRAGMA_OMP_MASTER:
   30945          137 :       strcpy (p_name, "#pragma omp");
   30946          137 :       stmt = c_parser_omp_master (loc, parser, p_name, mask, NULL, if_p,
   30947              :                                   UNKNOWN_LOCATION);
   30948          137 :       break;
   30949         2490 :     case PRAGMA_OMP_PARALLEL:
   30950         2490 :       strcpy (p_name, "#pragma omp");
   30951         2490 :       stmt = c_parser_omp_parallel (loc, parser, p_name, mask, NULL, if_p);
   30952         2490 :       break;
   30953           61 :     case PRAGMA_OMP_SCOPE:
   30954           61 :       stmt = c_parser_omp_scope (loc, parser, if_p);
   30955           61 :       break;
   30956          106 :     case PRAGMA_OMP_SECTIONS:
   30957          106 :       strcpy (p_name, "#pragma omp");
   30958          106 :       stmt = c_parser_omp_sections (loc, parser, p_name, mask, NULL);
   30959          106 :       break;
   30960          731 :     case PRAGMA_OMP_SIMD:
   30961          731 :       strcpy (p_name, "#pragma omp");
   30962          731 :       stmt = c_parser_omp_simd (loc, parser, p_name, mask, NULL, if_p);
   30963          731 :       break;
   30964          222 :     case PRAGMA_OMP_SINGLE:
   30965          222 :       stmt = c_parser_omp_single (loc, parser, if_p);
   30966          222 :       break;
   30967          898 :     case PRAGMA_OMP_TASK:
   30968          898 :       stmt = c_parser_omp_task (loc, parser, if_p);
   30969          898 :       break;
   30970          138 :     case PRAGMA_OMP_TASKGROUP:
   30971          138 :       stmt = c_parser_omp_taskgroup (loc, parser, if_p);
   30972          138 :       break;
   30973          256 :     case PRAGMA_OMP_TASKLOOP:
   30974          256 :       strcpy (p_name, "#pragma omp");
   30975          256 :       stmt = c_parser_omp_taskloop (loc, parser, p_name, mask, NULL, if_p);
   30976          256 :       break;
   30977         1926 :     case PRAGMA_OMP_TEAMS:
   30978         1926 :       strcpy (p_name, "#pragma omp");
   30979         1926 :       stmt = c_parser_omp_teams (loc, parser, p_name, mask, NULL, if_p);
   30980         1926 :       break;
   30981           46 :     case PRAGMA_OMP_ASSUME:
   30982           46 :       c_parser_omp_assume (parser, if_p);
   30983           46 :       return;
   30984          110 :     case PRAGMA_OMP_TILE:
   30985          110 :       stmt = c_parser_omp_tile (loc, parser, if_p);
   30986          110 :       break;
   30987          105 :     case PRAGMA_OMP_UNROLL:
   30988          105 :       stmt = c_parser_omp_unroll (loc, parser, if_p);
   30989          105 :       break;
   30990          155 :     case PRAGMA_OMP_DISPATCH:
   30991          155 :       stmt = c_parser_omp_dispatch (loc, parser);
   30992          155 :       break;
   30993            0 :     default:
   30994            0 :       gcc_unreachable ();
   30995              :     }
   30996              : 
   30997        15506 :   if (stmt && stmt != error_mark_node)
   30998        15197 :     gcc_assert (EXPR_LOCATION (stmt) != UNKNOWN_LOCATION);
   30999              : }
   31000              : 
   31001              : /* OpenMP 6.0:
   31002              :    # pragma omp groupprivate (variable-list) [device_type(...)]  */
   31003              : 
   31004              : #define OMP_GROUPPRIVATE_CLAUSE_MASK                                    \
   31005              :         ( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE) )
   31006              : 
   31007              : static void
   31008            9 : c_parser_omp_groupprivate (c_parser *parser)
   31009              : {
   31010            9 :   location_t loc = c_parser_peek_token (parser)->location;
   31011            9 :   c_parser_consume_pragma (parser);
   31012            9 :   tree vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
   31013            9 :   tree clauses = c_parser_omp_all_clauses (parser, OMP_GROUPPRIVATE_CLAUSE_MASK,
   31014              :                                            "#pragma omp groupprivate");
   31015              :   /* TODO: Implies 'declare target local' with specified device_type, check for
   31016              :      conflicts.  Check for other restrictions.  */
   31017            9 :   (void) vars;
   31018            9 :   (void) clauses;
   31019            9 :   sorry_at (loc, "%<omp groupprivate%>");
   31020            9 : }
   31021              : 
   31022              : /* OpenMP 2.5:
   31023              :    # pragma omp threadprivate (variable-list) */
   31024              : 
   31025              : static void
   31026           78 : c_parser_omp_threadprivate (c_parser *parser)
   31027              : {
   31028           78 :   tree vars, t;
   31029           78 :   location_t loc;
   31030              : 
   31031           78 :   c_parser_consume_pragma (parser);
   31032           78 :   vars = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_ERROR, NULL);
   31033              : 
   31034              :   /* Mark every variable in VARS to be assigned thread local storage.  */
   31035          167 :   for (t = vars; t; t = TREE_CHAIN (t))
   31036              :     {
   31037           89 :       tree v = TREE_PURPOSE (t);
   31038           89 :       loc = EXPR_LOCATION (TREE_VALUE (t));
   31039              : 
   31040              :       /* If V had already been marked threadprivate, it doesn't matter
   31041              :          whether it had been used prior to this point.  */
   31042           89 :       if (!VAR_P (v))
   31043            1 :         error_at (loc, "%qD is not a variable", v);
   31044           88 :       else if (TREE_USED (v) && !C_DECL_THREADPRIVATE_P (v))
   31045            2 :         error_at (loc, "%qE declared %<threadprivate%> after first use", v);
   31046           86 :       else if (! is_global_var (v))
   31047            2 :         error_at (loc, "automatic variable %qE cannot be %<threadprivate%>", v);
   31048           84 :       else if (TREE_TYPE (v) == error_mark_node)
   31049              :         ;
   31050           83 :       else if (! COMPLETE_TYPE_P (TREE_TYPE (v)))
   31051            1 :         error_at (loc, "%<threadprivate%> %qE has incomplete type", v);
   31052              :       else
   31053              :         {
   31054           82 :           if (! DECL_THREAD_LOCAL_P (v))
   31055              :             {
   31056           82 :               set_decl_tls_model (v, decl_default_tls_model (v));
   31057              :               /* If rtl has been already set for this var, call
   31058              :                  make_decl_rtl once again, so that encode_section_info
   31059              :                  has a chance to look at the new decl flags.  */
   31060           82 :               if (DECL_RTL_SET_P (v))
   31061            0 :                 make_decl_rtl (v);
   31062              :             }
   31063           82 :           C_DECL_THREADPRIVATE_P (v) = 1;
   31064              :         }
   31065              :     }
   31066              : 
   31067           78 :   c_parser_skip_to_pragma_eol (parser);
   31068           78 : }
   31069              : 
   31070              : /* Parse a transaction attribute (GCC Extension).
   31071              : 
   31072              :    transaction-attribute:
   31073              :      gnu-attributes
   31074              :      attribute-specifier
   31075              : */
   31076              : 
   31077              : static tree
   31078          139 : c_parser_transaction_attributes (c_parser *parser)
   31079              : {
   31080          139 :   if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
   31081            0 :     return c_parser_gnu_attributes (parser);
   31082              : 
   31083          139 :   if (!c_parser_next_token_is (parser, CPP_OPEN_SQUARE))
   31084              :     return NULL_TREE;
   31085           20 :   return c_parser_std_attribute_specifier (parser, true);
   31086              : }
   31087              : 
   31088              : /* Parse a __transaction_atomic or __transaction_relaxed statement
   31089              :    (GCC Extension).
   31090              : 
   31091              :    transaction-statement:
   31092              :      __transaction_atomic transaction-attribute[opt] compound-statement
   31093              :      __transaction_relaxed compound-statement
   31094              : 
   31095              :    Note that the only valid attribute is: "outer".
   31096              : */
   31097              : 
   31098              : static tree
   31099          137 : c_parser_transaction (c_parser *parser, enum rid keyword)
   31100              : {
   31101          137 :   unsigned int old_in = parser->in_transaction;
   31102          137 :   unsigned int this_in = 1, new_in;
   31103          137 :   location_t loc = c_parser_peek_token (parser)->location;
   31104          137 :   tree stmt, attrs;
   31105              : 
   31106          274 :   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
   31107              :       || keyword == RID_TRANSACTION_RELAXED)
   31108              :       && c_parser_next_token_is_keyword (parser, keyword));
   31109          137 :   c_parser_consume_token (parser);
   31110              : 
   31111          137 :   if (keyword == RID_TRANSACTION_RELAXED)
   31112              :     this_in |= TM_STMT_ATTR_RELAXED;
   31113              :   else
   31114              :     {
   31115          106 :       attrs = c_parser_transaction_attributes (parser);
   31116          106 :       if (attrs)
   31117           14 :         this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
   31118              :     }
   31119              : 
   31120              :   /* Keep track if we're in the lexical scope of an outer transaction.  */
   31121          137 :   new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);
   31122              : 
   31123          137 :   parser->in_transaction = new_in;
   31124          137 :   stmt = c_parser_compound_statement (parser);
   31125          137 :   parser->in_transaction = old_in;
   31126              : 
   31127          137 :   if (flag_tm)
   31128          135 :     stmt = c_finish_transaction (loc, stmt, this_in);
   31129              :   else
   31130            2 :     error_at (loc,
   31131              :               keyword == RID_TRANSACTION_ATOMIC
   31132              :               ? G_("%<__transaction_atomic%> without transactional memory "
   31133              :                    "support enabled")
   31134              :               : G_("%<__transaction_relaxed%> without transactional memory "
   31135              :                    "support enabled"));
   31136              : 
   31137          137 :   return stmt;
   31138              : }
   31139              : 
   31140              : /* Parse a __transaction_atomic or __transaction_relaxed expression
   31141              :    (GCC Extension).
   31142              : 
   31143              :    transaction-expression:
   31144              :      __transaction_atomic ( expression )
   31145              :      __transaction_relaxed ( expression )
   31146              : */
   31147              : 
   31148              : static struct c_expr
   31149            7 : c_parser_transaction_expression (c_parser *parser, enum rid keyword)
   31150              : {
   31151            7 :   struct c_expr ret;
   31152            7 :   unsigned int old_in = parser->in_transaction;
   31153            7 :   unsigned int this_in = 1;
   31154            7 :   location_t loc = c_parser_peek_token (parser)->location;
   31155            7 :   tree attrs;
   31156              : 
   31157           14 :   gcc_assert ((keyword == RID_TRANSACTION_ATOMIC
   31158              :       || keyword == RID_TRANSACTION_RELAXED)
   31159              :       && c_parser_next_token_is_keyword (parser, keyword));
   31160            7 :   c_parser_consume_token (parser);
   31161              : 
   31162            7 :   if (keyword == RID_TRANSACTION_RELAXED)
   31163              :     this_in |= TM_STMT_ATTR_RELAXED;
   31164              :   else
   31165              :     {
   31166            5 :       attrs = c_parser_transaction_attributes (parser);
   31167            5 :       if (attrs)
   31168            0 :         this_in |= parse_tm_stmt_attr (attrs, 0);
   31169              :     }
   31170              : 
   31171            7 :   parser->in_transaction = this_in;
   31172            7 :   matching_parens parens;
   31173            7 :   if (parens.require_open (parser))
   31174              :     {
   31175            7 :       tree expr = c_parser_expression (parser).value;
   31176            7 :       ret.original_type = TREE_TYPE (expr);
   31177            7 :       ret.value = build1 (TRANSACTION_EXPR, ret.original_type, expr);
   31178            7 :       if (this_in & TM_STMT_ATTR_RELAXED)
   31179            2 :         TRANSACTION_EXPR_RELAXED (ret.value) = 1;
   31180            7 :       SET_EXPR_LOCATION (ret.value, loc);
   31181            7 :       ret.original_code = TRANSACTION_EXPR;
   31182            7 :       ret.m_decimal = 0;
   31183            7 :       if (!parens.require_close (parser))
   31184              :         {
   31185            0 :           c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
   31186            0 :           goto error;
   31187              :         }
   31188              :     }
   31189              :   else
   31190              :     {
   31191            0 :      error:
   31192            0 :       ret.set_error ();
   31193            0 :       ret.original_code = ERROR_MARK;
   31194            0 :       ret.original_type = NULL;
   31195              :     }
   31196            7 :   parser->in_transaction = old_in;
   31197              : 
   31198            7 :   if (!flag_tm)
   31199            6 :     error_at (loc,
   31200              :               keyword == RID_TRANSACTION_ATOMIC
   31201              :               ? G_("%<__transaction_atomic%> without transactional memory "
   31202              :                    "support enabled")
   31203              :               : G_("%<__transaction_relaxed%> without transactional memory "
   31204              :                    "support enabled"));
   31205              : 
   31206            7 :   set_c_expr_source_range (&ret, loc, loc);
   31207              : 
   31208            7 :   return ret;
   31209              : }
   31210              : 
   31211              : /* Parse a __transaction_cancel statement (GCC Extension).
   31212              : 
   31213              :    transaction-cancel-statement:
   31214              :      __transaction_cancel transaction-attribute[opt] ;
   31215              : 
   31216              :    Note that the only valid attribute is "outer".
   31217              : */
   31218              : 
   31219              : static tree
   31220           28 : c_parser_transaction_cancel (c_parser *parser)
   31221              : {
   31222           28 :   location_t loc = c_parser_peek_token (parser)->location;
   31223           28 :   tree attrs;
   31224           28 :   bool is_outer = false;
   31225              : 
   31226           28 :   gcc_assert (c_parser_next_token_is_keyword (parser, RID_TRANSACTION_CANCEL));
   31227           28 :   c_parser_consume_token (parser);
   31228              : 
   31229           28 :   attrs = c_parser_transaction_attributes (parser);
   31230           28 :   if (attrs)
   31231            5 :     is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);
   31232              : 
   31233           28 :   if (!flag_tm)
   31234              :     {
   31235            2 :       error_at (loc, "%<__transaction_cancel%> without "
   31236              :                 "transactional memory support enabled");
   31237            2 :       goto ret_error;
   31238              :     }
   31239           26 :   else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
   31240              :     {
   31241            0 :       error_at (loc, "%<__transaction_cancel%> within a "
   31242              :                 "%<__transaction_relaxed%>");
   31243            0 :       goto ret_error;
   31244              :     }
   31245           26 :   else if (is_outer)
   31246              :     {
   31247            5 :       if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
   31248            5 :           && !is_tm_may_cancel_outer (current_function_decl))
   31249              :         {
   31250            0 :           error_at (loc, "outer %<__transaction_cancel%> not "
   31251              :                     "within outer %<__transaction_atomic%> or "
   31252              :                     "a %<transaction_may_cancel_outer%> function");
   31253            0 :           goto ret_error;
   31254              :         }
   31255              :     }
   31256           21 :   else if (parser->in_transaction == 0)
   31257              :     {
   31258            0 :       error_at (loc, "%<__transaction_cancel%> not within "
   31259              :                 "%<__transaction_atomic%>");
   31260            0 :       goto ret_error;
   31261              :     }
   31262              : 
   31263           26 :   return add_stmt (build_tm_abort_call (loc, is_outer));
   31264              : 
   31265            2 :  ret_error:
   31266            2 :   return build1 (NOP_EXPR, void_type_node, error_mark_node);
   31267              : }
   31268              : 
   31269              : /* Parse a single source file.  */
   31270              : 
   31271              : void
   31272       105368 : c_parse_file (void)
   31273              : {
   31274              :   /* Use local storage to begin.  If the first token is a pragma, parse it.
   31275              :      If it is #pragma GCC pch_preprocess, then this will load a PCH file
   31276              :      which will cause garbage collection.  */
   31277       105368 :   c_parser tparser;
   31278              : 
   31279       105368 :   memset (&tparser, 0, sizeof tparser);
   31280       105368 :   tparser.translate_strings_p = true;
   31281       105368 :   tparser.tokens = &tparser.tokens_buf[0];
   31282       105368 :   the_parser = &tparser;
   31283              : 
   31284       105368 :   if (c_parser_peek_token (&tparser)->pragma_kind == PRAGMA_GCC_PCH_PREPROCESS)
   31285           12 :     c_parser_pragma_pch_preprocess (&tparser);
   31286              :   else
   31287       105284 :     c_common_no_more_pch ();
   31288              : 
   31289       105296 :   the_parser = ggc_alloc<c_parser> ();
   31290       105296 :   *the_parser = tparser;
   31291       105296 :   if (tparser.tokens == &tparser.tokens_buf[0])
   31292       105296 :     the_parser->tokens = &the_parser->tokens_buf[0];
   31293              : 
   31294              :   /* Initialize EH, if we've been told to do so.  */
   31295       105296 :   if (flag_exceptions)
   31296          511 :     using_eh_for_cleanups ();
   31297              : 
   31298       105296 :   c_parser_translation_unit (the_parser);
   31299       105206 :   the_parser = NULL;
   31300       105206 : }
   31301              : 
   31302              : void
   31303         5407 : c_init_preprocess (void)
   31304              : {
   31305              :   /* Create a parser for use by pragma_lex during preprocessing.  */
   31306         5407 :   the_parser = ggc_alloc<c_parser> ();
   31307         5407 :   memset (the_parser, 0, sizeof (c_parser));
   31308         5407 :   the_parser->tokens = &the_parser->tokens_buf[0];
   31309         5407 : }
   31310              : 
   31311              : /* Parse the body of a function declaration marked with "__RTL".
   31312              : 
   31313              :    The RTL parser works on the level of characters read from a
   31314              :    FILE *, whereas c_parser works at the level of tokens.
   31315              :    Square this circle by consuming all of the tokens up to and
   31316              :    including the closing brace, recording the start/end of the RTL
   31317              :    fragment, and reopening the file and re-reading the relevant
   31318              :    lines within the RTL parser.
   31319              : 
   31320              :    This requires the opening and closing braces of the C function
   31321              :    to be on separate lines from the RTL they wrap.
   31322              : 
   31323              :    Take ownership of START_WITH_PASS, if non-NULL.  */
   31324              : 
   31325              : location_t
   31326           25 : c_parser_parse_rtl_body (c_parser *parser, char *start_with_pass)
   31327              : {
   31328           25 :   if (!c_parser_require (parser, CPP_OPEN_BRACE, "expected %<{%>"))
   31329              :     {
   31330            0 :       free (start_with_pass);
   31331            0 :       return c_parser_peek_token (parser)->location;
   31332              :     }
   31333              : 
   31334           25 :   location_t start_loc = c_parser_peek_token (parser)->location;
   31335              : 
   31336              :   /* Consume all tokens, up to the closing brace, handling
   31337              :      matching pairs of braces in the rtl dump.  */
   31338           25 :   int num_open_braces = 1;
   31339        25239 :   while (1)
   31340              :     {
   31341        12632 :       switch (c_parser_peek_token (parser)->type)
   31342              :         {
   31343            1 :         case CPP_OPEN_BRACE:
   31344            1 :           num_open_braces++;
   31345            1 :           break;
   31346           25 :         case CPP_CLOSE_BRACE:
   31347           25 :           if (--num_open_braces == 0)
   31348           24 :             goto found_closing_brace;
   31349              :           break;
   31350            1 :         case CPP_EOF:
   31351            1 :           error_at (start_loc, "no closing brace");
   31352            1 :           free (start_with_pass);
   31353            1 :           return c_parser_peek_token (parser)->location;
   31354              :         default:
   31355              :           break;
   31356              :         }
   31357        12607 :       c_parser_consume_token (parser);
   31358              :     }
   31359              : 
   31360           24 :  found_closing_brace:
   31361              :   /* At the closing brace; record its location.  */
   31362           24 :   location_t end_loc = c_parser_peek_token (parser)->location;
   31363              : 
   31364              :   /* Consume the closing brace.  */
   31365           24 :   c_parser_consume_token (parser);
   31366              : 
   31367              :   /* Invoke the RTL parser.  */
   31368           24 :   if (!read_rtl_function_body_from_file_range (start_loc, end_loc))
   31369              :     {
   31370            0 :       free (start_with_pass);
   31371            0 :       return end_loc;
   31372              :     }
   31373              : 
   31374              :  /*  Run the backend on the cfun created above, transferring ownership of
   31375              :      START_WITH_PASS.  */
   31376           23 :   run_rtl_passes (start_with_pass);
   31377           23 :   return end_loc;
   31378              : }
   31379              : 
   31380              : #include "gt-c-c-parser.h"
        

Generated by: LCOV version 2.4-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.