/* -*- C++ -*- Parser.
   Copyright (C) 2000-2023 Free Software Foundation, Inc.
   Written by Mark Mitchell <mark@codesourcery.com>.

   This file is part of GCC.

   GCC is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   GCC is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "cp-tree.h"
#include "c-family/c-common.h"
#include "timevar.h"
#include "stringpool.h"
#include "cgraph.h"
#include "print-tree.h"
#include "attribs.h"
#include "trans-mem.h"
#include "intl.h"
#include "decl.h"
#include "c-family/c-objc.h"
#include "plugin.h"
#include "tree-pretty-print.h"
#include "parser.h"
#include "gomp-constants.h"
#include "omp-general.h"
#include "omp-offload.h"
#include "c-family/c-indentation.h"
#include "context.h"
#include "gcc-rich-location.h"
#include "tree-iterator.h"
#include "cp-name-hint.h"
#include "memmodel.h"
#include "c-family/known-headers.h"
#include "contracts.h"
#include "bitmap.h"


/* The lexer.  */

/* The cp_lexer_* routines mediate between the lexer proper (in libcpp
   and c-lex.cc) and the C++ parser.  */

/* The various kinds of non integral constant we encounter. */
enum non_integral_constant {
  NIC_NONE,
  /* floating-point literal */
  NIC_FLOAT,
  /* %<this%> */
  NIC_THIS,
  /* %<__FUNCTION__%> */
  NIC_FUNC_NAME,
  /* %<__PRETTY_FUNCTION__%> */
  NIC_PRETTY_FUNC,
  /* %<__func__%> */
  NIC_C99_FUNC,
  /* "%<va_arg%> */
  NIC_VA_ARG,
  /* a cast */
  NIC_CAST,
  /* %<typeid%> operator */
  NIC_TYPEID,
  /* non-constant compound literals */
  NIC_NCC,
  /* a function call */
  NIC_FUNC_CALL,
  /* an increment */
  NIC_INC,
  /* an decrement */
  NIC_DEC,
  /* an array reference */
  NIC_ARRAY_REF,
  /* %<->%> */
  NIC_ARROW,
  /* %<.%> */
  NIC_POINT,
  /* the address of a label */
  NIC_ADDR_LABEL,
  /* %<*%> */
  NIC_STAR,
  /* %<&%> */
  NIC_ADDR,
  /* %<++%> */
  NIC_PREINCREMENT,
  /* %<--%> */
  NIC_PREDECREMENT,
  /* %<new%> */
  NIC_NEW,
  /* %<delete%> */
  NIC_DEL,
  /* calls to overloaded operators */
  NIC_OVERLOADED,
  /* an assignment */
  NIC_ASSIGNMENT,
  /* a comma operator */
  NIC_COMMA,
  /* a call to a constructor */
  NIC_CONSTRUCTOR,
  /* a transaction expression */
  NIC_TRANSACTION
};

/* The various kinds of errors about name-lookup failing. */
enum name_lookup_error {
  /* NULL */
  NLE_NULL,
  /* is not a type */
  NLE_TYPE,
  /* is not a class or namespace */
  NLE_CXX98,
  /* is not a class, namespace, or enumeration */
  NLE_NOT_CXX98
};

/* The various kinds of required token */
enum required_token {
  RT_NONE,
  RT_SEMICOLON,  /* ';' */
  RT_OPEN_PAREN, /* '(' */
  RT_CLOSE_BRACE, /* '}' */
  RT_OPEN_BRACE,  /* '{' */
  RT_CLOSE_SQUARE, /* ']' */
  RT_OPEN_SQUARE,  /* '[' */
  RT_COMMA, /* ',' */
  RT_SCOPE, /* '::' */
  RT_LESS, /* '<' */
  RT_GREATER, /* '>' */
  RT_EQ, /* '=' */
  RT_ELLIPSIS, /* '...' */
  RT_MULT, /* '*' */
  RT_COMPL, /* '~' */
  RT_COLON, /* ':' */
  RT_COLON_SCOPE, /* ':' or '::' */
  RT_CLOSE_PAREN, /* ')' */
  RT_COMMA_CLOSE_PAREN, /* ',' or ')' */
  RT_PRAGMA_EOL, /* end of line */
  RT_NAME, /* identifier */

  /* The type is CPP_KEYWORD */
  RT_NEW, /* new */
  RT_DELETE, /* delete */
  RT_RETURN, /* return */
  RT_WHILE, /* while */
  RT_EXTERN, /* extern */
  RT_STATIC_ASSERT, /* static_assert */
  RT_DECLTYPE, /* decltype */
  RT_OPERATOR, /* operator */
  RT_CLASS, /* class */
  RT_TEMPLATE, /* template */
  RT_NAMESPACE, /* namespace */
  RT_USING, /* using */
  RT_ASM, /* asm */
  RT_TRY, /* try */
  RT_CATCH, /* catch */
  RT_THROW, /* throw */
  RT_AUTO, /* auto */
  RT_LABEL, /* __label__ */
  RT_AT_TRY, /* @try */
  RT_AT_SYNCHRONIZED, /* @synchronized */
  RT_AT_THROW, /* @throw */

  RT_SELECT,  /* selection-statement */
  RT_ITERATION, /* iteration-statement */
  RT_JUMP, /* jump-statement */
  RT_CLASS_KEY, /* class-key */
  RT_CLASS_TYPENAME_TEMPLATE, /* class, typename, or template */
  RT_TRANSACTION_ATOMIC, /* __transaction_atomic */
  RT_TRANSACTION_RELAXED, /* __transaction_relaxed */
  RT_TRANSACTION_CANCEL, /* __transaction_cancel */

  RT_CO_YIELD /* co_yield */
};

/* RAII wrapper for parser->in_type_id_in_expr_p, setting it on creation and
   reverting it on destruction.  */

class type_id_in_expr_sentinel
{
  cp_parser *parser;
  bool saved;
public:
  type_id_in_expr_sentinel (cp_parser *parser, bool set = true)
    : parser (parser),
      saved (parser->in_type_id_in_expr_p)
  { parser->in_type_id_in_expr_p = set; }
  ~type_id_in_expr_sentinel ()
  { parser->in_type_id_in_expr_p = saved; }
};

/* Prototypes.  */

static cp_lexer *cp_lexer_new_main
  (void);
static cp_lexer *cp_lexer_new_from_tokens
  (cp_token_cache *tokens);
static void cp_lexer_destroy
  (cp_lexer *);
static int cp_lexer_saving_tokens
  (const cp_lexer *);
static cp_token *cp_lexer_token_at
  (cp_lexer *, cp_token_position);
static void cp_lexer_get_preprocessor_token
  (unsigned, cp_token *);
static inline cp_token *cp_lexer_peek_token
  (cp_lexer *);
static cp_token *cp_lexer_peek_nth_token
  (cp_lexer *, size_t);
static inline bool cp_lexer_next_token_is
  (cp_lexer *, enum cpp_ttype);
static bool cp_lexer_next_token_is_not
  (cp_lexer *, enum cpp_ttype);
static bool cp_lexer_next_token_is_keyword
  (cp_lexer *, enum rid);
static cp_token *cp_lexer_consume_token
  (cp_lexer *);
static void cp_lexer_purge_token
  (cp_lexer *);
static void cp_lexer_purge_tokens_after
  (cp_lexer *, cp_token_position);
static void cp_lexer_save_tokens
  (cp_lexer *);
static void cp_lexer_commit_tokens
  (cp_lexer *);
static void cp_lexer_rollback_tokens
  (cp_lexer *);
static void cp_lexer_print_token
  (FILE *, cp_token *);
static inline bool cp_lexer_debugging_p
  (cp_lexer *);
static void cp_lexer_start_debugging
  (cp_lexer *) ATTRIBUTE_UNUSED;
static void cp_lexer_stop_debugging
  (cp_lexer *) ATTRIBUTE_UNUSED;

static cp_token_cache *cp_token_cache_new
  (cp_token *, cp_token *);
static tree cp_parser_late_noexcept_specifier
  (cp_parser *, tree);
static void noexcept_override_late_checks
  (tree, tree);

static void cp_parser_initial_pragma
  (cp_token *);

static bool cp_parser_omp_declare_reduction_exprs
  (tree, cp_parser *);
static void cp_finalize_oacc_routine
  (cp_parser *, tree, bool);

/* Manifest constants.  */
#define CP_LEXER_BUFFER_SIZE ((256 * 1024) / sizeof (cp_token))
#define CP_SAVED_TOKEN_STACK 5

/* Variables.  */

/* The stream to which debugging output should be written.  */
static FILE *cp_lexer_debug_stream;

/* Nonzero if we are parsing an unevaluated operand: an operand to
   sizeof, typeof, or alignof.  */
int cp_unevaluated_operand;

/* Dump up to NUM tokens in BUFFER to FILE starting with token
   START_TOKEN.  If START_TOKEN is NULL, the dump starts with the
   first token in BUFFER.  If NUM is 0, dump all the tokens.  If
   CURR_TOKEN is set and it is one of the tokens in BUFFER, it will be
   highlighted by surrounding it in [[ ]].  */

static void
cp_lexer_dump_tokens (FILE *file, vec<cp_token, va_gc> *buffer,
		      cp_token *start_token, unsigned num,
		      cp_token *curr_token)
{
  unsigned i, nprinted;
  cp_token *token;
  bool do_print;

  fprintf (file, "%u tokens\n", vec_safe_length (buffer));

  if (buffer == NULL)
    return;

  if (num == 0)
    num = buffer->length ();

  if (start_token == NULL)
    start_token = buffer->address ();

  if (start_token > buffer->address ())
    {
      cp_lexer_print_token (file, &(*buffer)[0]);
      fprintf (file, " ... ");
    }

  do_print = false;
  nprinted = 0;
  for (i = 0; buffer->iterate (i, &token) && nprinted < num; i++)
    {
      if (token == start_token)
	do_print = true;

      if (!do_print)
	continue;

      nprinted++;
      if (token == curr_token)
	fprintf (file, "[[");

      cp_lexer_print_token (file, token);

      if (token == curr_token)
	fprintf (file, "]]");

      switch (token->type)
	{
	  case CPP_SEMICOLON:
	  case CPP_OPEN_BRACE:
	  case CPP_CLOSE_BRACE:
	  case CPP_EOF:
	    fputc ('\n', file);
	    break;

	  default:
	    fputc (' ', file);
	}
    }

  if (i == num && i < buffer->length ())
    {
      fprintf (file, " ... ");
      cp_lexer_print_token (file, &buffer->last ());
    }

  fprintf (file, "\n");
}


/* Dump all tokens in BUFFER to stderr.  */

void
cp_lexer_debug_tokens (vec<cp_token, va_gc> *buffer)
{
  cp_lexer_dump_tokens (stderr, buffer, NULL, 0, NULL);
}

DEBUG_FUNCTION void
debug (vec<cp_token, va_gc> &ref)
{
  cp_lexer_dump_tokens (stderr, &ref, NULL, 0, NULL);
}

DEBUG_FUNCTION void
debug (vec<cp_token, va_gc> *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Dump the cp_parser tree field T to FILE if T is non-NULL.  DESC is the
   description for T.  */

static void
cp_debug_print_tree_if_set (FILE *file, const char *desc, tree t)
{
  if (t)
    {
      fprintf (file, "%s: ", desc);
      print_node_brief (file, "", t, 0);
    }
}


/* Dump parser context C to FILE.  */

static void
cp_debug_print_context (FILE *file, cp_parser_context *c)
{
  const char *status_s[] = { "OK", "ERROR", "COMMITTED" };
  fprintf (file, "{ status = %s, scope = ", status_s[c->status]);
  print_node_brief (file, "", c->object_type, 0);
  fprintf (file, "}\n");
}


/* Print the stack of parsing contexts to FILE starting with FIRST.  */

static void
cp_debug_print_context_stack (FILE *file, cp_parser_context *first)
{
  unsigned i;
  cp_parser_context *c;

  fprintf (file, "Parsing context stack:\n");
  for (i = 0, c = first; c; c = c->next, i++)
    {
      fprintf (file, "\t#%u: ", i);
      cp_debug_print_context (file, c);
    }
}


/* Print the value of FLAG to FILE.  DESC is a string describing the flag.  */

static void
cp_debug_print_flag (FILE *file, const char *desc, bool flag)
{
  if (flag)
    fprintf (file, "%s: true\n", desc);
}


/* Print an unparsed function entry UF to FILE.  */

static void
cp_debug_print_unparsed_function (FILE *file, cp_unparsed_functions_entry *uf)
{
  unsigned i;
  cp_default_arg_entry *default_arg_fn;
  tree fn;

  fprintf (file, "\tFunctions with default args:\n");
  for (i = 0;
       vec_safe_iterate (uf->funs_with_default_args, i, &default_arg_fn);
       i++)
    {
      fprintf (file, "\t\tClass type: ");
      print_node_brief (file, "", default_arg_fn->class_type, 0);
      fprintf (file, "\t\tDeclaration: ");
      print_node_brief (file, "", default_arg_fn->decl, 0);
      fprintf (file, "\n");
    }

  fprintf (file, "\n\tFunctions with definitions that require "
	   "post-processing\n\t\t");
  for (i = 0; vec_safe_iterate (uf->funs_with_definitions, i, &fn); i++)
    {
      print_node_brief (file, "", fn, 0);
      fprintf (file, " ");
    }
  fprintf (file, "\n");

  fprintf (file, "\n\tNon-static data members with initializers that require "
           "post-processing\n\t\t");
  for (i = 0; vec_safe_iterate (uf->nsdmis, i, &fn); i++)
    {
      print_node_brief (file, "", fn, 0);
      fprintf (file, " ");
    }
  fprintf (file, "\n");
}


/* Print the stack of unparsed member functions S to FILE.  */

static void
cp_debug_print_unparsed_queues (FILE *file,
				vec<cp_unparsed_functions_entry, va_gc> *s)
{
  unsigned i;
  cp_unparsed_functions_entry *uf;

  fprintf (file, "Unparsed functions\n");
  for (i = 0; vec_safe_iterate (s, i, &uf); i++)
    {
      fprintf (file, "#%u:\n", i);
      cp_debug_print_unparsed_function (file, uf);
    }
}


/* Dump the tokens in a window of size WINDOW_SIZE around the next_token for
   the given PARSER.  If FILE is NULL, the output is printed on stderr. */

static void
cp_debug_parser_tokens (FILE *file, cp_parser *parser, int window_size)
{
  cp_token *next_token, *first_token, *start_token;

  if (file == NULL)
    file = stderr;

  next_token = parser->lexer->next_token;
  first_token = parser->lexer->buffer->address ();
  start_token = (next_token > first_token + window_size / 2)
		? next_token - window_size / 2
		: first_token;
  cp_lexer_dump_tokens (file, parser->lexer->buffer, start_token, window_size,
			next_token);
}


/* Dump debugging information for the given PARSER.  If FILE is NULL,
   the output is printed on stderr.  */

void
cp_debug_parser (FILE *file, cp_parser *parser)
{
  const size_t window_size = 20;
  cp_token *token;
  expanded_location eloc;

  if (file == NULL)
    file = stderr;

  fprintf (file, "Parser state\n\n");
  fprintf (file, "Number of tokens: %u\n",
	   vec_safe_length (parser->lexer->buffer));
  cp_debug_print_tree_if_set (file, "Lookup scope", parser->scope);
  cp_debug_print_tree_if_set (file, "Object scope",
				     parser->object_scope);
  cp_debug_print_tree_if_set (file, "Qualifying scope",
				     parser->qualifying_scope);
  cp_debug_print_context_stack (file, parser->context);
  cp_debug_print_flag (file, "Allow GNU extensions",
			      parser->allow_gnu_extensions_p);
  cp_debug_print_flag (file, "'>' token is greater-than",
			      parser->greater_than_is_operator_p);
  cp_debug_print_flag (file, "Default args allowed in current "
			      "parameter list", parser->default_arg_ok_p);
  cp_debug_print_flag (file, "Parsing integral constant-expression",
			      parser->integral_constant_expression_p);
  cp_debug_print_flag (file, "Allow non-constant expression in current "
			      "constant-expression",
			      parser->allow_non_integral_constant_expression_p);
  cp_debug_print_flag (file, "Seen non-constant expression",
			      parser->non_integral_constant_expression_p);
  cp_debug_print_flag (file, "Local names forbidden in current context",
			      (parser->local_variables_forbidden_p
			       & LOCAL_VARS_FORBIDDEN));
  cp_debug_print_flag (file, "'this' forbidden in current context",
			      (parser->local_variables_forbidden_p
			       & THIS_FORBIDDEN));
  cp_debug_print_flag (file, "In unbraced linkage specification",
			      parser->in_unbraced_linkage_specification_p);
  cp_debug_print_flag (file, "Parsing a declarator",
			      parser->in_declarator_p);
  cp_debug_print_flag (file, "In template argument list",
			      parser->in_template_argument_list_p);
  cp_debug_print_flag (file, "Parsing an iteration statement",
			      parser->in_statement & IN_ITERATION_STMT);
  cp_debug_print_flag (file, "Parsing a switch statement",
			      parser->in_statement & IN_SWITCH_STMT);
  cp_debug_print_flag (file, "Parsing a structured OpenMP block",
			      parser->in_statement & IN_OMP_BLOCK);
  cp_debug_print_flag (file, "Parsing an OpenMP loop",
			      parser->in_statement & IN_OMP_FOR);
  cp_debug_print_flag (file, "Parsing an if statement",
			      parser->in_statement & IN_IF_STMT);
  cp_debug_print_flag (file, "Parsing a type-id in an expression "
			      "context", parser->in_type_id_in_expr_p);
  cp_debug_print_flag (file, "String expressions should be translated "
			      "to execution character set",
			      parser->translate_strings_p);
  cp_debug_print_flag (file, "Parsing function body outside of a "
			      "local class", parser->in_function_body);
  cp_debug_print_flag (file, "Auto correct a colon to a scope operator",
			      parser->colon_corrects_to_scope_p);
  cp_debug_print_flag (file, "Colon doesn't start a class definition",
			      parser->colon_doesnt_start_class_def_p);
  cp_debug_print_flag (file, "Parsing an Objective-C++ message context",
			      parser->objective_c_message_context_p);
  if (parser->type_definition_forbidden_message)
    fprintf (file, "Error message for forbidden type definitions: %s %s\n",
	     parser->type_definition_forbidden_message,
	     parser->type_definition_forbidden_message_arg
	     ? parser->type_definition_forbidden_message_arg : "<none>");
  cp_debug_print_unparsed_queues (file, parser->unparsed_queues);
  fprintf (file, "Number of class definitions in progress: %u\n",
	   parser->num_classes_being_defined);
  fprintf (file, "Number of template parameter lists for the current "
	   "declaration: %u\n", parser->num_template_parameter_lists);
  cp_debug_parser_tokens (file, parser, window_size);
  token = parser->lexer->next_token;
  fprintf (file, "Next token to parse:\n");
  fprintf (file, "\tToken:  ");
  cp_lexer_print_token (file, token);
  eloc = expand_location (token->location);
  fprintf (file, "\n\tFile:   %s\n", eloc.file);
  fprintf (file, "\tLine:   %d\n", eloc.line);
  fprintf (file, "\tColumn: %d\n", eloc.column);
}

DEBUG_FUNCTION void
debug (cp_parser &ref)
{
  cp_debug_parser (stderr, &ref);
}

DEBUG_FUNCTION void
debug (cp_parser *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}

/* Allocate memory for a new lexer object and return it.  */

static cp_lexer *
cp_lexer_alloc (void)
{
  /* Allocate the memory.  */
  cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> ();

  /* Initially we are not debugging.  */
  lexer->debugging_p = false;

  lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);

  /* Create the buffer.  */
  vec_alloc (lexer->buffer, CP_LEXER_BUFFER_SIZE);

  return lexer;
}

/* Return TRUE if token is the start of a module declaration that will be
   terminated by a CPP_PRAGMA_EOL token.  */
static inline bool
cp_token_is_module_directive (cp_token *token)
{
  return token->keyword == RID__EXPORT
    || token->keyword == RID__MODULE
    || token->keyword == RID__IMPORT;
}

/* Return TOKEN's pragma_kind if it is CPP_PRAGMA, otherwise
   PRAGMA_NONE.  */

static enum pragma_kind
cp_parser_pragma_kind (cp_token *token)
{
  if (token->type != CPP_PRAGMA)
    return PRAGMA_NONE;
  /* We smuggled the cpp_token->u.pragma value in an INTEGER_CST.  */
  return (enum pragma_kind) TREE_INT_CST_LOW (token->u.value);
}

/* Handle early pragmas such as #pragma GCC diagnostic, which needs to be done
   during preprocessing for the case of preprocessing-related diagnostics.  This
   is called immediately after pushing the CPP_PRAGMA_EOL token onto
   lexer->buffer.  */

static void
cp_lexer_handle_early_pragma (cp_lexer *lexer)
{
  const auto first_token = lexer->buffer->address ();
  const auto last_token = first_token + lexer->buffer->length () - 1;

  /* Back up to the start of the pragma so pragma_lex () can parse it when
     c-pragma lib asks it to.  */
  auto begin = last_token;
  gcc_assert (begin->type == CPP_PRAGMA_EOL);
  while (begin->type != CPP_PRAGMA)
    {
      if (cp_token_is_module_directive (begin))
	return;
      gcc_assert (begin != first_token);
      --begin;
    }
  gcc_assert (!lexer->next_token);
  gcc_assert (!lexer->last_token);
  lexer->next_token = begin;
  lexer->last_token = last_token;

  /* Dispatch it.  */
  const unsigned int id
    = cp_parser_pragma_kind (cp_lexer_consume_token (lexer));
  if (id >= PRAGMA_FIRST_EXTERNAL)
    c_invoke_early_pragma_handler (id);

  /* Reset to normal state.  */
  lexer->next_token = lexer->last_token = nullptr;
}

/* The parser.  */
static cp_parser *cp_parser_new (cp_lexer *);
static GTY (()) cp_parser *the_parser;

/* Create a new main C++ lexer, the lexer that gets tokens from the
   preprocessor, and also create the main parser.  */

static cp_lexer *
cp_lexer_new_main (void)
{
  cp_token token;

  /* It's possible that parsing the first pragma will load a PCH file,
     which is a GC collection point.  So we have to do that before
     allocating any memory.  */
  cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, &token);
  cp_parser_initial_pragma (&token);
  c_common_no_more_pch ();

  cp_lexer *lexer = cp_lexer_alloc ();
  /* Put the first token in the buffer.  */
  cp_token *tok = lexer->buffer->quick_push (token);

  uintptr_t filter = 0;
  if (modules_p ())
    filter = module_token_cdtor (parse_in, filter);

  /* Create the parser now, so we can use it to handle early pragmas.  */
  gcc_assert (!the_parser);
  the_parser = cp_parser_new (lexer);

  /* Get the remaining tokens from the preprocessor.  */
  while (tok->type != CPP_EOF)
    {
      if (filter)
	/* Process the previous token.  */
	module_token_lang (tok->type, tok->keyword, tok->u.value,
			   tok->location, filter);

      /* Check for early pragmas that need to be handled now.  */
      if (tok->type == CPP_PRAGMA_EOL)
	cp_lexer_handle_early_pragma (lexer);

      tok = vec_safe_push (lexer->buffer, cp_token ());
      cp_lexer_get_preprocessor_token (C_LEX_STRING_NO_JOIN, tok);
    }

  lexer->next_token = lexer->buffer->address ();
  lexer->last_token = lexer->next_token
                      + lexer->buffer->length ()
		      - 1;

  if (lexer->buffer->length () != 1)
    {
      /* Set the EOF token's location to be the just after the previous
         token's range.  That way 'at-eof' diagnostics point at something
	 meaninful.  */
      auto range = get_range_from_loc (line_table, tok[-1].location);
      tok[0].location
	= linemap_position_for_loc_and_offset (line_table, range.m_finish, 1);
    }

  if (filter)
    module_token_cdtor (parse_in, filter);

  /* Subsequent preprocessor diagnostics should use compiler
     diagnostic functions to get the compiler source location.  */
  override_libcpp_locations = true;

  maybe_check_all_macros (parse_in);

  gcc_assert (!lexer->next_token->purged_p);
  return lexer;
}

/* Create a new lexer whose token stream is primed with the tokens in
   CACHE.  When these tokens are exhausted, no new tokens will be read.  */

static cp_lexer *
cp_lexer_new_from_tokens (cp_token_cache *cache)
{
  cp_token *first = cache->first;
  cp_token *last = cache->last;
  cp_lexer *lexer = ggc_cleared_alloc<cp_lexer> ();

  /* We do not own the buffer.  */
  lexer->buffer = NULL;

  /* Insert an EOF token.  */
  lexer->saved_type = last->type;
  lexer->saved_keyword = last->keyword;
  last->type = CPP_EOF;
  last->keyword = RID_MAX;

  lexer->next_token = first;
  lexer->last_token = last;

  lexer->saved_tokens.create (CP_SAVED_TOKEN_STACK);

  /* Initially we are not debugging.  */
  lexer->debugging_p = false;

  gcc_assert (!lexer->next_token->purged_p
	      && !lexer->last_token->purged_p);
  return lexer;
}

/* Frees all resources associated with LEXER.  */

static void
cp_lexer_destroy (cp_lexer *lexer)
{
  if (lexer->buffer)
    vec_free (lexer->buffer);
  else
    {
      /* Restore the token we overwrite with EOF.  */
      lexer->last_token->type = lexer->saved_type;
      lexer->last_token->keyword = lexer->saved_keyword;
    }
  lexer->saved_tokens.release ();
  ggc_free (lexer);
}

/* This needs to be set to TRUE before the lexer-debugging infrastructure can
   be used.  The point of this flag is to help the compiler to fold away calls
   to cp_lexer_debugging_p within this source file at compile time, when the
   lexer is not being debugged.  */

#define LEXER_DEBUGGING_ENABLED_P false

/* Returns nonzero if debugging information should be output.  */

static inline bool
cp_lexer_debugging_p (cp_lexer *lexer)
{
  if (!LEXER_DEBUGGING_ENABLED_P)
    return false;

  return lexer->debugging_p;
}


static inline cp_token_position
cp_lexer_token_position (cp_lexer *lexer, bool previous_p)
{
  return lexer->next_token - previous_p;
}

static inline cp_token *
cp_lexer_token_at (cp_lexer * /*lexer*/, cp_token_position pos)
{
  return pos;
}

static inline void
cp_lexer_set_token_position (cp_lexer *lexer, cp_token_position pos)
{
  lexer->next_token = cp_lexer_token_at (lexer, pos);
}

static inline cp_token_position
cp_lexer_previous_token_position (cp_lexer *lexer)
{
  return cp_lexer_token_position (lexer, true);
}

static inline cp_token *
cp_lexer_previous_token (cp_lexer *lexer)
{
  cp_token_position tp = cp_lexer_previous_token_position (lexer);

  /* Skip past purged tokens.  */
  while (tp->purged_p)
    {
      gcc_assert (tp != vec_safe_address (lexer->buffer));
      tp--;
    }

  return cp_lexer_token_at (lexer, tp);
}

/* Same as above, but return NULL when the lexer doesn't own the token
   buffer or if the next_token is at the start of the token
   vector or if all previous tokens are purged.  */

static cp_token *
cp_lexer_safe_previous_token (cp_lexer *lexer)
{
  if (lexer->buffer
      && lexer->next_token != lexer->buffer->address ())
    {
      cp_token_position tp = cp_lexer_previous_token_position (lexer);

      /* Skip past purged tokens.  */
      while (tp->purged_p)
	{
	  if (tp == lexer->buffer->address ())
	    return NULL;
	  tp--;
	}
      return cp_lexer_token_at (lexer, tp);
    }

  return NULL;
}

/* Overload for make_location, taking the lexer to mean the location of the
   previous token.  */

static inline location_t
make_location (location_t caret, location_t start, cp_lexer *lexer)
{
  cp_token *t = cp_lexer_previous_token (lexer);
  return make_location (caret, start, t->location);
}

/* Overload for make_location taking tokens instead of locations.  */

static inline location_t
make_location (cp_token *caret, cp_token *start, cp_token *end)
{
  return make_location (caret->location, start->location, end->location);
}

/* nonzero if we are presently saving tokens.  */

static inline int
cp_lexer_saving_tokens (const cp_lexer* lexer)
{
  return lexer->saved_tokens.length () != 0;
}

/* Store the next token from the preprocessor in *TOKEN.  Return true
   if we reach EOF.  If LEXER is NULL, assume we are handling an
   initial #pragma pch_preprocess, and thus want the lexer to return
   processed strings.

   Diagnostics issued from this function must have their controlling option (if
   any) in c.opt annotated as a libcpp option via the CppReason property.  */

static void
cp_lexer_get_preprocessor_token (unsigned flags, cp_token *token)
{
  static int is_extern_c = 0;

   /* Get a new token from the preprocessor.  */
  token->type
    = c_lex_with_flags (&token->u.value, &token->location, &token->flags,
			flags);
  token->keyword = RID_MAX;
  token->purged_p = false;
  token->error_reported = false;
  token->tree_check_p = false;
  /* Usually never see a zero, but just in case ... */
  token->main_source_p = line_table->depth <= 1;

  /* On some systems, some header files are surrounded by an
     implicit extern "C" block.  Set a flag in the token if it
     comes from such a header.  */
  is_extern_c += pending_lang_change;
  pending_lang_change = 0;
  token->implicit_extern_c = is_extern_c > 0;

  /* Check to see if this token is a keyword.  */
  if (token->type == CPP_NAME)
    {
      if (IDENTIFIER_KEYWORD_P (token->u.value))
	{
	  /* Mark this token as a keyword.  */
	  token->type = CPP_KEYWORD;
	  /* Record which keyword.  */
	  token->keyword = C_RID_CODE (token->u.value);
	}
      else
	{
          if (warn_cxx11_compat
	      && ((C_RID_CODE (token->u.value) >= RID_FIRST_CXX11
		   && C_RID_CODE (token->u.value) <= RID_LAST_CXX11)
		  /* These are outside the CXX11 range.  */
		  || C_RID_CODE (token->u.value) == RID_ALIGNOF
		  || C_RID_CODE (token->u.value) == RID_ALIGNAS
		  || C_RID_CODE (token->u.value)== RID_THREAD))
            {
	      /* Warn about the C++11 keyword (but still treat it as
                 an identifier).  */
	      warning_at (token->location, OPT_Wc__11_compat,
			  "identifier %qE is a keyword in C++11",
			  token->u.value);

              /* Clear out the C_RID_CODE so we don't warn about this
                 particular identifier-turned-keyword again.  */
              C_SET_RID_CODE (token->u.value, RID_MAX);
            }
	  if (warn_cxx20_compat
	      && C_RID_CODE (token->u.value) >= RID_FIRST_CXX20
	      && C_RID_CODE (token->u.value) <= RID_LAST_CXX20)
	    {
	      /* Warn about the C++20 keyword (but still treat it as
		 an identifier).  */
	      warning_at (token->location, OPT_Wc__20_compat,
			  "identifier %qE is a keyword in C++20",
			  token->u.value);

	      /* Clear out the C_RID_CODE so we don't warn about this
		 particular identifier-turned-keyword again.  */
	      C_SET_RID_CODE (token->u.value, RID_MAX);
	    }

	  token->keyword = RID_MAX;
	}
    }
  else if (token->type == CPP_AT_NAME)
    {
      /* This only happens in Objective-C++; it must be a keyword.  */
      token->type = CPP_KEYWORD;
      switch (C_RID_CODE (token->u.value))
	{
	  /* Replace 'class' with '@class', 'private' with '@private',
	     etc.  This prevents confusion with the C++ keyword
	     'class', and makes the tokens consistent with other
	     Objective-C 'AT' keywords.  For example '@class' is
	     reported as RID_AT_CLASS which is consistent with
	     '@synchronized', which is reported as
	     RID_AT_SYNCHRONIZED.
	  */
	case RID_CLASS:     token->keyword = RID_AT_CLASS; break;
	case RID_PRIVATE:   token->keyword = RID_AT_PRIVATE; break;
	case RID_PROTECTED: token->keyword = RID_AT_PROTECTED; break;
	case RID_PUBLIC:    token->keyword = RID_AT_PUBLIC; break;
	case RID_THROW:     token->keyword = RID_AT_THROW; break;
	case RID_TRY:       token->keyword = RID_AT_TRY; break;
	case RID_CATCH:     token->keyword = RID_AT_CATCH; break;
	case RID_SYNCHRONIZED: token->keyword = RID_AT_SYNCHRONIZED; break;
	default:            token->keyword = C_RID_CODE (token->u.value);
	}
    }
}

/* Update the globals input_location and the input file stack from TOKEN.  */
static inline void
cp_lexer_set_source_position_from_token (cp_token *token)
{
  input_location = token->location;
}

/* Update the globals input_location and the input file stack from LEXER.  */
static inline void
cp_lexer_set_source_position (cp_lexer *lexer)
{
  cp_token *token = cp_lexer_peek_token (lexer);
  cp_lexer_set_source_position_from_token (token);
}

/* Return a pointer to the next token in the token stream, but do not
   consume it.  */

static inline cp_token *
cp_lexer_peek_token (cp_lexer *lexer)
{
  if (cp_lexer_debugging_p (lexer))
    {
      fputs ("cp_lexer: peeking at token: ", cp_lexer_debug_stream);
      cp_lexer_print_token (cp_lexer_debug_stream, lexer->next_token);
      putc ('\n', cp_lexer_debug_stream);
    }
  return lexer->next_token;
}

/* Return true if the next token has the indicated TYPE.  */

static inline bool
cp_lexer_next_token_is (cp_lexer* lexer, enum cpp_ttype type)
{
  return cp_lexer_peek_token (lexer)->type == type;
}

/* Return true if the next token does not have the indicated TYPE.  */

static inline bool
cp_lexer_next_token_is_not (cp_lexer* lexer, enum cpp_ttype type)
{
  return !cp_lexer_next_token_is (lexer, type);
}

/* Return true if the next token is the indicated KEYWORD.  */

static inline bool
cp_lexer_next_token_is_keyword (cp_lexer* lexer, enum rid keyword)
{
  return cp_lexer_peek_token (lexer)->keyword == keyword;
}

static inline bool
cp_lexer_nth_token_is (cp_lexer* lexer, size_t n, enum cpp_ttype type)
{
  return cp_lexer_peek_nth_token (lexer, n)->type == type;
}

static inline bool
cp_lexer_nth_token_is_keyword (cp_lexer* lexer, size_t n, enum rid keyword)
{
  return cp_lexer_peek_nth_token (lexer, n)->keyword == keyword;
}

/* Return true if KEYWORD can start a decl-specifier.  */

bool
cp_keyword_starts_decl_specifier_p (enum rid keyword)
{
  switch (keyword)
    {
      /* auto specifier: storage-class-specifier in C++,
         simple-type-specifier in C++0x.  */
    case RID_AUTO:
      /* Storage classes.  */
    case RID_REGISTER:
    case RID_STATIC:
    case RID_EXTERN:
    case RID_MUTABLE:
    case RID_THREAD:
      /* Elaborated type specifiers.  */
    case RID_ENUM:
    case RID_CLASS:
    case RID_STRUCT:
    case RID_UNION:
    case RID_TYPENAME:
      /* Simple type specifiers.  */
    case RID_CHAR:
    case RID_CHAR8:
    case RID_CHAR16:
    case RID_CHAR32:
    case RID_WCHAR:
    case RID_BOOL:
    case RID_SHORT:
    case RID_INT:
    case RID_LONG:
    case RID_SIGNED:
    case RID_UNSIGNED:
    case RID_FLOAT:
    case RID_DOUBLE:
    CASE_RID_FLOATN_NX:
    case RID_VOID:
      /* CV qualifiers.  */
    case RID_CONST:
    case RID_VOLATILE:
      /* Function specifiers.  */
    case RID_EXPLICIT:
    case RID_VIRTUAL:
      /* friend/typdef/inline specifiers.  */
    case RID_FRIEND:
    case RID_TYPEDEF:
    case RID_INLINE:
      /* GNU extensions.  */
    case RID_TYPEOF:
      /* C++11 extensions.  */
    case RID_DECLTYPE:
    case RID_CONSTEXPR:
      /* C++20 extensions.  */
    case RID_CONSTINIT:
    case RID_CONSTEVAL:
      return true;

#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
    case RID_##CODE:
#include "cp-trait.def"
#undef DEFTRAIT_TYPE
      return true;

    default:
      if (keyword >= RID_FIRST_INT_N
	  && keyword < RID_FIRST_INT_N + NUM_INT_N_ENTS
	  && int_n_enabled_p[keyword - RID_FIRST_INT_N])
	return true;
      return false;
    }
}

/* Return true if the next token is a keyword for a decl-specifier.  */

static bool
cp_lexer_next_token_is_decl_specifier_keyword (cp_lexer *lexer)
{
  cp_token *token;

  token = cp_lexer_peek_token (lexer);
  return cp_keyword_starts_decl_specifier_p (token->keyword);
}

/* Returns TRUE iff the token T begins a decltype type.  */

static bool
token_is_decltype (cp_token *t)
{
  return (t->keyword == RID_DECLTYPE
	  || t->type == CPP_DECLTYPE);
}

/* Returns TRUE iff the next token begins a decltype type.  */

static bool
cp_lexer_next_token_is_decltype (cp_lexer *lexer)
{
  cp_token *t = cp_lexer_peek_token (lexer);
  return token_is_decltype (t);
}

/* Called when processing a token with tree_check_value; perform or defer the
   associated checks and return the value.  */

static tree
saved_checks_value (struct tree_check *check_value)
{
  /* Perform any access checks that were deferred.  */
  vec<deferred_access_check, va_gc> *checks;
  deferred_access_check *chk;
  checks = check_value->checks;
  if (checks)
    {
      int i;
      FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
	perform_or_defer_access_check (chk->binfo,
				       chk->decl,
				       chk->diag_decl, tf_warning_or_error);
    }
  /* Return the stored value.  */
  return check_value->value;
}

/* Return a pointer to the Nth token in the token stream.  If N is 1,
   then this is precisely equivalent to cp_lexer_peek_token (except
   that it is not inline).  One would like to disallow that case, but
   there is one case (cp_parser_nth_token_starts_template_id) where
   the caller passes a variable for N and it might be 1.  */

static cp_token *
cp_lexer_peek_nth_token (cp_lexer* lexer, size_t n)
{
  cp_token *token;

  /* N is 1-based, not zero-based.  */
  gcc_assert (n > 0);

  if (cp_lexer_debugging_p (lexer))
    fprintf (cp_lexer_debug_stream,
	     "cp_lexer: peeking ahead %ld at token: ", (long)n);

  --n;
  token = lexer->next_token;
  while (n && token->type != CPP_EOF)
    {
      ++token;
      if (!token->purged_p)
	--n;
    }

  if (cp_lexer_debugging_p (lexer))
    {
      cp_lexer_print_token (cp_lexer_debug_stream, token);
      putc ('\n', cp_lexer_debug_stream);
    }

  return token;
}

/* Return the next token, and advance the lexer's next_token pointer
   to point to the next non-purged token.  */

static cp_token *
cp_lexer_consume_token (cp_lexer* lexer)
{
  cp_token *token = lexer->next_token;

  do
    {
      gcc_assert (token->type != CPP_EOF);
      lexer->next_token++;
    }
  while (lexer->next_token->purged_p);

  cp_lexer_set_source_position_from_token (token);

  /* Provide debugging output.  */
  if (cp_lexer_debugging_p (lexer))
    {
      fputs ("cp_lexer: consuming token: ", cp_lexer_debug_stream);
      cp_lexer_print_token (cp_lexer_debug_stream, token);
      putc ('\n', cp_lexer_debug_stream);
    }

  return token;
}

/* Permanently remove the next token from the token stream, and
   advance the next_token pointer to refer to the next non-purged
   token.  */

static void
cp_lexer_purge_token (cp_lexer *lexer)
{
  cp_token *tok = lexer->next_token;

  gcc_assert (tok->type != CPP_EOF);
  tok->purged_p = true;
  tok->location = UNKNOWN_LOCATION;
  tok->u.value = NULL_TREE;
  tok->keyword = RID_MAX;

  do
    tok++;
  while (tok->purged_p);
  lexer->next_token = tok;
}

/* Permanently remove all tokens after TOK, up to, but not
   including, the token that will be returned next by
   cp_lexer_peek_token.  */

static void
cp_lexer_purge_tokens_after (cp_lexer *lexer, cp_token *tok)
{
  cp_token *peek = lexer->next_token;

  gcc_assert (tok < peek);

  for (tok++; tok != peek; tok++)
    {
      tok->purged_p = true;
      tok->location = UNKNOWN_LOCATION;
      tok->u.value = NULL_TREE;
      tok->keyword = RID_MAX;
    }
}

/* Begin saving tokens.  All tokens consumed after this point will be
   preserved.  */

static void
cp_lexer_save_tokens (cp_lexer* lexer)
{
  /* Provide debugging output.  */
  if (cp_lexer_debugging_p (lexer))
    fprintf (cp_lexer_debug_stream, "cp_lexer: saving tokens\n");

  lexer->saved_tokens.safe_push (lexer->next_token);
}

/* Commit to the portion of the token stream most recently saved.  */

static void
cp_lexer_commit_tokens (cp_lexer* lexer)
{
  /* Provide debugging output.  */
  if (cp_lexer_debugging_p (lexer))
    fprintf (cp_lexer_debug_stream, "cp_lexer: committing tokens\n");

  lexer->saved_tokens.pop ();
}

/* Return all tokens saved since the last call to cp_lexer_save_tokens
   to the token stream.  Stop saving tokens.  */

static void
cp_lexer_rollback_tokens (cp_lexer* lexer)
{
  /* Provide debugging output.  */
  if (cp_lexer_debugging_p (lexer))
    fprintf (cp_lexer_debug_stream, "cp_lexer: restoring tokens\n");

  lexer->next_token = lexer->saved_tokens.pop ();
}

/* Determines what saved_token_sentinel does when going out of scope.  */

enum saved_token_sentinel_mode {
  STS_COMMIT,
  STS_ROLLBACK,
  STS_DONOTHING
};

/* RAII wrapper around the above functions, with sanity checking (the token
   stream should be the same at the point of instantiation as it is at the
   point of destruction).

   Creating a variable saves tokens.  MODE determines what happens when the
   object is destroyed.  STS_COMMIT commits tokens (default),
   STS_ROLLBACK rolls-back and STS_DONOTHING does nothing.  Calling
   rollback() will immediately roll-back tokens and set MODE to
   STS_DONOTHING.  */

struct saved_token_sentinel
{
  cp_lexer *lexer;
  unsigned len;
  saved_token_sentinel_mode mode;
  saved_token_sentinel (cp_lexer *_lexer,
			saved_token_sentinel_mode _mode = STS_COMMIT)
    : lexer (_lexer), mode (_mode)
  {
    len = lexer->saved_tokens.length ();
    cp_lexer_save_tokens (lexer);
  }
  void rollback ()
  {
    cp_lexer_rollback_tokens (lexer);
    cp_lexer_set_source_position_from_token
      (cp_lexer_previous_token (lexer));
    mode = STS_DONOTHING;
  }
  ~saved_token_sentinel ()
  {
    if (mode == STS_COMMIT)
      cp_lexer_commit_tokens (lexer);
    else if (mode == STS_ROLLBACK)
      rollback ();

    gcc_assert (lexer->saved_tokens.length () == len);
  }
};

/* Print a representation of the TOKEN on the STREAM.  */

static void
cp_lexer_print_token (FILE * stream, cp_token *token)
{
  /* We don't use cpp_type2name here because the parser defines
     a few tokens of its own.  */
  static const char *const token_names[] = {
    /* cpplib-defined token types */
#define OP(e, s) #e,
#define TK(e, s) #e,
    TTYPE_TABLE
#undef OP
#undef TK
    /* C++ parser token types - see "Manifest constants", above.  */
    "KEYWORD",
    "TEMPLATE_ID",
    "NESTED_NAME_SPECIFIER",
  };

  /* For some tokens, print the associated data.  */
  switch (token->type)
    {
    case CPP_KEYWORD:
      /* Some keywords have a value that is not an IDENTIFIER_NODE.
	 For example, `struct' is mapped to an INTEGER_CST.  */
      if (!identifier_p (token->u.value))
	break;
      /* fall through */
    case CPP_NAME:
      fputs (IDENTIFIER_POINTER (token->u.value), stream);
      break;

    case CPP_STRING:
    case CPP_STRING16:
    case CPP_STRING32:
    case CPP_WSTRING:
    case CPP_UTF8STRING:
      fprintf (stream, " \"%s\"", TREE_STRING_POINTER (token->u.value));
      break;

    case CPP_NUMBER:
      print_generic_expr (stream, token->u.value);
      break;

    default:
      /* If we have a name for the token, print it out.  Otherwise, we
	 simply give the numeric code.  */
      if (token->type < ARRAY_SIZE(token_names))
	fputs (token_names[token->type], stream);
      else
	fprintf (stream, "[%d]", token->type);
      break;
    }
}

DEBUG_FUNCTION void
debug (cp_token &ref)
{
  cp_lexer_print_token (stderr, &ref);
  fprintf (stderr, "\n");
}

DEBUG_FUNCTION void
debug (cp_token *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Start emitting debugging information.  */

static void
cp_lexer_start_debugging (cp_lexer* lexer)
{
  if (!LEXER_DEBUGGING_ENABLED_P)
    fatal_error (input_location,
		 "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true");

  lexer->debugging_p = true;
  cp_lexer_debug_stream = stderr;
}

/* Stop emitting debugging information.  */

static void
cp_lexer_stop_debugging (cp_lexer* lexer)
{
  if (!LEXER_DEBUGGING_ENABLED_P)
    fatal_error (input_location,
		 "%<LEXER_DEBUGGING_ENABLED_P%> is not set to true");

  lexer->debugging_p = false;
  cp_lexer_debug_stream = NULL;
}

/* Create a new cp_token_cache, representing a range of tokens.  */

static cp_token_cache *
cp_token_cache_new (cp_token *first, cp_token *last)
{
  cp_token_cache *cache = ggc_alloc<cp_token_cache> ();
  cache->first = first;
  cache->last = last;
  return cache;
}

/* Diagnose if #pragma omp declare simd isn't followed immediately
   by function declaration or definition.  */

static inline void
cp_ensure_no_omp_declare_simd (cp_parser *parser)
{
  if (parser->omp_declare_simd && !parser->omp_declare_simd->error_seen)
    {
      error ("%<#pragma omp declare %s%> not immediately followed by "
	     "function declaration or definition",
	     parser->omp_declare_simd->variant_p ? "variant" : "simd");
      parser->omp_declare_simd = NULL;
    }
}

/* Finalize #pragma omp declare simd clauses after FNDECL has been parsed,
   and put that into "omp declare simd" attribute.  */

static inline void
cp_finalize_omp_declare_simd (cp_parser *parser, tree fndecl)
{
  if (UNLIKELY (parser->omp_declare_simd != NULL))
    {
      if (fndecl == error_mark_node)
	{
	  parser->omp_declare_simd = NULL;
	  return;
	}
      if (TREE_CODE (fndecl) != FUNCTION_DECL)
	{
	  cp_ensure_no_omp_declare_simd (parser);
	  return;
	}
    }
}

/* Similarly, but for use in declaration parsing functions
   which call cp_parser_handle_directive_omp_attributes.  */

static inline void
cp_finalize_omp_declare_simd (cp_parser *parser, cp_omp_declare_simd_data *data)
{
  if (parser->omp_declare_simd != data)
    return;

  if (!parser->omp_declare_simd->error_seen
      && !parser->omp_declare_simd->fndecl_seen)
    error_at (parser->omp_declare_simd->loc,
	      "%<declare %s%> directive not immediately followed by "
	      "function declaration or definition",
	      parser->omp_declare_simd->variant_p ? "variant" : "simd");
  parser->omp_declare_simd = NULL;
}

/* Diagnose if #pragma acc routine isn't followed immediately by function
   declaration or definition.  */

static inline void
cp_ensure_no_oacc_routine (cp_parser *parser)
{
  if (parser->oacc_routine && !parser->oacc_routine->error_seen)
    {
      error_at (parser->oacc_routine->loc,
		"%<#pragma acc routine%> not immediately followed by "
		"function declaration or definition");
      parser->oacc_routine = NULL;
    }
}

/* Decl-specifiers.  */

/* Set *DECL_SPECS to represent an empty decl-specifier-seq.  */

static void
clear_decl_specs (cp_decl_specifier_seq *decl_specs)
{
  memset (decl_specs, 0, sizeof (cp_decl_specifier_seq));
}

/* Declarators.  */

/* Nothing other than the parser should be creating declarators;
   declarators are a semi-syntactic representation of C++ entities.
   Other parts of the front end that need to create entities (like
   VAR_DECLs or FUNCTION_DECLs) should do that directly.  */

static cp_declarator *make_call_declarator
  (cp_declarator *, tree, cp_cv_quals, cp_virt_specifiers, cp_ref_qualifier,
   tree, tree, tree, tree, tree, location_t);
static cp_declarator *make_array_declarator
  (cp_declarator *, tree);
static cp_declarator *make_pointer_declarator
  (cp_cv_quals, cp_declarator *, tree);
static cp_declarator *make_reference_declarator
  (cp_cv_quals, cp_declarator *, bool, tree);
static cp_declarator *make_ptrmem_declarator
  (cp_cv_quals, tree, cp_declarator *, tree);

/* An erroneous declarator.  */
static cp_declarator *cp_error_declarator;

/* The obstack on which declarators and related data structures are
   allocated.  */
static struct obstack declarator_obstack;

/* Alloc BYTES from the declarator memory pool.  */

static inline void *
alloc_declarator (size_t bytes)
{
  return obstack_alloc (&declarator_obstack, bytes);
}

/* Allocate a declarator of the indicated KIND.  Clear fields that are
   common to all declarators.  */

static cp_declarator *
make_declarator (cp_declarator_kind kind)
{
  cp_declarator *declarator;

  declarator = (cp_declarator *) alloc_declarator (sizeof (cp_declarator));
  declarator->kind = kind;
  declarator->parenthesized = UNKNOWN_LOCATION;
  declarator->attributes = NULL_TREE;
  declarator->std_attributes = NULL_TREE;
  declarator->declarator = NULL;
  declarator->parameter_pack_p = false;
  declarator->id_loc = UNKNOWN_LOCATION;
  declarator->init_loc = UNKNOWN_LOCATION;

  return declarator;
}

/* Make a declarator for a generalized identifier.  If
   QUALIFYING_SCOPE is non-NULL, the identifier is
   QUALIFYING_SCOPE::UNQUALIFIED_NAME; otherwise, it is just
   UNQUALIFIED_NAME.  SFK indicates the kind of special function this
   is, if any.   */

static cp_declarator *
make_id_declarator (tree qualifying_scope, tree unqualified_name,
		    special_function_kind sfk, location_t id_location)
{
  cp_declarator *declarator;

  /* It is valid to write:

       class C { void f(); };
       typedef C D;
       void D::f();

     The standard is not clear about whether `typedef const C D' is
     legal; as of 2002-09-15 the committee is considering that
     question.  EDG 3.0 allows that syntax.  Therefore, we do as
     well.  */
  if (qualifying_scope && TYPE_P (qualifying_scope))
    qualifying_scope = TYPE_MAIN_VARIANT (qualifying_scope);

  gcc_assert (identifier_p (unqualified_name)
	      || TREE_CODE (unqualified_name) == BIT_NOT_EXPR
	      || TREE_CODE (unqualified_name) == TEMPLATE_ID_EXPR);

  declarator = make_declarator (cdk_id);
  declarator->u.id.qualifying_scope = qualifying_scope;
  declarator->u.id.unqualified_name = unqualified_name;
  declarator->u.id.sfk = sfk;
  declarator->id_loc = id_location;

  return declarator;
}

/* Make a declarator for a pointer to TARGET.  CV_QUALIFIERS is a list
   of modifiers such as const or volatile to apply to the pointer
   type, represented as identifiers.  ATTRIBUTES represent the attributes that
   appertain to the pointer or reference.  */

cp_declarator *
make_pointer_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
			 tree attributes)
{
  cp_declarator *declarator;

  declarator = make_declarator (cdk_pointer);
  declarator->declarator = target;
  declarator->u.pointer.qualifiers = cv_qualifiers;
  declarator->u.pointer.class_type = NULL_TREE;
  if (target)
    {
      declarator->id_loc = target->id_loc;
      declarator->parameter_pack_p = target->parameter_pack_p;
      target->parameter_pack_p = false;
    }
  else
    declarator->parameter_pack_p = false;

  declarator->std_attributes = attributes;

  return declarator;
}

/* Like make_pointer_declarator -- but for references.  ATTRIBUTES
   represent the attributes that appertain to the pointer or
   reference.  */

cp_declarator *
make_reference_declarator (cp_cv_quals cv_qualifiers, cp_declarator *target,
			   bool rvalue_ref, tree attributes)
{
  cp_declarator *declarator;

  declarator = make_declarator (cdk_reference);
  declarator->declarator = target;
  declarator->u.reference.qualifiers = cv_qualifiers;
  declarator->u.reference.rvalue_ref = rvalue_ref;
  if (target)
    {
      declarator->id_loc = target->id_loc;
      declarator->parameter_pack_p = target->parameter_pack_p;
      target->parameter_pack_p = false;
    }
  else
    declarator->parameter_pack_p = false;

  declarator->std_attributes = attributes;

  return declarator;
}

/* Like make_pointer_declarator -- but for a pointer to a non-static
   member of CLASS_TYPE.  ATTRIBUTES represent the attributes that
   appertain to the pointer or reference.  */

cp_declarator *
make_ptrmem_declarator (cp_cv_quals cv_qualifiers, tree class_type,
			cp_declarator *pointee,
			tree attributes)
{
  cp_declarator *declarator;

  declarator = make_declarator (cdk_ptrmem);
  declarator->declarator = pointee;
  declarator->u.pointer.qualifiers = cv_qualifiers;
  declarator->u.pointer.class_type = class_type;

  if (pointee)
    {
      declarator->parameter_pack_p = pointee->parameter_pack_p;
      pointee->parameter_pack_p = false;
    }
  else
    declarator->parameter_pack_p = false;

  declarator->std_attributes = attributes;

  return declarator;
}

/* Make a declarator for the function given by TARGET, with the
   indicated PARMS.  The CV_QUALIFIERS apply to the function, as in
   "const"-qualified member function.  The EXCEPTION_SPECIFICATION
   indicates what exceptions can be thrown.  STD_ATTRS contains
   attributes that appertain to the function type. */

cp_declarator *
make_call_declarator (cp_declarator *target,
		      tree parms,
		      cp_cv_quals cv_qualifiers,
		      cp_virt_specifiers virt_specifiers,
		      cp_ref_qualifier ref_qualifier,
		      tree tx_qualifier,
		      tree exception_specification,
		      tree late_return_type,
		      tree requires_clause,
		      tree std_attrs,
		      location_t parens_loc)
{
  cp_declarator *declarator;

  declarator = make_declarator (cdk_function);
  declarator->declarator = target;
  declarator->u.function.parameters = parms;
  declarator->u.function.qualifiers = cv_qualifiers;
  declarator->u.function.virt_specifiers = virt_specifiers;
  declarator->u.function.ref_qualifier = ref_qualifier;
  declarator->u.function.tx_qualifier = tx_qualifier;
  declarator->u.function.exception_specification = exception_specification;
  declarator->u.function.late_return_type = late_return_type;
  declarator->u.function.requires_clause = requires_clause;
  declarator->u.function.parens_loc = parens_loc;
  if (target)
    {
      declarator->id_loc = target->id_loc;
      declarator->parameter_pack_p = target->parameter_pack_p;
      target->parameter_pack_p = false;
    }
  else
    declarator->parameter_pack_p = false;

  declarator->std_attributes = std_attrs;

  return declarator;
}

/* Make a declarator for an array of BOUNDS elements, each of which is
   defined by ELEMENT.  */

cp_declarator *
make_array_declarator (cp_declarator *element, tree bounds)
{
  cp_declarator *declarator;

  declarator = make_declarator (cdk_array);
  declarator->declarator = element;
  declarator->u.array.bounds = bounds;
  if (element)
    {
      declarator->id_loc = element->id_loc;
      declarator->parameter_pack_p = element->parameter_pack_p;
      element->parameter_pack_p = false;
    }
  else
    declarator->parameter_pack_p = false;

  return declarator;
}

/* Determine whether the declarator we've seen so far can be a
   parameter pack, when followed by an ellipsis.  */
static bool
declarator_can_be_parameter_pack (cp_declarator *declarator)
{
  if (declarator && declarator->parameter_pack_p)
    /* We already saw an ellipsis.  */
    return false;

  /* Search for a declarator name, or any other declarator that goes
     after the point where the ellipsis could appear in a parameter
     pack. If we find any of these, then this declarator cannot be
     made into a parameter pack.  */
  bool found = false;
  while (declarator && !found)
    {
      switch ((int)declarator->kind)
	{
	case cdk_id:
	case cdk_array:
	case cdk_decomp:
	  found = true;
	  break;

	case cdk_error:
	  return true;

	default:
	  declarator = declarator->declarator;
	  break;
	}
    }

  return !found;
}

cp_parameter_declarator *no_parameters;

/* Create a parameter declarator with the indicated DECL_SPECIFIERS,
   DECLARATOR and DEFAULT_ARGUMENT.  */

cp_parameter_declarator *
make_parameter_declarator (cp_decl_specifier_seq *decl_specifiers,
			   cp_declarator *declarator,
			   tree default_argument,
			   location_t loc,
			   bool template_parameter_pack_p = false)
{
  cp_parameter_declarator *parameter;

  parameter = ((cp_parameter_declarator *)
	       alloc_declarator (sizeof (cp_parameter_declarator)));
  parameter->next = NULL;
  if (decl_specifiers)
    parameter->decl_specifiers = *decl_specifiers;
  else
    clear_decl_specs (&parameter->decl_specifiers);
  parameter->declarator = declarator;
  parameter->default_argument = default_argument;
  parameter->template_parameter_pack_p = template_parameter_pack_p;
  parameter->loc = loc;

  return parameter;
}

/* Returns true iff DECLARATOR  is a declaration for a function.  */

static bool
function_declarator_p (const cp_declarator *declarator)
{
  while (declarator)
    {
      if (declarator->kind == cdk_function
	  && declarator->declarator->kind == cdk_id)
	return true;
      if (declarator->kind == cdk_id
	  || declarator->kind == cdk_decomp
	  || declarator->kind == cdk_error)
	return false;
      declarator = declarator->declarator;
    }
  return false;
}

/* The parser.  */

/* Overview
   --------

   A cp_parser parses the token stream as specified by the C++
   grammar.  Its job is purely parsing, not semantic analysis.  For
   example, the parser breaks the token stream into declarators,
   expressions, statements, and other similar syntactic constructs.
   It does not check that the types of the expressions on either side
   of an assignment-statement are compatible, or that a function is
   not declared with a parameter of type `void'.

   The parser invokes routines elsewhere in the compiler to perform
   semantic analysis and to build up the abstract syntax tree for the
   code processed.

   The parser (and the template instantiation code, which is, in a
   way, a close relative of parsing) are the only parts of the
   compiler that should be calling push_scope and pop_scope, or
   related functions.  The parser (and template instantiation code)
   keeps track of what scope is presently active; everything else
   should simply honor that.  (The code that generates static
   initializers may also need to set the scope, in order to check
   access control correctly when emitting the initializers.)

   Methodology
   -----------

   The parser is of the standard recursive-descent variety.  Upcoming
   tokens in the token stream are examined in order to determine which
   production to use when parsing a non-terminal.  Some C++ constructs
   require arbitrary look ahead to disambiguate.  For example, it is
   impossible, in the general case, to tell whether a statement is an
   expression or declaration without scanning the entire statement.
   Therefore, the parser is capable of "parsing tentatively."  When the
   parser is not sure what construct comes next, it enters this mode.
   Then, while we attempt to parse the construct, the parser queues up
   error messages, rather than issuing them immediately, and saves the
   tokens it consumes.  If the construct is parsed successfully, the
   parser "commits", i.e., it issues any queued error messages and
   the tokens that were being preserved are permanently discarded.
   If, however, the construct is not parsed successfully, the parser
   rolls back its state completely so that it can resume parsing using
   a different alternative.

   Future Improvements
   -------------------

   The performance of the parser could probably be improved substantially.
   We could often eliminate the need to parse tentatively by looking ahead
   a little bit.  In some places, this approach might not entirely eliminate
   the need to parse tentatively, but it might still speed up the average
   case.  */

/* Flags that are passed to some parsing functions.  These values can
   be bitwise-ored together.  */

enum
{
  /* No flags.  */
  CP_PARSER_FLAGS_NONE = 0x0,
  /* The construct is optional.  If it is not present, then no error
     should be issued.  */
  CP_PARSER_FLAGS_OPTIONAL = 0x1,
  /* When parsing a type-specifier, treat user-defined type-names
     as non-type identifiers.  */
  CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES = 0x2,
  /* When parsing a type-specifier, do not try to parse a class-specifier
     or enum-specifier.  */
  CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS = 0x4,
  /* When parsing a decl-specifier-seq, only allow type-specifier or
     constexpr.  */
  CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR = 0x8,
  /* When parsing a decl-specifier-seq, only allow mutable, constexpr or
     for C++20 consteval or for C++23 static.  */
  CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10,
  /* When parsing a decl-specifier-seq, allow missing typename.  */
  CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20,
  /* When parsing of the noexcept-specifier should be delayed.  */
  CP_PARSER_FLAGS_DELAY_NOEXCEPT = 0x40,
  /* When parsing a consteval declarator.  */
  CP_PARSER_FLAGS_CONSTEVAL = 0x80
};

/* This type is used for parameters and variables which hold
   combinations of the above flags.  */
typedef int cp_parser_flags;

/* The different kinds of declarators we want to parse.  */

enum cp_parser_declarator_kind
{
  /* We want an abstract declarator.  */
  CP_PARSER_DECLARATOR_ABSTRACT,
  /* We want a named declarator.  */
  CP_PARSER_DECLARATOR_NAMED,
  /* We don't mind, but the name must be an unqualified-id.  */
  CP_PARSER_DECLARATOR_EITHER
};

/* The precedence values used to parse binary expressions.  The minimum value
   of PREC must be 1, because zero is reserved to quickly discriminate
   binary operators from other tokens.  */

enum cp_parser_prec
{
  PREC_NOT_OPERATOR,
  PREC_LOGICAL_OR_EXPRESSION,
  PREC_LOGICAL_AND_EXPRESSION,
  PREC_INCLUSIVE_OR_EXPRESSION,
  PREC_EXCLUSIVE_OR_EXPRESSION,
  PREC_AND_EXPRESSION,
  PREC_EQUALITY_EXPRESSION,
  PREC_RELATIONAL_EXPRESSION,
  PREC_SPACESHIP_EXPRESSION,
  PREC_SHIFT_EXPRESSION,
  PREC_ADDITIVE_EXPRESSION,
  PREC_MULTIPLICATIVE_EXPRESSION,
  PREC_PM_EXPRESSION,
  NUM_PREC_VALUES = PREC_PM_EXPRESSION
};

/* A mapping from a token type to a corresponding tree node type, with a
   precedence value.  */

struct cp_parser_binary_operations_map_node
{
  /* The token type.  */
  enum cpp_ttype token_type;
  /* The corresponding tree code.  */
  enum tree_code tree_type;
  /* The precedence of this operator.  */
  enum cp_parser_prec prec;
};

struct cp_parser_expression_stack_entry
{
  /* Left hand side of the binary operation we are currently
     parsing.  */
  cp_expr lhs;
  /* Original tree code for left hand side, if it was a binary
     expression itself (used for -Wparentheses).  */
  enum tree_code lhs_type;
  /* Tree code for the binary operation we are parsing.  */
  enum tree_code tree_type;
  /* Precedence of the binary operation we are parsing.  */
  enum cp_parser_prec prec;
  /* Location of the binary operation we are parsing.  */
  location_t loc;
  /* Flags from the operator token.  */
  unsigned char flags;
};

/* The stack for storing partial expressions.  We only need NUM_PREC_VALUES
   entries because precedence levels on the stack are monotonically
   increasing.  */
typedef struct cp_parser_expression_stack_entry
  cp_parser_expression_stack[NUM_PREC_VALUES];

/* Prototypes.  */

/* Constructors and destructors.  */

static cp_parser_context *cp_parser_context_new
  (cp_parser_context *);

/* Class variables.  */

static GTY((deletable)) cp_parser_context* cp_parser_context_free_list;

/* The operator-precedence table used by cp_parser_binary_expression.
   Transformed into an associative array (binops_by_token) by
   cp_parser_new.  */

static const cp_parser_binary_operations_map_node binops[] = {
  { CPP_DEREF_STAR, MEMBER_REF, PREC_PM_EXPRESSION },
  { CPP_DOT_STAR, DOTSTAR_EXPR, PREC_PM_EXPRESSION },

  { CPP_MULT, MULT_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
  { CPP_DIV, TRUNC_DIV_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },
  { CPP_MOD, TRUNC_MOD_EXPR, PREC_MULTIPLICATIVE_EXPRESSION },

  { CPP_PLUS, PLUS_EXPR, PREC_ADDITIVE_EXPRESSION },
  { CPP_MINUS, MINUS_EXPR, PREC_ADDITIVE_EXPRESSION },

  { CPP_LSHIFT, LSHIFT_EXPR, PREC_SHIFT_EXPRESSION },
  { CPP_RSHIFT, RSHIFT_EXPR, PREC_SHIFT_EXPRESSION },

  { CPP_SPACESHIP, SPACESHIP_EXPR, PREC_SPACESHIP_EXPRESSION },

  { CPP_LESS, LT_EXPR, PREC_RELATIONAL_EXPRESSION },
  { CPP_GREATER, GT_EXPR, PREC_RELATIONAL_EXPRESSION },
  { CPP_LESS_EQ, LE_EXPR, PREC_RELATIONAL_EXPRESSION },
  { CPP_GREATER_EQ, GE_EXPR, PREC_RELATIONAL_EXPRESSION },

  { CPP_EQ_EQ, EQ_EXPR, PREC_EQUALITY_EXPRESSION },
  { CPP_NOT_EQ, NE_EXPR, PREC_EQUALITY_EXPRESSION },

  { CPP_AND, BIT_AND_EXPR, PREC_AND_EXPRESSION },

  { CPP_XOR, BIT_XOR_EXPR, PREC_EXCLUSIVE_OR_EXPRESSION },

  { CPP_OR, BIT_IOR_EXPR, PREC_INCLUSIVE_OR_EXPRESSION },

  { CPP_AND_AND, TRUTH_ANDIF_EXPR, PREC_LOGICAL_AND_EXPRESSION },

  { CPP_OR_OR, TRUTH_ORIF_EXPR, PREC_LOGICAL_OR_EXPRESSION }
};

/* The same as binops, but initialized by cp_parser_new so that
   binops_by_token[N].token_type == N.  Used in cp_parser_binary_expression
   for speed.  */
static cp_parser_binary_operations_map_node binops_by_token[N_CP_TTYPES];

/* Constructors and destructors.  */

/* Construct a new context.  The context below this one on the stack
   is given by NEXT.  */

static cp_parser_context *
cp_parser_context_new (cp_parser_context* next)
{
  cp_parser_context *context;

  /* Allocate the storage.  */
  if (cp_parser_context_free_list != NULL)
    {
      /* Pull the first entry from the free list.  */
      context = cp_parser_context_free_list;
      cp_parser_context_free_list = context->next;
      memset (context, 0, sizeof (*context));
    }
  else
    context = ggc_cleared_alloc<cp_parser_context> ();

  /* No errors have occurred yet in this context.  */
  context->status = CP_PARSER_STATUS_KIND_NO_ERROR;
  /* If this is not the bottommost context, copy information that we
     need from the previous context.  */
  if (next)
    {
      /* If, in the NEXT context, we are parsing an `x->' or `x.'
	 expression, then we are parsing one in this context, too.  */
      context->object_type = next->object_type;
      /* Thread the stack.  */
      context->next = next;
    }

  return context;
}

/* Managing the unparsed function queues.  */

#define unparsed_funs_with_default_args \
  parser->unparsed_queues->last ().funs_with_default_args
#define unparsed_funs_with_definitions \
  parser->unparsed_queues->last ().funs_with_definitions
#define unparsed_nsdmis \
  parser->unparsed_queues->last ().nsdmis
#define unparsed_noexcepts \
  parser->unparsed_queues->last ().noexcepts
#define unparsed_contracts \
  parser->unparsed_queues->last ().contracts

static void
push_unparsed_function_queues (cp_parser *parser)
{
  cp_unparsed_functions_entry e
      = { NULL, make_tree_vector (), NULL, NULL, NULL };
  vec_safe_push (parser->unparsed_queues, e);
}

static void
pop_unparsed_function_queues (cp_parser *parser)
{
  release_tree_vector (unparsed_funs_with_definitions);
  parser->unparsed_queues->pop ();
}

/* Prototypes.  */

/* Routines to parse various constructs.

   Those that return `tree' will return the error_mark_node (rather
   than NULL_TREE) if a parse error occurs, unless otherwise noted.
   Sometimes, they will return an ordinary node if error-recovery was
   attempted, even though a parse error occurred.  So, to check
   whether or not a parse error occurred, you should always use
   cp_parser_error_occurred.  If the construct is optional (indicated
   either by an `_opt' in the name of the function that does the
   parsing or via a FLAGS parameter), then NULL_TREE is returned if
   the construct is not present.  */

/* Lexical conventions [gram.lex]  */

static tree finish_userdef_string_literal
  (tree);

/* Basic concepts [gram.basic]  */

static void cp_parser_translation_unit (cp_parser *);

/* Expressions [gram.expr]  */

static cp_expr cp_parser_primary_expression
  (cp_parser *, bool, bool, bool, cp_id_kind *);
static cp_expr cp_parser_id_expression
  (cp_parser *, bool, bool, bool *, bool, bool);
static cp_expr cp_parser_unqualified_id
  (cp_parser *, bool, bool, bool, bool);
static tree cp_parser_nested_name_specifier_opt
  (cp_parser *, bool, bool, bool, bool, bool = false);
static tree cp_parser_nested_name_specifier
  (cp_parser *, bool, bool, bool, bool);
static tree cp_parser_qualifying_entity
  (cp_parser *, bool, bool, bool, bool, bool);
static cp_expr cp_parser_postfix_expression
  (cp_parser *, bool, bool, bool, bool, cp_id_kind *);
static tree cp_parser_postfix_open_square_expression
  (cp_parser *, tree, bool, bool);
static tree cp_parser_postfix_dot_deref_expression
  (cp_parser *, enum cpp_ttype, cp_expr, bool, cp_id_kind *, location_t);
static vec<tree, va_gc> *cp_parser_parenthesized_expression_list
  (cp_parser *, int, bool, bool, bool *, location_t * = NULL,
   bool = false);
/* Values for the second parameter of cp_parser_parenthesized_expression_list.  */
enum { non_attr = 0, normal_attr = 1, id_attr = 2, assume_attr = 3 };
static void cp_parser_pseudo_destructor_name
  (cp_parser *, tree, tree *, tree *);
static cp_expr cp_parser_unary_expression
  (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
static enum tree_code cp_parser_unary_operator
  (cp_token *);
static tree cp_parser_has_attribute_expression
  (cp_parser *);
static tree cp_parser_new_expression
  (cp_parser *);
static vec<tree, va_gc> *cp_parser_new_placement
  (cp_parser *);
static tree cp_parser_new_type_id
  (cp_parser *, tree *);
static cp_declarator *cp_parser_new_declarator_opt
  (cp_parser *);
static cp_declarator *cp_parser_direct_new_declarator
  (cp_parser *);
static vec<tree, va_gc> *cp_parser_new_initializer
  (cp_parser *);
static tree cp_parser_delete_expression
  (cp_parser *);
static cp_expr cp_parser_cast_expression
  (cp_parser *, bool, bool, bool, cp_id_kind *);
static cp_expr cp_parser_binary_expression
  (cp_parser *, bool, bool, enum cp_parser_prec, cp_id_kind *);
static tree cp_parser_question_colon_clause
  (cp_parser *, cp_expr);
static cp_expr cp_parser_conditional_expression (cp_parser *);
static cp_expr cp_parser_assignment_expression
  (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
static enum tree_code cp_parser_assignment_operator_opt
  (cp_parser *);
static cp_expr cp_parser_expression
  (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
static cp_expr cp_parser_constant_expression
  (cp_parser *, int = 0, bool * = NULL, bool = false);
static cp_expr cp_parser_builtin_offsetof
  (cp_parser *);
static cp_expr cp_parser_lambda_expression
  (cp_parser *);
static void cp_parser_lambda_introducer
  (cp_parser *, tree);
static bool cp_parser_lambda_declarator_opt
  (cp_parser *, tree);
static void cp_parser_lambda_body
  (cp_parser *, tree);

/* Statements [gram.stmt.stmt]  */

static void cp_parser_statement
  (cp_parser *, tree, bool, bool *, vec<tree> * = NULL, location_t * = NULL);
static void cp_parser_label_for_labeled_statement
(cp_parser *, tree);
static tree cp_parser_expression_statement
  (cp_parser *, tree);
static tree cp_parser_compound_statement
  (cp_parser *, tree, int, bool);
static void cp_parser_statement_seq_opt
  (cp_parser *, tree);
static tree cp_parser_selection_statement
  (cp_parser *, bool *, vec<tree> *);
static tree cp_parser_condition
  (cp_parser *);
static tree cp_parser_iteration_statement
  (cp_parser *, bool *, bool, unsigned short);
static bool cp_parser_init_statement
  (cp_parser *, tree *decl);
static tree cp_parser_for
  (cp_parser *, bool, unsigned short);
static tree cp_parser_c_for
  (cp_parser *, tree, tree, bool, unsigned short);
static tree cp_parser_range_for
  (cp_parser *, tree, tree, tree, bool, unsigned short, bool);
static void do_range_for_auto_deduction
  (tree, tree, tree, unsigned int);
static tree cp_parser_perform_range_for_lookup
  (tree, tree *, tree *);
static tree cp_parser_range_for_member_function
  (tree, tree);
static tree cp_parser_jump_statement
  (cp_parser *);
static void cp_parser_declaration_statement
  (cp_parser *);

static tree cp_parser_implicitly_scoped_statement
  (cp_parser *, bool *, const token_indent_info &, vec<tree> * = NULL);
static void cp_parser_already_scoped_statement
  (cp_parser *, bool *, const token_indent_info &);

/* State of module-declaration parsing.  */
enum module_parse
{
  MP_NOT_MODULE,	/* Not a module.  */

  _MP_UNUSED,

  MP_FIRST,	/* First declaration of TU.  */
  MP_GLOBAL,	/* Global Module Fragment.  */

  MP_PURVIEW_IMPORTS,   /* Imports of a module.  */
  MP_PURVIEW,	/* Purview of a named module.  */

  MP_PRIVATE_IMPORTS, /* Imports of a Private Module Fragment.  */
  MP_PRIVATE,   /* Private Module Fragment.  */
};

static module_parse cp_parser_module_declaration
  (cp_parser *parser, module_parse, bool exporting);
static void cp_parser_import_declaration
  (cp_parser *parser, module_parse, bool exporting);

/* Declarations [gram.dcl.dcl] */

static void cp_parser_declaration_seq_opt
  (cp_parser *);
static void cp_parser_declaration
  (cp_parser *, tree);
static void cp_parser_toplevel_declaration
  (cp_parser *);
static void cp_parser_block_declaration
  (cp_parser *, bool);
static void cp_parser_simple_declaration
  (cp_parser *, bool, tree *);
static void cp_parser_decl_specifier_seq
  (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, int *);
static tree cp_parser_storage_class_specifier_opt
  (cp_parser *);
static tree cp_parser_function_specifier_opt
  (cp_parser *, cp_decl_specifier_seq *);
static tree cp_parser_type_specifier
  (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *, bool,
   int *, bool *);
static tree cp_parser_simple_type_specifier
  (cp_parser *, cp_decl_specifier_seq *, cp_parser_flags);
static tree cp_parser_placeholder_type_specifier
  (cp_parser *, location_t, tree, bool);
static tree cp_parser_type_name
  (cp_parser *, bool);
static tree cp_parser_nonclass_name
  (cp_parser* parser);
static tree cp_parser_elaborated_type_specifier
  (cp_parser *, bool, bool);
static tree cp_parser_enum_specifier
  (cp_parser *);
static void cp_parser_enumerator_list
  (cp_parser *, tree);
static void cp_parser_enumerator_definition
  (cp_parser *, tree);
static tree cp_parser_namespace_name
  (cp_parser *);
static void cp_parser_namespace_definition
  (cp_parser *);
static void cp_parser_namespace_body
  (cp_parser *);
static tree cp_parser_qualified_namespace_specifier
  (cp_parser *);
static void cp_parser_namespace_alias_definition
  (cp_parser *);
static bool cp_parser_using_declaration
  (cp_parser *, bool);
static void cp_parser_using_directive
  (cp_parser *);
static void cp_parser_using_enum
  (cp_parser *);
static tree cp_parser_alias_declaration
  (cp_parser *);
static void cp_parser_asm_definition
  (cp_parser *);
static void cp_parser_linkage_specification
  (cp_parser *, tree);
static void cp_parser_static_assert
  (cp_parser *, bool);
static tree cp_parser_decltype
  (cp_parser *);
static tree cp_parser_decomposition_declaration
  (cp_parser *, cp_decl_specifier_seq *, tree *, location_t *);

/* Declarators [gram.dcl.decl] */

static tree cp_parser_init_declarator
  (cp_parser *, cp_parser_flags, cp_decl_specifier_seq *,
   vec<deferred_access_check, va_gc> *, bool, bool, int, bool *, tree *,
   location_t *, tree *);
static cp_declarator *cp_parser_declarator
  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool *,
   bool, bool, bool);
static cp_declarator *cp_parser_direct_declarator
  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, bool, bool,
   bool);
static enum tree_code cp_parser_ptr_operator
  (cp_parser *, tree *, cp_cv_quals *, tree *);
static cp_cv_quals cp_parser_cv_qualifier_seq_opt
  (cp_parser *);
static cp_virt_specifiers cp_parser_virt_specifier_seq_opt
  (cp_parser *);
static cp_ref_qualifier cp_parser_ref_qualifier_opt
  (cp_parser *);
static tree cp_parser_tx_qualifier_opt
  (cp_parser *);
static tree cp_parser_late_return_type_opt
  (cp_parser *, cp_declarator *, tree &);
static tree cp_parser_declarator_id
  (cp_parser *, bool);
static tree cp_parser_type_id
  (cp_parser *, cp_parser_flags = CP_PARSER_FLAGS_NONE, location_t * = NULL);
static tree cp_parser_template_type_arg
  (cp_parser *);
static tree cp_parser_trailing_type_id (cp_parser *);
static tree cp_parser_type_id_1
  (cp_parser *, cp_parser_flags, bool, bool, location_t *);
static void cp_parser_type_specifier_seq
  (cp_parser *, cp_parser_flags, bool, bool, cp_decl_specifier_seq *);
static tree cp_parser_parameter_declaration_clause
  (cp_parser *, cp_parser_flags);
static tree cp_parser_parameter_declaration_list
  (cp_parser *, cp_parser_flags, auto_vec<tree> *);
static cp_parameter_declarator *cp_parser_parameter_declaration
  (cp_parser *, cp_parser_flags, bool, bool *);
static tree cp_parser_default_argument
  (cp_parser *, bool);
static void cp_parser_function_body
  (cp_parser *, bool);
static tree cp_parser_initializer
  (cp_parser *, bool *, bool *, bool = false);
static cp_expr cp_parser_initializer_clause
  (cp_parser *, bool *);
static cp_expr cp_parser_braced_list
  (cp_parser*, bool*);
static vec<constructor_elt, va_gc> *cp_parser_initializer_list
  (cp_parser *, bool *, bool *);

static void cp_parser_ctor_initializer_opt_and_function_body
  (cp_parser *, bool);

static tree cp_parser_late_parsing_omp_declare_simd
  (cp_parser *, tree);

static tree cp_parser_late_parsing_oacc_routine
  (cp_parser *, tree);

static tree synthesize_implicit_template_parm
  (cp_parser *, tree);
static tree finish_fully_implicit_template
  (cp_parser *, tree);
static void abort_fully_implicit_template
  (cp_parser *);

/* Classes [gram.class] */

static tree cp_parser_class_name
  (cp_parser *, bool, bool, enum tag_types, bool, bool, bool, bool = false);
static tree cp_parser_class_specifier
  (cp_parser *);
static tree cp_parser_class_head
  (cp_parser *, bool *);
static enum tag_types cp_parser_class_key
  (cp_parser *);
static void cp_parser_type_parameter_key
  (cp_parser* parser);
static void cp_parser_member_specification_opt
  (cp_parser *);
static void cp_parser_member_declaration
  (cp_parser *);
static tree cp_parser_pure_specifier
  (cp_parser *);
static tree cp_parser_constant_initializer
  (cp_parser *);

/* Derived classes [gram.class.derived] */

static tree cp_parser_base_clause
  (cp_parser *);
static tree cp_parser_base_specifier
  (cp_parser *);

/* Special member functions [gram.special] */

static tree cp_parser_conversion_function_id
  (cp_parser *);
static tree cp_parser_conversion_type_id
  (cp_parser *);
static cp_declarator *cp_parser_conversion_declarator_opt
  (cp_parser *);
static void cp_parser_ctor_initializer_opt
  (cp_parser *);
static void cp_parser_mem_initializer_list
  (cp_parser *);
static tree cp_parser_mem_initializer
  (cp_parser *);
static tree cp_parser_mem_initializer_id
  (cp_parser *);

/* Overloading [gram.over] */

static cp_expr cp_parser_operator_function_id
  (cp_parser *);
static cp_expr cp_parser_operator
  (cp_parser *, location_t);

/* Templates [gram.temp] */

static void cp_parser_template_declaration
  (cp_parser *, bool);
static tree cp_parser_template_parameter_list
  (cp_parser *);
static tree cp_parser_template_parameter
  (cp_parser *, bool *, bool *);
static tree cp_parser_type_parameter
  (cp_parser *, bool *);
static tree cp_parser_template_id
  (cp_parser *, bool, bool, enum tag_types, bool);
static tree cp_parser_template_id_expr
  (cp_parser *, bool, bool, bool);
static tree cp_parser_template_name
  (cp_parser *, bool, bool, bool, enum tag_types, bool *);
static tree cp_parser_template_argument_list
  (cp_parser *);
static tree cp_parser_template_argument
  (cp_parser *);
static void cp_parser_explicit_instantiation
  (cp_parser *);
static void cp_parser_explicit_specialization
  (cp_parser *);

/* Exception handling [gram.except] */

static tree cp_parser_try_block
  (cp_parser *);
static void cp_parser_function_try_block
  (cp_parser *);
static void cp_parser_handler_seq
  (cp_parser *);
static void cp_parser_handler
  (cp_parser *);
static tree cp_parser_exception_declaration
  (cp_parser *);
static tree cp_parser_throw_expression
  (cp_parser *);
static tree cp_parser_exception_specification_opt
  (cp_parser *, cp_parser_flags);
static tree cp_parser_type_id_list
  (cp_parser *);
static tree cp_parser_noexcept_specification_opt
  (cp_parser *, cp_parser_flags, bool, bool *, bool);

/* GNU Extensions */

static tree cp_parser_asm_specification_opt
  (cp_parser *);
static tree cp_parser_asm_operand_list
  (cp_parser *);
static tree cp_parser_asm_clobber_list
  (cp_parser *);
static tree cp_parser_asm_label_list
  (cp_parser *);
static bool cp_next_tokens_can_be_attribute_p
  (cp_parser *);
static bool cp_next_tokens_can_be_gnu_attribute_p
  (cp_parser *);
static bool cp_next_tokens_can_be_std_attribute_p
  (cp_parser *);
static bool cp_nth_tokens_can_be_std_attribute_p
  (cp_parser *, size_t);
static bool cp_nth_tokens_can_be_gnu_attribute_p
  (cp_parser *, size_t);
static bool cp_nth_tokens_can_be_attribute_p
  (cp_parser *, size_t);
static tree cp_parser_attributes_opt
  (cp_parser *);
static tree cp_parser_gnu_attributes_opt
  (cp_parser *);
static tree cp_parser_gnu_attribute_list
  (cp_parser *, bool = false);
static tree cp_parser_std_attribute
  (cp_parser *, tree);
static tree cp_parser_std_attribute_spec
  (cp_parser *);
static tree cp_parser_std_attribute_spec_seq
  (cp_parser *);
static size_t cp_parser_skip_std_attribute_spec_seq
  (cp_parser *, size_t);
static size_t cp_parser_skip_attributes_opt
  (cp_parser *, size_t);
static bool cp_parser_extension_opt
  (cp_parser *, int *);
static void cp_parser_label_declaration
  (cp_parser *);

/* Concept Extensions */

static tree cp_parser_concept_definition
  (cp_parser *);
static tree cp_parser_constraint_expression
  (cp_parser *);
static tree cp_parser_requires_clause_opt
  (cp_parser *, bool);
static tree cp_parser_requires_expression
  (cp_parser *);
static tree cp_parser_requirement_parameter_list
  (cp_parser *);
static tree cp_parser_requirement_body
  (cp_parser *);
static tree cp_parser_requirement_seq
  (cp_parser *);
static tree cp_parser_requirement
  (cp_parser *);
static tree cp_parser_simple_requirement
  (cp_parser *);
static tree cp_parser_compound_requirement
  (cp_parser *);
static tree cp_parser_type_requirement
  (cp_parser *);
static tree cp_parser_nested_requirement
  (cp_parser *);

/* Transactional Memory Extensions */

static tree cp_parser_transaction
  (cp_parser *, cp_token *);
static tree cp_parser_transaction_expression
  (cp_parser *, enum rid);
static void cp_parser_function_transaction
  (cp_parser *, enum rid);
static tree cp_parser_transaction_cancel
  (cp_parser *);

/* Coroutine extensions.  */

static tree cp_parser_yield_expression
  (cp_parser *);

/* Contracts */

static void cp_parser_late_contract_condition
  (cp_parser *, tree, tree);

enum pragma_context {
  pragma_external,
  pragma_member,
  pragma_objc_icode,
  pragma_stmt,
  pragma_compound
};
static bool cp_parser_pragma
  (cp_parser *, enum pragma_context, bool *);

/* Objective-C++ Productions */

static tree cp_parser_objc_message_receiver
  (cp_parser *);
static tree cp_parser_objc_message_args
  (cp_parser *);
static tree cp_parser_objc_message_expression
  (cp_parser *);
static cp_expr cp_parser_objc_encode_expression
  (cp_parser *);
static tree cp_parser_objc_defs_expression
  (cp_parser *);
static tree cp_parser_objc_protocol_expression
  (cp_parser *);
static tree cp_parser_objc_selector_expression
  (cp_parser *);
static cp_expr cp_parser_objc_expression
  (cp_parser *);
static bool cp_parser_objc_selector_p
  (enum cpp_ttype);
static tree cp_parser_objc_selector
  (cp_parser *);
static tree cp_parser_objc_protocol_refs_opt
  (cp_parser *);
static void cp_parser_objc_declaration
  (cp_parser *, tree);
static tree cp_parser_objc_statement
  (cp_parser *);
static bool cp_parser_objc_valid_prefix_attributes
  (cp_parser *, tree *);
static void cp_parser_objc_at_property_declaration
  (cp_parser *) ;
static void cp_parser_objc_at_synthesize_declaration
  (cp_parser *) ;
static void cp_parser_objc_at_dynamic_declaration
  (cp_parser *) ;
static tree cp_parser_objc_struct_declaration
  (cp_parser *) ;

/* Utility Routines */

static cp_expr cp_parser_lookup_name
  (cp_parser *, tree, enum tag_types, bool, bool, bool, tree *, location_t);
static tree cp_parser_lookup_name_simple
  (cp_parser *, tree, location_t);
static tree cp_parser_maybe_treat_template_as_class
  (tree, bool);
static bool cp_parser_check_declarator_template_parameters
  (cp_parser *, cp_declarator *, location_t);
static bool cp_parser_check_template_parameters
  (cp_parser *, unsigned, bool, location_t, cp_declarator *);
static cp_expr cp_parser_simple_cast_expression
  (cp_parser *);
static tree cp_parser_global_scope_opt
  (cp_parser *, bool);
static bool cp_parser_constructor_declarator_p
  (cp_parser *, cp_parser_flags, bool);
static tree cp_parser_function_definition_from_specifiers_and_declarator
  (cp_parser *, cp_decl_specifier_seq *, tree, const cp_declarator *);
static tree cp_parser_function_definition_after_declarator
  (cp_parser *, bool);
static bool cp_parser_template_declaration_after_export
  (cp_parser *, bool);
static void cp_parser_perform_template_parameter_access_checks
  (vec<deferred_access_check, va_gc> *);
static tree cp_parser_single_declaration
  (cp_parser *, vec<deferred_access_check, va_gc> *, bool, bool, bool *);
static cp_expr cp_parser_functional_cast
  (cp_parser *, tree);
static tree cp_parser_save_member_function_body
  (cp_parser *, cp_decl_specifier_seq *, cp_declarator *, tree);
static tree cp_parser_save_nsdmi
  (cp_parser *);
static tree cp_parser_enclosed_template_argument_list
  (cp_parser *);
static void cp_parser_save_default_args
  (cp_parser *, tree);
static void cp_parser_late_parsing_for_member
  (cp_parser *, tree);
static tree cp_parser_late_parse_one_default_arg
  (cp_parser *, tree, tree, tree);
static void cp_parser_late_parsing_nsdmi
  (cp_parser *, tree);
static void cp_parser_late_parsing_default_args
  (cp_parser *, tree);
static tree cp_parser_sizeof_operand
  (cp_parser *, enum rid);
static cp_expr cp_parser_trait
  (cp_parser *, enum rid);
static bool cp_parser_declares_only_class_p
  (cp_parser *);
static void cp_parser_set_storage_class
  (cp_parser *, cp_decl_specifier_seq *, enum rid, cp_token *);
static void cp_parser_set_decl_spec_type
  (cp_decl_specifier_seq *, tree, cp_token *, bool);
static void set_and_check_decl_spec_loc
  (cp_decl_specifier_seq *decl_specs,
   cp_decl_spec ds, cp_token *);
static bool cp_parser_friend_p
  (const cp_decl_specifier_seq *);
static void cp_parser_required_error
  (cp_parser *, required_token, bool, location_t);
static cp_token *cp_parser_require
  (cp_parser *, enum cpp_ttype, required_token, location_t = UNKNOWN_LOCATION);
static cp_token *cp_parser_require_keyword
  (cp_parser *, enum rid, required_token);
static bool cp_parser_token_starts_function_definition_p
  (cp_token *);
static bool cp_parser_next_token_starts_class_definition_p
  (cp_parser *);
static bool cp_parser_next_token_ends_template_argument_p
  (cp_parser *);
static bool cp_parser_nth_token_starts_template_argument_list_p
  (cp_parser *, size_t);
static enum tag_types cp_parser_token_is_class_key
  (cp_token *);
static enum tag_types cp_parser_token_is_type_parameter_key
  (cp_token *);
static void cp_parser_maybe_warn_enum_key (cp_parser *, location_t, tree, rid);
static void cp_parser_check_class_key
(cp_parser *, location_t, enum tag_types, tree type, bool, bool);
static void cp_parser_check_access_in_redeclaration
  (tree type, location_t location);
static bool cp_parser_optional_template_keyword
  (cp_parser *);
static void cp_parser_pre_parsed_nested_name_specifier
  (cp_parser *);
static bool cp_parser_cache_group
  (cp_parser *, enum cpp_ttype, unsigned);
static tree cp_parser_cache_defarg
  (cp_parser *parser, bool nsdmi);
static void cp_parser_parse_tentatively
  (cp_parser *);
static void cp_parser_commit_to_tentative_parse
  (cp_parser *);
static void cp_parser_commit_to_topmost_tentative_parse
  (cp_parser *);
static void cp_parser_abort_tentative_parse
  (cp_parser *);
static bool cp_parser_parse_definitely
  (cp_parser *);
static inline bool cp_parser_parsing_tentatively
  (cp_parser *);
static bool cp_parser_uncommitted_to_tentative_parse_p
  (cp_parser *);
static void cp_parser_error
  (cp_parser *, const char *);
static void cp_parser_name_lookup_error
  (cp_parser *, tree, tree, name_lookup_error, location_t);
static bool cp_parser_simulate_error
  (cp_parser *);
static bool cp_parser_check_type_definition
  (cp_parser *);
static void cp_parser_check_for_definition_in_return_type
  (cp_declarator *, tree, location_t type_location);
static void cp_parser_check_for_invalid_template_id
  (cp_parser *, tree, enum tag_types, location_t location);
static bool cp_parser_non_integral_constant_expression
  (cp_parser *, non_integral_constant);
static void cp_parser_diagnose_invalid_type_name
  (cp_parser *, tree, location_t);
static bool cp_parser_parse_and_diagnose_invalid_type_name
  (cp_parser *);
static int cp_parser_skip_to_closing_parenthesis
  (cp_parser *, bool, bool, bool);
static void cp_parser_skip_to_end_of_statement
  (cp_parser *);
static void cp_parser_consume_semicolon_at_end_of_statement
  (cp_parser *);
static void cp_parser_skip_to_end_of_block_or_statement
  (cp_parser *);
static bool cp_parser_skip_to_closing_brace
  (cp_parser *);
static bool cp_parser_skip_entire_template_parameter_list
  (cp_parser *);
static void cp_parser_require_end_of_template_parameter_list
  (cp_parser *);
static bool cp_parser_skip_to_end_of_template_parameter_list
  (cp_parser *);
static void cp_parser_skip_to_pragma_eol
  (cp_parser*, cp_token *);
static bool cp_parser_error_occurred
  (cp_parser *);
static bool cp_parser_allow_gnu_extensions_p
  (cp_parser *);
static bool cp_parser_is_pure_string_literal
  (cp_token *);
static bool cp_parser_is_string_literal
  (cp_token *);
static bool cp_parser_is_keyword
  (cp_token *, enum rid);
static tree cp_parser_make_typename_type
  (cp_parser *, tree, location_t location);
static cp_declarator * cp_parser_make_indirect_declarator
  (enum tree_code, tree, cp_cv_quals, cp_declarator *, tree);
static bool cp_parser_compound_literal_p
  (cp_parser *);
static bool cp_parser_array_designator_p
  (cp_parser *);
static bool cp_parser_init_statement_p
  (cp_parser *);
static bool cp_parser_skip_up_to_closing_square_bracket
  (cp_parser *);
static bool cp_parser_skip_to_closing_square_bracket
  (cp_parser *);
static size_t cp_parser_skip_balanced_tokens (cp_parser *, size_t);

// -------------------------------------------------------------------------- //
// Unevaluated Operand Guard
//
// Implementation of an RAII helper for unevaluated operand parsing.
cp_unevaluated::cp_unevaluated ()
{
  ++cp_unevaluated_operand;
  ++c_inhibit_evaluation_warnings;
}

cp_unevaluated::~cp_unevaluated ()
{
  --c_inhibit_evaluation_warnings;
  --cp_unevaluated_operand;
}

// -------------------------------------------------------------------------- //
// Tentative Parsing

/* Returns nonzero if we are parsing tentatively.  */

static inline bool
cp_parser_parsing_tentatively (cp_parser* parser)
{
  return parser->context->next != NULL;
}

/* Returns nonzero if TOKEN is a string literal.  */

static bool
cp_parser_is_pure_string_literal (cp_token* token)
{
  return (token->type == CPP_STRING ||
	  token->type == CPP_STRING16 ||
	  token->type == CPP_STRING32 ||
	  token->type == CPP_WSTRING ||
	  token->type == CPP_UTF8STRING);
}

/* Returns nonzero if TOKEN is a string literal
   of a user-defined string literal.  */

static bool
cp_parser_is_string_literal (cp_token* token)
{
  return (cp_parser_is_pure_string_literal (token) ||
	  token->type == CPP_STRING_USERDEF ||
	  token->type == CPP_STRING16_USERDEF ||
	  token->type == CPP_STRING32_USERDEF ||
	  token->type == CPP_WSTRING_USERDEF ||
	  token->type == CPP_UTF8STRING_USERDEF);
}

/* Returns nonzero if TOKEN is the indicated KEYWORD.  */

static bool
cp_parser_is_keyword (cp_token* token, enum rid keyword)
{
  return token->keyword == keyword;
}

/* Helper function for cp_parser_error.
   Having peeked a token of kind TOK1_KIND that might signify
   a conflict marker, peek successor tokens to determine
   if we actually do have a conflict marker.
   Specifically, we consider a run of 7 '<', '=' or '>' characters
   at the start of a line as a conflict marker.
   These come through the lexer as three pairs and a single,
   e.g. three CPP_LSHIFT tokens ("<<") and a CPP_LESS token ('<').
   If it returns true, *OUT_LOC is written to with the location/range
   of the marker.  */

static bool
cp_lexer_peek_conflict_marker (cp_lexer *lexer, enum cpp_ttype tok1_kind,
			       location_t *out_loc)
{
  cp_token *token2 = cp_lexer_peek_nth_token (lexer, 2);
  if (token2->type != tok1_kind)
    return false;
  cp_token *token3 = cp_lexer_peek_nth_token (lexer, 3);
  if (token3->type != tok1_kind)
    return false;
  cp_token *token4 = cp_lexer_peek_nth_token (lexer, 4);
  if (token4->type != conflict_marker_get_final_tok_kind (tok1_kind))
    return false;

  /* It must be at the start of the line.  */
  location_t start_loc = cp_lexer_peek_token (lexer)->location;
  if (LOCATION_COLUMN (start_loc) != 1)
    return false;

  /* We have a conflict marker.  Construct a location of the form:
       <<<<<<<
       ^~~~~~~
     with start == caret, finishing at the end of the marker.  */
  location_t finish_loc = get_finish (token4->location);
  *out_loc = make_location (start_loc, start_loc, finish_loc);

  return true;
}

/* Get a description of the matching symbol to TOKEN_DESC e.g. "(" for
   RT_CLOSE_PAREN.  */

static const char *
get_matching_symbol (required_token token_desc)
{
  switch (token_desc)
    {
    default:
      gcc_unreachable ();
      return "";
    case RT_CLOSE_BRACE:
      return "{";
    case RT_CLOSE_PAREN:
      return "(";
    }
}

/* Attempt to convert TOKEN_DESC from a required_token to an
   enum cpp_ttype, returning CPP_EOF if there is no good conversion.  */

static enum cpp_ttype
get_required_cpp_ttype (required_token token_desc)
{
  switch (token_desc)
    {
    case RT_SEMICOLON:
      return CPP_SEMICOLON;
    case RT_OPEN_PAREN:
      return CPP_OPEN_PAREN;
    case RT_CLOSE_BRACE:
      return CPP_CLOSE_BRACE;
    case RT_OPEN_BRACE:
      return CPP_OPEN_BRACE;
    case RT_CLOSE_SQUARE:
      return CPP_CLOSE_SQUARE;
    case RT_OPEN_SQUARE:
      return CPP_OPEN_SQUARE;
    case RT_COMMA:
      return CPP_COMMA;
    case RT_COLON:
      return CPP_COLON;
    case RT_CLOSE_PAREN:
      return CPP_CLOSE_PAREN;

    default:
      /* Use CPP_EOF as a "no completions possible" code.  */
      return CPP_EOF;
    }
}


/* Subroutine of cp_parser_error and cp_parser_required_error.

   Issue a diagnostic of the form
      FILE:LINE: MESSAGE before TOKEN
   where TOKEN is the next token in the input stream.  MESSAGE
   (specified by the caller) is usually of the form "expected
   OTHER-TOKEN".

   This bypasses the check for tentative passing, and potentially
   adds material needed by cp_parser_required_error.

   If MISSING_TOKEN_DESC is not RT_NONE, then potentially add fix-it hints
   suggesting insertion of the missing token.

   Additionally, if MATCHING_LOCATION is not UNKNOWN_LOCATION, then we
   have an unmatched symbol at MATCHING_LOCATION; highlight this secondary
   location.  */

static void
cp_parser_error_1 (cp_parser* parser, const char* gmsgid,
		   required_token missing_token_desc,
		   location_t matching_location)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  /* This diagnostic makes more sense if it is tagged to the line
     of the token we just peeked at.  */
  cp_lexer_set_source_position_from_token (token);

  if (token->type == CPP_PRAGMA)
    {
      error_at (token->location,
		"%<#pragma%> is not allowed here");
      cp_parser_skip_to_pragma_eol (parser, token);
      return;
    }

  /* If this is actually a conflict marker, report it as such.  */
  if (token->type == CPP_LSHIFT
      || token->type == CPP_RSHIFT
      || token->type == CPP_EQ_EQ)
    {
      location_t loc;
      if (cp_lexer_peek_conflict_marker (parser->lexer, token->type, &loc))
	{
	  error_at (loc, "version control conflict marker in file");
	  expanded_location token_exploc = expand_location (token->location);
	  /* Consume tokens until the end of the source line.  */
	  for (;;)
	    {
	      cp_lexer_consume_token (parser->lexer);
	      cp_token *next = cp_lexer_peek_token (parser->lexer);
	      if (next->type == CPP_EOF)
		break;
	      if (next->location == UNKNOWN_LOCATION
		  || loc == UNKNOWN_LOCATION)
		break;

	      expanded_location next_exploc = expand_location (next->location);
	      if (next_exploc.file != token_exploc.file)
		break;
	      if (next_exploc.line != token_exploc.line)
		break;
	    }
	  return;
	}
    }

  auto_diagnostic_group d;
  gcc_rich_location richloc (input_location);

  bool added_matching_location = false;

  if (missing_token_desc != RT_NONE)
    if (cp_token *prev_token = cp_lexer_safe_previous_token (parser->lexer))
      {
	/* Potentially supply a fix-it hint, suggesting to add the
	   missing token immediately after the *previous* token.
	   This may move the primary location within richloc.  */
	enum cpp_ttype ttype = get_required_cpp_ttype (missing_token_desc);
	location_t prev_token_loc = prev_token->location;
	maybe_suggest_missing_token_insertion (&richloc, ttype,
					       prev_token_loc);

	/* If matching_location != UNKNOWN_LOCATION, highlight it.
	   Attempt to consolidate diagnostics by printing it as a
	   secondary range within the main diagnostic.  */
	if (matching_location != UNKNOWN_LOCATION)
	  added_matching_location
	    = richloc.add_location_if_nearby (matching_location);
      }

  /* If we were parsing a string-literal and there is an unknown name
     token right after, then check to see if that could also have been
     a literal string by checking the name against a list of known
     standard string literal constants defined in header files. If
     there is one, then add that as an hint to the error message. */
  name_hint h;
  if (token->type == CPP_NAME)
    if (cp_token *prev_token = cp_lexer_safe_previous_token (parser->lexer))
      if (cp_parser_is_string_literal (prev_token))
	{
	  tree name = token->u.value;
	  const char *token_name = IDENTIFIER_POINTER (name);
	  const char *header_hint
	    = get_cp_stdlib_header_for_string_macro_name (token_name);
	  if (header_hint != NULL)
	    h = name_hint (NULL, new suggest_missing_header (token->location,
							     token_name,
							     header_hint));
	}

  /* Actually emit the error.  */
  c_parse_error (gmsgid,
		 /* Because c_parser_error does not understand
		    CPP_KEYWORD, keywords are treated like
		    identifiers.  */
		 (token->type == CPP_KEYWORD ? CPP_NAME : token->type),
		 token->u.value, token->flags, &richloc);

  if (missing_token_desc != RT_NONE)
    {
      /* If we weren't able to consolidate matching_location, then
	 print it as a secondary diagnostic.  */
      if (matching_location != UNKNOWN_LOCATION
	  && !added_matching_location)
	inform (matching_location, "to match this %qs",
		get_matching_symbol (missing_token_desc));
    }
}

/* If not parsing tentatively, issue a diagnostic of the form
      FILE:LINE: MESSAGE before TOKEN
   where TOKEN is the next token in the input stream.  MESSAGE
   (specified by the caller) is usually of the form "expected
   OTHER-TOKEN".  */

static void
cp_parser_error (cp_parser* parser, const char* gmsgid)
{
  if (!cp_parser_simulate_error (parser))
    cp_parser_error_1 (parser, gmsgid, RT_NONE, UNKNOWN_LOCATION);
}

/* Issue an error about name-lookup failing.  NAME is the
   IDENTIFIER_NODE DECL is the result of
   the lookup (as returned from cp_parser_lookup_name).  DESIRED is
   the thing that we hoped to find.  */

static void
cp_parser_name_lookup_error (cp_parser* parser,
			     tree name,
			     tree decl,
			     name_lookup_error desired,
			     location_t location)
{
  /* If name lookup completely failed, tell the user that NAME was not
     declared.  */
  if (decl == error_mark_node)
    {
      if (parser->scope && parser->scope != global_namespace)
	error_at (location, "%<%E::%E%> has not been declared",
		  parser->scope, name);
      else if (parser->scope == global_namespace)
	error_at (location, "%<::%E%> has not been declared", name);
      else if (parser->object_scope
	       && !CLASS_TYPE_P (parser->object_scope))
	error_at (location, "request for member %qE in non-class type %qT",
		  name, parser->object_scope);
      else if (parser->object_scope)
	error_at (location, "%<%T::%E%> has not been declared",
		  parser->object_scope, name);
      else
	error_at (location, "%qE has not been declared", name);
    }
  else if (parser->scope && parser->scope != global_namespace)
    {
      switch (desired)
	{
	  case NLE_TYPE:
	    error_at (location, "%<%E::%E%> is not a type",
	    			parser->scope, name);
	    break;
	  case NLE_CXX98:
	    error_at (location, "%<%E::%E%> is not a class or namespace",
	    			parser->scope, name);
	    break;
	  case NLE_NOT_CXX98:
	    error_at (location,
	    	      "%<%E::%E%> is not a class, namespace, or enumeration",
		      parser->scope, name);
	    break;
	  default:
	    gcc_unreachable ();

	}
    }
  else if (parser->scope == global_namespace)
    {
      switch (desired)
	{
	  case NLE_TYPE:
	    error_at (location, "%<::%E%> is not a type", name);
	    break;
	  case NLE_CXX98:
	    error_at (location, "%<::%E%> is not a class or namespace", name);
	    break;
	  case NLE_NOT_CXX98:
	    error_at (location,
		      "%<::%E%> is not a class, namespace, or enumeration",
		      name);
	    break;
	  default:
	    gcc_unreachable ();
	}
    }
  else
    {
      switch (desired)
	{
	  case NLE_TYPE:
	    error_at (location, "%qE is not a type", name);
	    break;
	  case NLE_CXX98:
	    error_at (location, "%qE is not a class or namespace", name);
	    break;
	  case NLE_NOT_CXX98:
	    error_at (location,
		      "%qE is not a class, namespace, or enumeration", name);
	    break;
	  default:
	    gcc_unreachable ();
	}
    }
}

/* If we are parsing tentatively, remember that an error has occurred
   during this tentative parse.  Returns true if the error was
   simulated; false if a message should be issued by the caller.  */

static bool
cp_parser_simulate_error (cp_parser* parser)
{
  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    {
      parser->context->status = CP_PARSER_STATUS_KIND_ERROR;
      return true;
    }
  return false;
}

/* This function is called when a type is defined.  If type
   definitions are forbidden at this point, an error message is
   issued.  */

static bool
cp_parser_check_type_definition (cp_parser* parser)
{
  /* If types are forbidden here, issue a message.  */
  if (parser->type_definition_forbidden_message)
    {
      /* Don't use `%s' to print the string, because quotations (`%<', `%>')
	 or %qs in the message need to be interpreted.  */
      error (parser->type_definition_forbidden_message,
	     parser->type_definition_forbidden_message_arg);
      return false;
    }
  return true;
}

/* This function is called when the DECLARATOR is processed.  The TYPE
   was a type defined in the decl-specifiers.  If it is invalid to
   define a type in the decl-specifiers for DECLARATOR, an error is
   issued. TYPE_LOCATION is the location of TYPE and is used
   for error reporting.  */

static void
cp_parser_check_for_definition_in_return_type (cp_declarator *declarator,
					       tree type, location_t type_location)
{
  /* [dcl.fct] forbids type definitions in return types.
     Unfortunately, it's not easy to know whether or not we are
     processing a return type until after the fact.  */
  while (declarator
	 && (declarator->kind == cdk_pointer
	     || declarator->kind == cdk_reference
	     || declarator->kind == cdk_ptrmem))
    declarator = declarator->declarator;
  if (declarator
      && declarator->kind == cdk_function)
    {
      error_at (type_location,
		"new types may not be defined in a return type");
      inform (type_location,
	      "(perhaps a semicolon is missing after the definition of %qT)",
	      type);
    }
}

/* A type-specifier (TYPE) has been parsed which cannot be followed by
   "<" in any valid C++ program.  If the next token is indeed "<",
   issue a message warning the user about what appears to be an
   invalid attempt to form a template-id. LOCATION is the location
   of the type-specifier (TYPE) */

static void
cp_parser_check_for_invalid_template_id (cp_parser* parser,
					 tree type,
					 enum tag_types tag_type,
					 location_t location)
{
  cp_token_position start = 0;

  if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    {
      if (TREE_CODE (type) == TYPE_DECL)
	type = TREE_TYPE (type);
      if (TYPE_P (type) && !template_placeholder_p (type))
	error_at (location, "%qT is not a template", type);
      else if (identifier_p (type))
	{
	  if (tag_type != none_type)
	    error_at (location, "%qE is not a class template", type);
	  else
	    error_at (location, "%qE is not a template", type);
	}
      else
	error_at (location, "invalid template-id");
      /* Remember the location of the invalid "<".  */
      if (cp_parser_uncommitted_to_tentative_parse_p (parser))
	start = cp_lexer_token_position (parser->lexer, true);
      /* Consume the "<".  */
      cp_lexer_consume_token (parser->lexer);
      /* Parse the template arguments.  */
      cp_parser_enclosed_template_argument_list (parser);
      /* Permanently remove the invalid template arguments so that
	 this error message is not issued again.  */
      if (start)
	cp_lexer_purge_tokens_after (parser->lexer, start);
    }
}

/* If parsing an integral constant-expression, issue an error message
   about the fact that THING appeared and return true.  Otherwise,
   return false.  In either case, set
   PARSER->NON_INTEGRAL_CONSTANT_EXPRESSION_P.  */

static bool
cp_parser_non_integral_constant_expression (cp_parser  *parser,
					    non_integral_constant thing)
{
  parser->non_integral_constant_expression_p = true;
  if (parser->integral_constant_expression_p)
    {
      if (!parser->allow_non_integral_constant_expression_p)
	{
	  const char *msg = NULL;
	  switch (thing)
	    {
  	      case NIC_FLOAT:
		pedwarn (input_location, OPT_Wpedantic,
			 "ISO C++ forbids using a floating-point literal "
			 "in a constant-expression");
		return true;
	      case NIC_CAST:
		error ("a cast to a type other than an integral or "
		       "enumeration type cannot appear in a "
		       "constant-expression");
		return true;
	      case NIC_TYPEID:
		error ("%<typeid%> operator "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_NCC:
		error ("non-constant compound literals "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_FUNC_CALL:
		error ("a function call "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_INC:
		error ("an increment "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_DEC:
		error ("an decrement "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_ARRAY_REF:
		error ("an array reference "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_ADDR_LABEL:
		error ("the address of a label "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_OVERLOADED:
		error ("calls to overloaded operators "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_ASSIGNMENT:
		error ("an assignment cannot appear in a constant-expression");
		return true;
	      case NIC_COMMA:
		error ("a comma operator "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_CONSTRUCTOR:
		error ("a call to a constructor "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_TRANSACTION:
		error ("a transaction expression "
		       "cannot appear in a constant-expression");
		return true;
	      case NIC_THIS:
		msg = "this";
		break;
	      case NIC_FUNC_NAME:
		msg = "__FUNCTION__";
		break;
  	      case NIC_PRETTY_FUNC:
		msg = "__PRETTY_FUNCTION__";
		break;
	      case NIC_C99_FUNC:
		msg = "__func__";
		break;
	      case NIC_VA_ARG:
		msg = "va_arg";
		break;
	      case NIC_ARROW:
		msg = "->";
		break;
	      case NIC_POINT:
		msg = ".";
		break;
	      case NIC_STAR:
		msg = "*";
		break;
	      case NIC_ADDR:
		msg = "&";
		break;
	      case NIC_PREINCREMENT:
		msg = "++";
		break;
	      case NIC_PREDECREMENT:
		msg = "--";
		break;
	      case NIC_NEW:
		msg = "new";
		break;
	      case NIC_DEL:
		msg = "delete";
		break;
	      default:
		gcc_unreachable ();
	    }
	  if (msg)
	    error ("%qs cannot appear in a constant-expression", msg);
	  return true;
	}
    }
  return false;
}

/* Emit a diagnostic for an invalid type name.  This function commits
   to the current active tentative parse, if any.  (Otherwise, the
   problematic construct might be encountered again later, resulting
   in duplicate error messages.) LOCATION is the location of ID.  */

static void
cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
				      location_t location)
{
  tree decl, ambiguous_decls;
  cp_parser_commit_to_tentative_parse (parser);
  /* Try to lookup the identifier.  */
  decl = cp_parser_lookup_name (parser, id, none_type,
				/*is_template=*/false,
				/*is_namespace=*/false,
				/*check_dependency=*/true,
				&ambiguous_decls, location);
  if (ambiguous_decls)
    /* If the lookup was ambiguous, an error will already have
       been issued.  */
    return;
  /* If the lookup found a template-name, it means that the user forgot
  to specify an argument list. Emit a useful error message.  */
  if (DECL_TYPE_TEMPLATE_P (decl))
    {
      auto_diagnostic_group d;
      error_at (location,
		"invalid use of template-name %qE without an argument list",
		decl);
      if (DECL_CLASS_TEMPLATE_P (decl) && cxx_dialect < cxx17)
	inform (location, "class template argument deduction is only available "
		"with %<-std=c++17%> or %<-std=gnu++17%>");
      inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
    }
  else if (TREE_CODE (id) == BIT_NOT_EXPR)
    error_at (location, "invalid use of destructor %qD as a type", id);
  else if (TREE_CODE (decl) == TYPE_DECL)
    /* Something like 'unsigned A a;'  */
    error_at (location, "invalid combination of multiple type-specifiers");
  else if (!parser->scope)
    {
      /* Issue an error message.  */
      auto_diagnostic_group d;
      name_hint hint;
      if (TREE_CODE (id) == IDENTIFIER_NODE)
	hint = lookup_name_fuzzy (id, FUZZY_LOOKUP_TYPENAME, location);
      if (const char *suggestion = hint.suggestion ())
	{
	  gcc_rich_location richloc (location);
	  richloc.add_fixit_replace (suggestion);
	  error_at (&richloc,
		    "%qE does not name a type; did you mean %qs?",
		    id, suggestion);
	}
      else
	error_at (location, "%qE does not name a type", id);
      /* If we're in a template class, it's possible that the user was
	 referring to a type from a base class.  For example:

	   template <typename T> struct A { typedef T X; };
	   template <typename T> struct B : public A<T> { X x; };

	 The user should have said "typename A<T>::X".  */
      if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR])
	inform (location, "C++11 %<constexpr%> only available with "
		"%<-std=c++11%> or %<-std=gnu++11%>");
      else if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_NOEXCEPT])
	inform (location, "C++11 %<noexcept%> only available with "
		"%<-std=c++11%> or %<-std=gnu++11%>");
      else if (TREE_CODE (id) == IDENTIFIER_NODE
	       && (id_equal (id, "module") || id_equal (id, "import")))
	{
	  if (modules_p ())
	    inform (location, "%qE is not recognized as a module control-line",
		    id);
	  else if (cxx_dialect < cxx20)
	    inform (location, "C++20 %qE only available with %<-fmodules-ts%>",
		    id);
	  else
	    inform (location, "C++20 %qE only available with %<-fmodules-ts%>"
		    ", which is not yet enabled with %<-std=c++20%>", id);
	}
      else if (cxx_dialect < cxx11
	       && TREE_CODE (id) == IDENTIFIER_NODE
	       && id_equal (id, "thread_local"))
	inform (location, "C++11 %<thread_local%> only available with "
		"%<-std=c++11%> or %<-std=gnu++11%>");
      else if (cxx_dialect < cxx20 && id == ridpointers[(int)RID_CONSTINIT])
	inform (location, "C++20 %<constinit%> only available with "
		"%<-std=c++20%> or %<-std=gnu++20%>");
      else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
	inform (location, "%<concept%> only available with %<-std=c++20%> or "
		"%<-fconcepts%>");
      else if (!flag_concepts && id == ridpointers[(int)RID_REQUIRES])
	inform (location, "%<requires%> only available with %<-std=c++20%> or "
		"%<-fconcepts%>");
      else if (processing_template_decl && current_class_type
	       && TYPE_BINFO (current_class_type))
	{
	  for (tree b = TREE_CHAIN (TYPE_BINFO (current_class_type));
	       b; b = TREE_CHAIN (b))
	    {
	      tree base_type = BINFO_TYPE (b);
	      if (CLASS_TYPE_P (base_type)
		  && dependent_type_p (base_type))
		{
		  /* Go from a particular instantiation of the
		     template (which will have an empty TYPE_FIELDs),
		     to the main version.  */
		  base_type = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (base_type);
		  for (tree field = TYPE_FIELDS (base_type);
		       field; field = DECL_CHAIN (field))
		    if (TREE_CODE (field) == TYPE_DECL
			&& DECL_NAME (field) == id)
		      {
			inform (location,
				"(perhaps %<typename %T::%E%> was intended)",
				BINFO_TYPE (b), id);
			goto found;
		      }
		}
	    }
	found:;
	}
    }
  /* Here we diagnose qualified-ids where the scope is actually correct,
     but the identifier does not resolve to a valid type name.  */
  else if (parser->scope != error_mark_node)
    {
      if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
	{
	  auto_diagnostic_group d;
	  name_hint hint;
	  if (decl == error_mark_node)
	    hint = suggest_alternative_in_explicit_scope (location, id,
							  parser->scope);
	  const char *suggestion = hint.suggestion ();
	  gcc_rich_location richloc (location_of (id));
	  if (suggestion)
	    richloc.add_fixit_replace (suggestion);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
	    {
	      if (suggestion)
		error_at (&richloc,
			  "%qE in namespace %qE does not name a template"
			  " type; did you mean %qs?",
			  id, parser->scope, suggestion);
	      else
		error_at (&richloc,
			  "%qE in namespace %qE does not name a template type",
			  id, parser->scope);
	    }
	  else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
	    {
	      if (suggestion)
		error_at (&richloc,
			  "%qE in namespace %qE does not name a template"
			  " type; did you mean %qs?",
			  TREE_OPERAND (id, 0), parser->scope, suggestion);
	      else
		error_at (&richloc,
			  "%qE in namespace %qE does not name a template"
			  " type",
			  TREE_OPERAND (id, 0), parser->scope);
	    }
	  else
	    {
	      if (suggestion)
		error_at (&richloc,
			  "%qE in namespace %qE does not name a type"
			  "; did you mean %qs?",
			  id, parser->scope, suggestion);
	      else
		error_at (&richloc,
			  "%qE in namespace %qE does not name a type",
			  id, parser->scope);
	    }
	  if (DECL_P (decl))
	    inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
	}
      else if (CLASS_TYPE_P (parser->scope)
	       && constructor_name_p (id, parser->scope))
	{
	  /* A<T>::A<T>() */
	  auto_diagnostic_group d;
	  error_at (location, "%<%T::%E%> names the constructor, not"
		    " the type", parser->scope, id);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
	    error_at (location, "and %qT has no template constructors",
		      parser->scope);
	}
      else if (TYPE_P (parser->scope)
	       && dependent_scope_p (parser->scope))
	{
	  gcc_rich_location richloc (location);
	  richloc.add_fixit_insert_before ("typename ");
	  if (TREE_CODE (parser->scope) == TYPENAME_TYPE)
	    error_at (&richloc,
		      "need %<typename%> before %<%T::%D::%E%> because "
		      "%<%T::%D%> is a dependent scope",
		      TYPE_CONTEXT (parser->scope),
		      TYPENAME_TYPE_FULLNAME (parser->scope),
		      id,
		      TYPE_CONTEXT (parser->scope),
		      TYPENAME_TYPE_FULLNAME (parser->scope));
	  else
	    error_at (&richloc, "need %<typename%> before %<%T::%E%> because "
		      "%qT is a dependent scope",
		      parser->scope, id, parser->scope);
	}
      else if (TYPE_P (parser->scope))
	{
	  auto_diagnostic_group d;
	  if (!COMPLETE_TYPE_P (parser->scope))
	    cxx_incomplete_type_error (location_of (id), NULL_TREE,
				       parser->scope);
	  else if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
	    error_at (location_of (id),
		      "%qE in %q#T does not name a template type",
		      id, parser->scope);
	  else if (TREE_CODE (id) == TEMPLATE_ID_EXPR)
	    error_at (location_of (id),
		      "%qE in %q#T does not name a template type",
		      TREE_OPERAND (id, 0), parser->scope);
	  else
	    error_at (location_of (id),
		      "%qE in %q#T does not name a type",
		      id, parser->scope);
	  if (DECL_P (decl))
	    inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
	}
      else
	gcc_unreachable ();
    }
}

/* Check for a common situation where a type-name should be present,
   but is not, and issue a sensible error message.  Returns true if an
   invalid type-name was detected.

   The situation handled by this function are variable declarations of the
   form `ID a', where `ID' is an id-expression and `a' is a plain identifier.
   Usually, `ID' should name a type, but if we got here it means that it
   does not. We try to emit the best possible error message depending on
   how exactly the id-expression looks like.  */

static bool
cp_parser_parse_and_diagnose_invalid_type_name (cp_parser *parser)
{
  tree id;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Avoid duplicate error about ambiguous lookup.  */
  if (token->type == CPP_NESTED_NAME_SPECIFIER)
    {
      cp_token *next = cp_lexer_peek_nth_token (parser->lexer, 2);
      if (next->type == CPP_NAME && next->error_reported)
	goto out;
    }

  cp_parser_parse_tentatively (parser);
  id = cp_parser_id_expression (parser,
				/*template_keyword_p=*/false,
				/*check_dependency_p=*/true,
				/*template_p=*/NULL,
				/*declarator_p=*/true,
				/*optional_p=*/false);
  /* If the next token is a (, this is a function with no explicit return
     type, i.e. constructor, destructor or conversion op.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
      || TREE_CODE (id) == TYPE_DECL)
    {
      cp_parser_abort_tentative_parse (parser);
      return false;
    }
  if (!cp_parser_parse_definitely (parser))
    return false;

  /* Emit a diagnostic for the invalid type.  */
  cp_parser_diagnose_invalid_type_name (parser, id, token->location);
 out:
  /* If we aren't in the middle of a declarator (i.e. in a
     parameter-declaration-clause), skip to the end of the declaration;
     there's no point in trying to process it.  */
  if (!parser->in_declarator_p)
    cp_parser_skip_to_end_of_block_or_statement (parser);
  return true;
}

/* Consume tokens up to, and including, the next non-nested closing `)'.
   Returns 1 iff we found a closing `)'.  RECOVERING is true, if we
   are doing error recovery. Returns -1 if OR_TTYPE is not CPP_EOF and we
   found an unnested token of that type.  */

static int
cp_parser_skip_to_closing_parenthesis_1 (cp_parser *parser,
					 bool recovering,
					 cpp_ttype or_ttype,
					 bool consume_paren)
{
  unsigned paren_depth = 0;
  unsigned brace_depth = 0;
  unsigned square_depth = 0;
  unsigned condop_depth = 0;

  if (recovering && or_ttype == CPP_EOF
      && cp_parser_uncommitted_to_tentative_parse_p (parser))
    return 0;

  while (true)
    {
      cp_token * token = cp_lexer_peek_token (parser->lexer);

      /* Have we found what we're looking for before the closing paren?  */
      if (token->type == or_ttype && or_ttype != CPP_EOF
	  && !brace_depth && !paren_depth && !square_depth && !condop_depth)
	return -1;

      switch (token->type)
	{
	case CPP_PRAGMA_EOL:
	  if (!parser->lexer->in_pragma)
	    break;
	  /* FALLTHRU */
	case CPP_EOF:
	  /* If we've run out of tokens, then there is no closing `)'.  */
	  return 0;

        /* This is good for lambda expression capture-lists.  */
        case CPP_OPEN_SQUARE:
          ++square_depth;
          break;
        case CPP_CLOSE_SQUARE:
          if (!square_depth--)
            return 0;
          break;

	case CPP_SEMICOLON:
	  /* This matches the processing in skip_to_end_of_statement.  */
	  if (!brace_depth)
	    return 0;
	  break;

	case CPP_OPEN_BRACE:
	  ++brace_depth;
	  break;
	case CPP_CLOSE_BRACE:
	  if (!brace_depth--)
	    return 0;
	  break;

	case CPP_OPEN_PAREN:
	  if (!brace_depth)
	    ++paren_depth;
	  break;

	case CPP_CLOSE_PAREN:
	  if (!brace_depth && !paren_depth--)
	    {
	      if (consume_paren)
		cp_lexer_consume_token (parser->lexer);
	      return 1;
	    }
	  break;

	case CPP_QUERY:
	  if (!brace_depth && !paren_depth && !square_depth)
	    ++condop_depth;
	  break;

	case CPP_COLON:
	  if (!brace_depth && !paren_depth && !square_depth && condop_depth > 0)
	    condop_depth--;
	  break;

	case CPP_KEYWORD:
	  if (!cp_token_is_module_directive (token))
	    break;
	  /* FALLTHROUGH  */

	case CPP_PRAGMA:
	  /* We fell into a pragma.  Skip it, and continue. */
	  cp_parser_skip_to_pragma_eol (parser, recovering ? token : nullptr);
	  continue;

	default:
	  break;
	}

      /* Consume the token.  */
      cp_lexer_consume_token (parser->lexer);
    }
}

/* Consume tokens up to, and including, the next non-nested closing `)'.
   Returns 1 iff we found a closing `)'.  RECOVERING is true, if we
   are doing error recovery. Returns -1 if OR_COMMA is true and we
   found an unnested token of that type.  */

static int
cp_parser_skip_to_closing_parenthesis (cp_parser *parser,
				       bool recovering,
				       bool or_comma,
				       bool consume_paren)
{
  cpp_ttype ttype = or_comma ? CPP_COMMA : CPP_EOF;
  return cp_parser_skip_to_closing_parenthesis_1 (parser, recovering,
						  ttype, consume_paren);
}

/* Consume tokens until we reach the end of the current statement.
   Normally, that will be just before consuming a `;'.  However, if a
   non-nested `}' comes first, then we stop before consuming that.  */

static void
cp_parser_skip_to_end_of_statement (cp_parser* parser)
{
  unsigned nesting_depth = 0;

  /* Unwind generic function template scope if necessary.  */
  if (parser->fully_implicit_function_template_p)
    abort_fully_implicit_template (parser);

  while (true)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_PRAGMA_EOL:
	  if (!parser->lexer->in_pragma)
	    break;
	  /* FALLTHRU */
	case CPP_EOF:
	  /* If we've run out of tokens, stop.  */
	  return;

	case CPP_SEMICOLON:
	  /* If the next token is a `;', we have reached the end of the
	     statement.  */
	  if (!nesting_depth)
	    return;
	  break;

	case CPP_CLOSE_BRACE:
	  /* If this is a non-nested '}', stop before consuming it.
	     That way, when confronted with something like:

	       { 3 + }

	     we stop before consuming the closing '}', even though we
	     have not yet reached a `;'.  */
	  if (nesting_depth == 0)
	    return;

	  /* If it is the closing '}' for a block that we have
	     scanned, stop -- but only after consuming the token.
	     That way given:

		void f g () { ... }
		typedef int I;

	     we will stop after the body of the erroneously declared
	     function, but before consuming the following `typedef'
	     declaration.  */
	  if (--nesting_depth == 0)
	    {
	      cp_lexer_consume_token (parser->lexer);
	      return;
	    }
	  break;

	case CPP_OPEN_BRACE:
	  ++nesting_depth;
	  break;

	case CPP_KEYWORD:
	  if (!cp_token_is_module_directive (token))
	    break;
	  /* FALLTHROUGH  */

	case CPP_PRAGMA:
	  /* We fell into a pragma.  Skip it, and continue or return. */
	  cp_parser_skip_to_pragma_eol (parser, token);
	  if (!nesting_depth)
	    return;
	  continue;

	default:
	  break;
	}

      /* Consume the token.  */
      cp_lexer_consume_token (parser->lexer);
    }
}

/* This function is called at the end of a statement or declaration.
   If the next token is a semicolon, it is consumed; otherwise, error
   recovery is attempted.  */

static void
cp_parser_consume_semicolon_at_end_of_statement (cp_parser *parser)
{
  /* Look for the trailing `;'.  */
  if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
    {
      /* If there is additional (erroneous) input, skip to the end of
	 the statement.  */
      cp_parser_skip_to_end_of_statement (parser);
      /* If the next token is now a `;', consume it.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	cp_lexer_consume_token (parser->lexer);
    }
}

/* Skip tokens until we have consumed an entire block, or until we
   have consumed a non-nested `;'.  */

static void
cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
{
  int nesting_depth = 0;

  /* Unwind generic function template scope if necessary.  */
  if (parser->fully_implicit_function_template_p)
    abort_fully_implicit_template (parser);

  while (nesting_depth >= 0)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_PRAGMA_EOL:
	  if (!parser->lexer->in_pragma)
	    break;
	  /* FALLTHRU */
	case CPP_EOF:
	  /* If we've run out of tokens, stop.  */
	  return;

	case CPP_SEMICOLON:
	  /* Stop if this is an unnested ';'. */
	  if (!nesting_depth)
	    nesting_depth = -1;
	  break;

	case CPP_CLOSE_BRACE:
	  /* Stop if this is an unnested '}', or closes the outermost
	     nesting level.  */
	  nesting_depth--;
	  if (nesting_depth < 0)
	    return;
	  if (!nesting_depth)
	    nesting_depth = -1;
	  break;

	case CPP_OPEN_BRACE:
	  /* Nest. */
	  nesting_depth++;
	  break;

	case CPP_KEYWORD:
	  if (!cp_token_is_module_directive (token))
	    break;
	  /* FALLTHROUGH  */

	case CPP_PRAGMA:
	  /* Skip it, and continue or return. */
	  cp_parser_skip_to_pragma_eol (parser, token);
	  if (!nesting_depth)
	    return;
	  continue;

	default:
	  break;
	}

      /* Consume the token.  */
      cp_lexer_consume_token (parser->lexer);
    }
}

/* Skip tokens until a non-nested closing curly brace is the next
   token, or there are no more tokens. Return true in the first case,
   false otherwise.  */

static bool
cp_parser_skip_to_closing_brace (cp_parser *parser)
{
  unsigned nesting_depth = 0;

  while (true)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_PRAGMA_EOL:
	  if (!parser->lexer->in_pragma)
	    break;
	  /* FALLTHRU */
	case CPP_EOF:
	  /* If we've run out of tokens, stop.  */
	  return false;

	case CPP_CLOSE_BRACE:
	  /* If the next token is a non-nested `}', then we have reached
	     the end of the current block.  */
	  if (nesting_depth-- == 0)
	    return true;
	  break;

	case CPP_OPEN_BRACE:
	  /* If it the next token is a `{', then we are entering a new
	     block.  Consume the entire block.  */
	  ++nesting_depth;
	  break;

	default:
	  break;
	}

      /* Consume the token.  */
      cp_lexer_consume_token (parser->lexer);
    }
}

/* Consume tokens until we reach the end of the pragma.  The PRAGMA_TOK
   parameter is the PRAGMA token, allowing us to purge the entire pragma
   sequence.  PRAGMA_TOK can be NULL, if we're speculatively scanning
   forwards (not error recovery).  */

static void
cp_parser_skip_to_pragma_eol (cp_parser* parser, cp_token *pragma_tok)
{
  cp_token *token;

  do
    {
      /* The preprocessor makes sure that a PRAGMA_EOL token appears
         before an EOF token, even when the EOF is on the pragma line.
         We should never get here without being inside a deferred
         pragma.  */
      gcc_checking_assert (cp_lexer_next_token_is_not (parser->lexer, CPP_EOF));
      token = cp_lexer_consume_token (parser->lexer);
    }
  while (token->type != CPP_PRAGMA_EOL);

  if (pragma_tok)
    {
      parser->lexer->in_pragma = false;
      if (parser->lexer->in_omp_attribute_pragma
	  && cp_lexer_next_token_is (parser->lexer, CPP_EOF))
	{
	  parser->lexer = parser->lexer->next;
	  /* Put the current source position back where it was before this
	     lexer was pushed.  */
	  cp_lexer_set_source_position_from_token (parser->lexer->next_token);
	}
    }
}

/* Require pragma end of line, resyncing with it as necessary.  The
   arguments are as for cp_parser_skip_to_pragma_eol.  */

static void
cp_parser_require_pragma_eol (cp_parser *parser, cp_token *pragma_tok)
{
  parser->lexer->in_pragma = false;
  if (!cp_parser_require (parser, CPP_PRAGMA_EOL, RT_PRAGMA_EOL))
    cp_parser_skip_to_pragma_eol (parser, pragma_tok);
  else if (parser->lexer->in_omp_attribute_pragma
	   && cp_lexer_next_token_is (parser->lexer, CPP_EOF))
    {
      parser->lexer = parser->lexer->next;
      /* Put the current source position back where it was before this
	 lexer was pushed.  */
      cp_lexer_set_source_position_from_token (parser->lexer->next_token);
    }
}

/* This is a simple wrapper around make_typename_type. When the id is
   an unresolved identifier node, we can provide a superior diagnostic
   using cp_parser_diagnose_invalid_type_name.  */

static tree
cp_parser_make_typename_type (cp_parser *parser, tree id,
			      location_t id_location)
{
  tree result;
  if (identifier_p (id))
    {
      result = make_typename_type (parser->scope, id, typename_type,
				   /*complain=*/tf_none);
      if (result == error_mark_node)
	cp_parser_diagnose_invalid_type_name (parser, id, id_location);
      return result;
    }
  return make_typename_type (parser->scope, id, typename_type, tf_error);
}

/* This is a wrapper around the
   make_{pointer,ptrmem,reference}_declarator functions that decides
   which one to call based on the CODE and CLASS_TYPE arguments. The
   CODE argument should be one of the values returned by
   cp_parser_ptr_operator.  ATTRIBUTES represent the attributes that
   appertain to the pointer or reference.  */

static cp_declarator *
cp_parser_make_indirect_declarator (enum tree_code code, tree class_type,
				    cp_cv_quals cv_qualifiers,
				    cp_declarator *target,
				    tree attributes)
{
  if (code == ERROR_MARK || target == cp_error_declarator)
    return cp_error_declarator;

  if (code == INDIRECT_REF)
    if (class_type == NULL_TREE)
      return make_pointer_declarator (cv_qualifiers, target, attributes);
    else
      return make_ptrmem_declarator (cv_qualifiers, class_type,
				     target, attributes);
  else if (code == ADDR_EXPR && class_type == NULL_TREE)
    return make_reference_declarator (cv_qualifiers, target,
				      false, attributes);
  else if (code == NON_LVALUE_EXPR && class_type == NULL_TREE)
    return make_reference_declarator (cv_qualifiers, target,
				      true, attributes);
  gcc_unreachable ();
}

/* Create a new C++ parser.  */

static cp_parser *
cp_parser_new (cp_lexer *lexer)
{
  /* Initialize the binops_by_token so that we can get the tree
     directly from the token.  */
  for (unsigned i = 0; i < ARRAY_SIZE (binops); i++)
    binops_by_token[binops[i].token_type] = binops[i];

  cp_parser *parser = ggc_cleared_alloc<cp_parser> ();
  parser->lexer = lexer;
  parser->context = cp_parser_context_new (NULL);

  /* For now, we always accept GNU extensions.  */
  parser->allow_gnu_extensions_p = 1;

  /* The `>' token is a greater-than operator, not the end of a
     template-id.  */
  parser->greater_than_is_operator_p = true;

  parser->default_arg_ok_p = true;

  /* We are not parsing a constant-expression.  */
  parser->integral_constant_expression_p = false;
  parser->allow_non_integral_constant_expression_p = false;
  parser->non_integral_constant_expression_p = false;

  /* Local variable names are not forbidden.  */
  parser->local_variables_forbidden_p = 0;

  /* We are not processing an `extern "C"' declaration.  */
  parser->in_unbraced_linkage_specification_p = false;

  /* We are not processing a declarator.  */
  parser->in_declarator_p = false;

  /* We are not processing a template-argument-list.  */
  parser->in_template_argument_list_p = false;

  /* We are not in an iteration statement.  */
  parser->in_statement = 0;

  /* We are not in a switch statement.  */
  parser->in_switch_statement_p = false;

  /* We are not parsing a type-id inside an expression.  */
  parser->in_type_id_in_expr_p = false;

  /* String literals should be translated to the execution character set.  */
  parser->translate_strings_p = true;

  /* We are not parsing a function body.  */
  parser->in_function_body = false;

  /* We can correct until told otherwise.  */
  parser->colon_corrects_to_scope_p = true;

  /* The unparsed function queue is empty.  */
  push_unparsed_function_queues (parser);

  /* There are no classes being defined.  */
  parser->num_classes_being_defined = 0;

  /* No template parameters apply.  */
  parser->num_template_parameter_lists = 0;

  /* Special parsing data structures.  */
  parser->omp_declare_simd = NULL;
  parser->oacc_routine = NULL;

  /* Not declaring an implicit function template.  */
  parser->auto_is_implicit_function_template_parm_p = false;
  parser->fully_implicit_function_template_p = false;
  parser->implicit_template_parms = 0;
  parser->implicit_template_scope = 0;

  /* Allow constrained-type-specifiers. */
  parser->prevent_constrained_type_specifiers = 0;

  /* We haven't yet seen an 'extern "C"'.  */
  parser->innermost_linkage_specification_location = UNKNOWN_LOCATION;

  return parser;
}

/* Create a cp_lexer structure which will emit the tokens in CACHE
   and push it onto the parser's lexer stack.  This is used for delayed
   parsing of in-class method bodies and default arguments, and should
   not be confused with tentative parsing.  */
static void
cp_parser_push_lexer_for_tokens (cp_parser *parser, cp_token_cache *cache)
{
  cp_lexer *lexer = cp_lexer_new_from_tokens (cache);
  lexer->next = parser->lexer;
  parser->lexer = lexer;

  /* Move the current source position to that of the first token in the
     new lexer.  */
  cp_lexer_set_source_position_from_token (lexer->next_token);
}

/* Pop the top lexer off the parser stack.  This is never used for the
   "main" lexer, only for those pushed by cp_parser_push_lexer_for_tokens.  */
static void
cp_parser_pop_lexer (cp_parser *parser)
{
  cp_lexer *lexer = parser->lexer;
  parser->lexer = lexer->next;
  cp_lexer_destroy (lexer);

  /* Put the current source position back where it was before this
     lexer was pushed.  */
  cp_lexer_set_source_position_from_token (parser->lexer->next_token);
}

/* Lexical conventions [gram.lex]  */

/* Parse an identifier.  Returns an IDENTIFIER_NODE representing the
   identifier.  */

static cp_expr
cp_parser_identifier (cp_parser* parser)
{
  cp_token *token;

  /* Look for the identifier.  */
  token = cp_parser_require (parser, CPP_NAME, RT_NAME);
  /* Return the value.  */
  if (token)
    return cp_expr (token->u.value, token->location);
  else
    return error_mark_node;
}

/* Worker for cp_parser_string_literal and cp_parser_userdef_string_literal.
   Do not call this directly; use either of the above.

   Parse a sequence of adjacent string constants.  Return a
   TREE_STRING representing the combined, nul-terminated string
   constant.  If TRANSLATE is true, translate the string to the
   execution character set.  If WIDE_OK is true, a wide string is
   valid here.  If UDL_OK is true, a string literal with user-defined
   suffix can be used in this context.

   C++98 [lex.string] says that if a narrow string literal token is
   adjacent to a wide string literal token, the behavior is undefined.
   However, C99 6.4.5p4 says that this results in a wide string literal.
   We follow C99 here, for consistency with the C front end.

   This code is largely lifted from lex_string() in c-lex.cc.

   FUTURE: ObjC++ will need to handle @-strings here.  */

static cp_expr
cp_parser_string_literal_common (cp_parser *parser, bool translate,
				 bool wide_ok, bool udl_ok,
				 bool lookup_udlit)
{
  tree value;
  size_t count;
  struct obstack str_ob;
  struct obstack loc_ob;
  cpp_string str, istr, *strs;
  cp_token *tok;
  enum cpp_ttype type, curr_type;
  int have_suffix_p = 0;
  tree string_tree;
  tree suffix_id = NULL_TREE;
  bool curr_tok_is_userdef_p = false;

  tok = cp_lexer_peek_token (parser->lexer);
  if (!cp_parser_is_string_literal (tok))
    {
      cp_parser_error (parser, "expected string-literal");
      return error_mark_node;
    }

  location_t loc = tok->location;

  if (cpp_userdef_string_p (tok->type))
    {
      if (!udl_ok)
	{
	  error_at (loc, "string literal with user-defined suffix "
		    "is invalid in this context");
	  return error_mark_node;
	}
      string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
      curr_type = cpp_userdef_string_remove_type (tok->type);
      curr_tok_is_userdef_p = true;
    }
  else
    {
      string_tree = tok->u.value;
      curr_type = tok->type;
    }
  type = curr_type;

  /* Try to avoid the overhead of creating and destroying an obstack
     for the common case of just one string.  */
  if (!cp_parser_is_string_literal
      (cp_lexer_peek_nth_token (parser->lexer, 2)))
    {
      cp_lexer_consume_token (parser->lexer);

      str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
      str.len = TREE_STRING_LENGTH (string_tree);
      count = 1;

      if (curr_tok_is_userdef_p)
	{
	  suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
	  have_suffix_p = 1;
	  curr_type = cpp_userdef_string_remove_type (tok->type);
	}
      else
	curr_type = tok->type;

      strs = &str;
    }
  else
    {
      location_t last_tok_loc = tok->location;
      gcc_obstack_init (&str_ob);
      gcc_obstack_init (&loc_ob);
      count = 0;

      do
	{
	  cp_lexer_consume_token (parser->lexer);
	  count++;
	  str.text = (const unsigned char *)TREE_STRING_POINTER (string_tree);
	  str.len = TREE_STRING_LENGTH (string_tree);

	  if (curr_tok_is_userdef_p)
	    {
	      tree curr_suffix_id = USERDEF_LITERAL_SUFFIX_ID (tok->u.value);
	      if (have_suffix_p == 0)
		{
		  suffix_id = curr_suffix_id;
		  have_suffix_p = 1;
		}
	      else if (have_suffix_p == 1
		       && curr_suffix_id != suffix_id)
		{
		  error ("inconsistent user-defined literal suffixes"
			 " %qD and %qD in string literal",
			 suffix_id, curr_suffix_id);
		  have_suffix_p = -1;
		}
	      curr_type = cpp_userdef_string_remove_type (tok->type);
	    }
	  else
	    curr_type = tok->type;

	  if (type != curr_type)
	    {
	      if (type == CPP_STRING)
		type = curr_type;
	      else if (curr_type != CPP_STRING)
		{
		  rich_location rich_loc (line_table, tok->location);
		  rich_loc.add_range (last_tok_loc);
		  error_at (&rich_loc,
			    "concatenation of string literals with "
			    "conflicting encoding prefixes");
		}
	    }

	  obstack_grow (&str_ob, &str, sizeof (cpp_string));
	  obstack_grow (&loc_ob, &tok->location, sizeof (location_t));

	  last_tok_loc = tok->location;

	  tok = cp_lexer_peek_token (parser->lexer);
	  if (cpp_userdef_string_p (tok->type))
	    {
	      if (!udl_ok)
		{
		  error_at (loc, "string literal with user-defined suffix "
			    "is invalid in this context");
		  return error_mark_node;
		}
	      string_tree = USERDEF_LITERAL_VALUE (tok->u.value);
	      curr_type = cpp_userdef_string_remove_type (tok->type);
	      curr_tok_is_userdef_p = true;
	    }
	  else
	    {
	      string_tree = tok->u.value;
	      curr_type = tok->type;
	      curr_tok_is_userdef_p = false;
	    }
	}
      while (cp_parser_is_string_literal (tok));

      /* A string literal built by concatenation has its caret=start at
	 the start of the initial string, and its finish at the finish of
	 the final string literal.  */
      loc = make_location (loc, loc, get_finish (last_tok_loc));

      strs = (cpp_string *) obstack_finish (&str_ob);
    }

  if (type != CPP_STRING && !wide_ok)
    {
      cp_parser_error (parser, "a wide string is invalid in this context");
      type = CPP_STRING;
    }

  if ((translate ? cpp_interpret_string : cpp_interpret_string_notranslate)
      (parse_in, strs, count, &istr, type))
    {
      value = build_string (istr.len, (const char *)istr.text);
      free (CONST_CAST (unsigned char *, istr.text));
      if (count > 1)
	{
	  location_t *locs = (location_t *)obstack_finish (&loc_ob);
	  gcc_assert (g_string_concat_db);
	  g_string_concat_db->record_string_concatenation (count, locs);
	}

      switch (type)
	{
	default:
	case CPP_STRING:
	  TREE_TYPE (value) = char_array_type_node;
	  break;
	case CPP_UTF8STRING:
	  if (flag_char8_t)
	    TREE_TYPE (value) = char8_array_type_node;
	  else
	    TREE_TYPE (value) = char_array_type_node;
	  break;
	case CPP_STRING16:
	  TREE_TYPE (value) = char16_array_type_node;
	  break;
	case CPP_STRING32:
	  TREE_TYPE (value) = char32_array_type_node;
	  break;
	case CPP_WSTRING:
	  TREE_TYPE (value) = wchar_array_type_node;
	  break;
	}

      value = fix_string_type (value);

      if (have_suffix_p)
	{
	  tree literal = build_userdef_literal (suffix_id, value,
						OT_NONE, NULL_TREE);
	  if (lookup_udlit)
	    value = finish_userdef_string_literal (literal);
	  else
	    value = literal;
	}
    }
  else
    /* cpp_interpret_string has issued an error.  */
    value = error_mark_node;

  if (count > 1)
    {
      obstack_free (&str_ob, 0);
      obstack_free (&loc_ob, 0);
    }

  return cp_expr (value, loc);
}

/* Parse a sequence of adjacent string constants.  Return a TREE_STRING
   representing the combined, nul-terminated string constant.  If
   TRANSLATE is true, translate the string to the execution character set.
   If WIDE_OK is true, a wide string is valid here.

   This function issues an error if a user defined string literal is
   encountered; use cp_parser_userdef_string_literal if UDLs are allowed.  */

static inline cp_expr
cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok)
{
  return cp_parser_string_literal_common (parser, translate, wide_ok,
					  /*udl_ok=*/false,
					  /*lookup_udlit=*/false);
}

/* Parse a string literal or user defined string literal.

   user-defined-string-literal :
     string-literal ud-suffix

   If LOOKUP_UDLIT, perform a lookup for a suitable template function.  */

static inline cp_expr
cp_parser_userdef_string_literal (cp_parser *parser, bool lookup_udlit)
{
  return cp_parser_string_literal_common (parser, /*translate=*/true,
					  /*wide_ok=*/true, /*udl_ok=*/true,
					  lookup_udlit);
}

/* Look up a literal operator with the name and the exact arguments.  */

static tree
lookup_literal_operator (tree name, vec<tree, va_gc> *args)
{
  tree decl = lookup_name (name);
  if (!decl || !is_overloaded_fn (decl))
    return error_mark_node;

  for (lkp_iterator iter (decl); iter; ++iter)
    {
      tree fn = *iter;

      if (tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (fn)))
	{
	  unsigned int ix;
	  bool found = true;

	  for (ix = 0;
	       found && ix < vec_safe_length (args) && parmtypes != NULL_TREE;
	       ++ix, parmtypes = TREE_CHAIN (parmtypes))
	    {
	      tree tparm = TREE_VALUE (parmtypes);
	      tree targ = TREE_TYPE ((*args)[ix]);
	      bool ptr = TYPE_PTR_P (tparm);
	      bool arr = TREE_CODE (targ) == ARRAY_TYPE;
	      if ((ptr || arr || !same_type_p (tparm, targ))
		  && (!ptr || !arr
		      || !same_type_p (TREE_TYPE (tparm),
				       TREE_TYPE (targ))))
		found = false;
	    }

	  if (found
	      && ix == vec_safe_length (args)
	      /* May be this should be sufficient_parms_p instead,
		 depending on how exactly should user-defined literals
		 work in presence of default arguments on the literal
		 operator parameters.  */
	      && parmtypes == void_list_node)
	    return decl;
	}
    }

  return error_mark_node;
}

/* Parse a user-defined char constant.  Returns a call to a user-defined
   literal operator taking the character as an argument.  */

static cp_expr
cp_parser_userdef_char_literal (cp_parser *parser)
{
  cp_token *token = cp_lexer_consume_token (parser->lexer);
  tree literal = token->u.value;
  tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
  tree value = USERDEF_LITERAL_VALUE (literal);
  tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
  tree decl, result;

  /* Build up a call to the user-defined operator  */
  /* Lookup the name we got back from the id-expression.  */
  releasing_vec args;
  vec_safe_push (args, value);
  decl = lookup_literal_operator (name, args);
  if (!decl || decl == error_mark_node)
    {
      error ("unable to find character literal operator %qD with %qT argument",
	     name, TREE_TYPE (value));
      return error_mark_node;
    }
  result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
  return result;
}

/* A subroutine of cp_parser_userdef_numeric_literal to
   create a char... template parameter pack from a string node.  */

static tree
make_char_string_pack (tree value)
{
  tree charvec;
  tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
  const unsigned char *str
    = (const unsigned char *) TREE_STRING_POINTER (value);
  int i, len = TREE_STRING_LENGTH (value) - 1;
  tree argvec = make_tree_vec (1);

  /* Fill in CHARVEC with all of the parameters.  */
  charvec = make_tree_vec (len);
  for (i = 0; i < len; ++i)
    {
      unsigned char s[3] = { '\'', str[i], '\'' };
      cpp_string in = { 3, s };
      cpp_string out = { 0, 0 };
      if (!cpp_interpret_string (parse_in, &in, 1, &out, CPP_STRING))
	return NULL_TREE;
      gcc_assert (out.len == 2);
      TREE_VEC_ELT (charvec, i) = build_int_cst (char_type_node,
						 out.text[0]);
    }

  /* Build the argument packs.  */
  ARGUMENT_PACK_ARGS (argpack) = charvec;

  TREE_VEC_ELT (argvec, 0) = argpack;

  return argvec;
}

/* A subroutine of cp_parser_userdef_numeric_literal to
   create a char... template parameter pack from a string node.  */

static tree
make_string_pack (tree value)
{
  tree charvec;
  tree argpack = make_node (NONTYPE_ARGUMENT_PACK);
  const unsigned char *str
    = (const unsigned char *) TREE_STRING_POINTER (value);
  int sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value))));
  int len = TREE_STRING_LENGTH (value) / sz - 1;
  tree argvec = make_tree_vec (2);

  tree str_char_type_node = TREE_TYPE (TREE_TYPE (value));
  str_char_type_node = TYPE_MAIN_VARIANT (str_char_type_node);

  /* First template parm is character type.  */
  TREE_VEC_ELT (argvec, 0) = str_char_type_node;

  /* Fill in CHARVEC with all of the parameters.  */
  charvec = make_tree_vec (len);
  for (int i = 0; i < len; ++i)
    TREE_VEC_ELT (charvec, i)
      = double_int_to_tree (str_char_type_node,
			    double_int::from_buffer (str + i * sz, sz));

  /* Build the argument packs.  */
  ARGUMENT_PACK_ARGS (argpack) = charvec;

  TREE_VEC_ELT (argvec, 1) = argpack;

  return argvec;
}

/* Parse a user-defined numeric constant.  returns a call to a user-defined
   literal operator.  */

static cp_expr
cp_parser_userdef_numeric_literal (cp_parser *parser)
{
  cp_token *token = cp_lexer_consume_token (parser->lexer);
  tree literal = token->u.value;
  tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
  tree value = USERDEF_LITERAL_VALUE (literal);
  int overflow = USERDEF_LITERAL_OVERFLOW (literal);
  tree num_string = USERDEF_LITERAL_NUM_STRING (literal);
  tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
  tree decl, result;

  /* Look for a literal operator taking the exact type of numeric argument
     as the literal value.  */
  releasing_vec args;
  vec_safe_push (args, value);
  decl = lookup_literal_operator (name, args);
  if (decl && decl != error_mark_node)
    {
      result = finish_call_expr (decl, &args, false, true,
				 tf_warning_or_error);

      if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0)
	{
	  warning_at (token->location, OPT_Woverflow,
		      "integer literal exceeds range of %qT type",
		      long_long_unsigned_type_node);
	}
      else
	{
	  if (overflow > 0)
	    warning_at (token->location, OPT_Woverflow,
			"floating literal exceeds range of %qT type",
			long_double_type_node);
	  else if (overflow < 0)
	    warning_at (token->location, OPT_Woverflow,
			"floating literal truncated to zero");
	}

      return result;
    }

  /* If the numeric argument didn't work, look for a raw literal
     operator taking a const char* argument consisting of the number
     in string format.  */
  args->truncate (0);
  vec_safe_push (args, num_string);
  decl = lookup_literal_operator (name, args);
  if (decl && decl != error_mark_node)
    {
      result = finish_call_expr (decl, &args, false, true,
				 tf_warning_or_error);
      return result;
    }

  /* If the raw literal didn't work, look for a non-type template
     function with parameter pack char....  Call the function with
     template parameter characters representing the number.  */
  args->truncate (0);
  decl = lookup_literal_operator (name, args);
  if (decl && decl != error_mark_node)
    {
      tree tmpl_args = make_char_string_pack (num_string);
      if (tmpl_args == NULL_TREE)
	{
	  error ("failed to translate literal to execution character set %qT",
		 num_string);
	  return error_mark_node;
	}
      decl = lookup_template_function (decl, tmpl_args);
      result = finish_call_expr (decl, &args, false, true,
				 tf_warning_or_error);
      return result;
    }

  /* In C++14 the standard library defines complex number suffixes that
     conflict with GNU extensions.  Prefer them if <complex> is #included.  */
  bool ext = cpp_get_options (parse_in)->ext_numeric_literals;
  bool i14 = (cxx_dialect > cxx11
	      && (id_equal (suffix_id, "i")
		  || id_equal (suffix_id, "if")
		  || id_equal (suffix_id, "il")));
  diagnostic_t kind = DK_ERROR;
  int opt = 0;

  if (i14 && ext)
    {
      tree cxlit = lookup_qualified_name (std_node, "complex_literals",
					  LOOK_want::NORMAL, false);
      if (cxlit == error_mark_node)
	{
	  /* No <complex>, so pedwarn and use GNU semantics.  */
	  kind = DK_PEDWARN;
	  opt = OPT_Wpedantic;
	}
    }

  bool complained
    = emit_diagnostic (kind, input_location, opt,
		       "unable to find numeric literal operator %qD", name);

  if (!complained)
    /* Don't inform either.  */;
  else if (i14)
    {
      inform (token->location, "add %<using namespace std::complex_literals%> "
	      "(from %<<complex>%>) to enable the C++14 user-defined literal "
	      "suffixes");
      if (ext)
	inform (token->location, "or use %<j%> instead of %<i%> for the "
		"GNU built-in suffix");
    }
  else if (!ext)
    inform (token->location, "use %<-fext-numeric-literals%> "
	    "to enable more built-in suffixes");

  if (kind == DK_ERROR)
    value = error_mark_node;
  else
    {
      /* Use the built-in semantics.  */
      tree type;
      if (id_equal (suffix_id, "i"))
	{
	  if (TREE_CODE (value) == INTEGER_CST)
	    type = integer_type_node;
	  else
	    type = double_type_node;
	}
      else if (id_equal (suffix_id, "if"))
	type = float_type_node;
      else /* if (id_equal (suffix_id, "il")) */
	type = long_double_type_node;

      value = fold_build2 (COMPLEX_EXPR, build_complex_type (type),
			   build_zero_cst (type), fold_convert (type, value));
    }

  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    /* Avoid repeated diagnostics.  */
    token->u.value = value;
  return value;
}

/* Parse a user-defined string constant.  Returns a call to a user-defined
   literal operator taking a character pointer and the length of the string
   as arguments.  */

static tree
finish_userdef_string_literal (tree literal)
{
  tree suffix_id = USERDEF_LITERAL_SUFFIX_ID (literal);
  tree name = cp_literal_operator_id (IDENTIFIER_POINTER (suffix_id));
  tree value = USERDEF_LITERAL_VALUE (literal);
  int len = TREE_STRING_LENGTH (value)
	/ TREE_INT_CST_LOW (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (value)))) - 1;
  tree decl;

  /* Build up a call to the user-defined operator.  */
  /* Lookup the name we got back from the id-expression.  */
  releasing_vec args;
  vec_safe_push (args, value);
  vec_safe_push (args, build_int_cst (size_type_node, len));
  decl = lookup_literal_operator (name, args);

  if (decl && decl != error_mark_node)
    return finish_call_expr (decl, &args, false, true,
			     tf_warning_or_error);

  /* Look for a suitable template function, either (C++20) with a single
     parameter of class type, or (N3599) with typename parameter CharT and
     parameter pack CharT...  */
  args->truncate (0);
  decl = lookup_literal_operator (name, args);
  if (decl && decl != error_mark_node)
    {
      /* Use resolve_nondeduced_context to try to choose one form of template
	 or the other.  */
      tree tmpl_args = make_tree_vec (1);
      TREE_VEC_ELT (tmpl_args, 0) = value;
      decl = lookup_template_function (decl, tmpl_args);
      tree res = resolve_nondeduced_context (decl, tf_none);
      if (DECL_P (res))
	decl = res;
      else
	{
	  TREE_OPERAND (decl, 1) = make_string_pack (value);
	  res = resolve_nondeduced_context (decl, tf_none);
	  if (DECL_P (res))
	    decl = res;
	}
      if (!DECL_P (decl) && cxx_dialect > cxx17)
	TREE_OPERAND (decl, 1) = tmpl_args;
      return finish_call_expr (decl, &args, false, true,
			       tf_warning_or_error);
    }

  error ("unable to find string literal operator %qD with %qT, %qT arguments",
	 name, TREE_TYPE (value), size_type_node);
  return error_mark_node;
}


/* Basic concepts [gram.basic]  */

/* Parse a translation-unit.

   translation-unit:
     declaration-seq [opt]  */

static void
cp_parser_translation_unit (cp_parser* parser)
{
  gcc_checking_assert (!cp_error_declarator);

  /* Create the declarator obstack.  */
  gcc_obstack_init (&declarator_obstack);
  /* Create the error declarator.  */
  cp_error_declarator = make_declarator (cdk_error);
  /* Create the empty parameter list.  */
  no_parameters = make_parameter_declarator (NULL, NULL, NULL_TREE,
					     UNKNOWN_LOCATION);
  /* Remember where the base of the declarator obstack lies.  */
  void *declarator_obstack_base = obstack_next_free (&declarator_obstack);

  push_deferring_access_checks (flag_access_control
				? dk_no_deferred : dk_no_check);

  module_parse mp_state = MP_NOT_MODULE;
  if (modules_p () && !header_module_p ())
    mp_state = MP_FIRST;

  bool implicit_extern_c = false;

  /* Parse until EOF.  */
  for (;;)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      /* If we're entering or exiting a region that's implicitly
	 extern "C", modify the lang context appropriately.  This is
	 so horrible.  Please die.   */
      if (implicit_extern_c
	  != cp_lexer_peek_token (parser->lexer)->implicit_extern_c)
	{
	  implicit_extern_c = !implicit_extern_c;
	  if (implicit_extern_c)
	    push_lang_context (lang_name_c);
	  else
	    pop_lang_context ();
	}

      if (token->type == CPP_EOF)
	break;

      if (modules_p ())
	{
	  /* Top-level module declarations are ok, and change the
	     portion of file we're in.  Top-level import declarations
	     are significant for the import portions.  */

	  cp_token *next = token;
	  bool exporting = token->keyword == RID__EXPORT;
	  if (exporting)
	    {
	      cp_lexer_consume_token (parser->lexer);
	      next = cp_lexer_peek_token (parser->lexer);
	    }
	  if (next->keyword == RID__MODULE)
	    {
	      mp_state
		= cp_parser_module_declaration (parser, mp_state, exporting);
	      continue;
	    }
	  else if (next->keyword == RID__IMPORT)
	    {
	      if (mp_state == MP_FIRST)
		mp_state = MP_NOT_MODULE;
	      cp_parser_import_declaration (parser, mp_state, exporting);
	      continue;
	    }
	  else
	    gcc_checking_assert (!exporting);

	  if (mp_state == MP_GLOBAL && token->main_source_p)
	    {
	      static bool warned = false;
	      if (!warned)
		{
		  warned = true;
		  error_at (token->location,
			    "global module fragment contents must be"
			    " from preprocessor inclusion");
		}
	    }
	}

      /* This relies on the ordering of module_parse values.  */
      if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS)
	/* We're no longer in the import portion of a named module.  */
	mp_state = module_parse (mp_state + 1);
      else if (mp_state == MP_FIRST)
	mp_state = MP_NOT_MODULE;

      if (token->type == CPP_CLOSE_BRACE)
	{
	  cp_parser_error (parser, "expected declaration");
	  cp_lexer_consume_token (parser->lexer);
	  /* If the next token is now a `;', consume it.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	    cp_lexer_consume_token (parser->lexer);
	}
      else
	cp_parser_toplevel_declaration (parser);
    }

  /* Get rid of the token array; we don't need it any more.  */
  cp_lexer_destroy (parser->lexer);
  parser->lexer = NULL;

  /* The EOF should have reset this. */
  gcc_checking_assert (!implicit_extern_c);

  /* Make sure the declarator obstack was fully cleaned up.  */
  gcc_assert (obstack_next_free (&declarator_obstack)
	      == declarator_obstack_base);
}

/* Return the appropriate tsubst flags for parsing, possibly in N3276
   decltype context.  */

static inline tsubst_flags_t
complain_flags (bool decltype_p)
{
  tsubst_flags_t complain = tf_warning_or_error;
  if (decltype_p)
    complain |= tf_decltype;
  return complain;
}

/* We're about to parse a collection of statements.  If we're currently
   parsing tentatively, set up a firewall so that any nested
   cp_parser_commit_to_tentative_parse won't affect the current context.  */

static cp_token_position
cp_parser_start_tentative_firewall (cp_parser *parser)
{
  if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
    return 0;

  cp_parser_parse_tentatively (parser);
  cp_parser_commit_to_topmost_tentative_parse (parser);
  return cp_lexer_token_position (parser->lexer, false);
}

/* We've finished parsing the collection of statements.  Wrap up the
   firewall and replace the relevant tokens with the parsed form.  */

static void
cp_parser_end_tentative_firewall (cp_parser *parser, cp_token_position start,
				  tree expr)
{
  if (!start)
    return;

  /* Finish the firewall level.  */
  cp_parser_parse_definitely (parser);
  /* And remember the result of the parse for when we try again.  */
  cp_token *token = cp_lexer_token_at (parser->lexer, start);
  token->type = CPP_PREPARSED_EXPR;
  token->u.value = expr;
  token->keyword = RID_MAX;
  cp_lexer_purge_tokens_after (parser->lexer, start);
}

/* Like the above functions, but let the user modify the tokens.  Used by
   CPP_DECLTYPE and CPP_TEMPLATE_ID, where we are saving the side-effects for
   later parses, so it makes sense to localize the effects of
   cp_parser_commit_to_tentative_parse.  */

struct tentative_firewall
{
  cp_parser *parser;
  bool set;

  tentative_firewall (cp_parser *p): parser(p)
  {
    /* If we're currently parsing tentatively, start a committed level as a
       firewall and then an inner tentative parse.  */
    if ((set = cp_parser_uncommitted_to_tentative_parse_p (parser)))
      {
	cp_parser_parse_tentatively (parser);
	cp_parser_commit_to_topmost_tentative_parse (parser);
	cp_parser_parse_tentatively (parser);
      }
  }

  ~tentative_firewall()
  {
    if (set)
      {
	/* Finish the inner tentative parse and the firewall, propagating any
	   uncommitted error state to the outer tentative parse.  */
	bool err = cp_parser_error_occurred (parser);
	cp_parser_parse_definitely (parser);
	cp_parser_parse_definitely (parser);
	if (err)
	  cp_parser_simulate_error (parser);
      }
  }
};

/* Some tokens naturally come in pairs e.g.'(' and ')'.
   This class is for tracking such a matching pair of symbols.
   In particular, it tracks the location of the first token,
   so that if the second token is missing, we can highlight the
   location of the first token when notifying the user about the
   problem.  */

template <typename traits_t>
class token_pair
{
 public:
  /* token_pair's ctor.  */
  token_pair () : m_open_loc (UNKNOWN_LOCATION) {}

  /* If the next token is the opening symbol for this pair, consume it and
     return true.
     Otherwise, issue an error and return false.
     In either case, record the location of the opening token.  */

  bool require_open (cp_parser *parser)
  {
    m_open_loc = cp_lexer_peek_token (parser->lexer)->location;
    return cp_parser_require (parser, traits_t::open_token_type,
			      traits_t::required_token_open);
  }

  /* Consume the next token from PARSER, recording its location as
     that of the opening token within the pair.  */

  cp_token * consume_open (cp_parser *parser)
  {
    cp_token *tok = cp_lexer_consume_token (parser->lexer);
    gcc_assert (tok->type == traits_t::open_token_type);
    m_open_loc = tok->location;
    return tok;
  }

  /* If the next token is the closing symbol for this pair, consume it
     and return it.
     Otherwise, issue an error, highlighting the location of the
     corresponding opening token, and return NULL.  */

  cp_token *require_close (cp_parser *parser) const
  {
    return cp_parser_require (parser, traits_t::close_token_type,
			      traits_t::required_token_close,
			      m_open_loc);
  }

  location_t open_location () const { return m_open_loc; }

 private:
  location_t m_open_loc;
};

/* Traits for token_pair<T> for tracking matching pairs of parentheses.  */

struct matching_paren_traits
{
  static const enum cpp_ttype open_token_type = CPP_OPEN_PAREN;
  static const enum required_token required_token_open  = RT_OPEN_PAREN;
  static const enum cpp_ttype close_token_type = CPP_CLOSE_PAREN;
  static const enum required_token required_token_close = RT_CLOSE_PAREN;
};

/* "matching_parens" is a token_pair<T> class for tracking matching
   pairs of parentheses.  */

typedef token_pair<matching_paren_traits> matching_parens;

/* Traits for token_pair<T> for tracking matching pairs of braces.  */

struct matching_brace_traits
{
  static const enum cpp_ttype open_token_type = CPP_OPEN_BRACE;
  static const enum required_token required_token_open = RT_OPEN_BRACE;
  static const enum cpp_ttype close_token_type = CPP_CLOSE_BRACE;
  static const enum required_token required_token_close = RT_CLOSE_BRACE;
};

/* "matching_braces" is a token_pair<T> class for tracking matching
   pairs of braces.  */

typedef token_pair<matching_brace_traits> matching_braces;


/* Parse a GNU statement-expression, i.e. ({ stmts }), except for the
   enclosing parentheses.  */

static cp_expr
cp_parser_statement_expr (cp_parser *parser)
{
  cp_token_position start = cp_parser_start_tentative_firewall (parser);

  /* Consume the '('.  */
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
  matching_parens parens;
  parens.consume_open (parser);
  /* Start the statement-expression.  */
  tree expr = begin_stmt_expr ();
  /* Parse the compound-statement.  */
  cp_parser_compound_statement (parser, expr, BCS_STMT_EXPR, false);
  /* Finish up.  */
  expr = finish_stmt_expr (expr, false);
  /* Consume the ')'.  */
  location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
  if (!parens.require_close (parser))
    cp_parser_skip_to_end_of_statement (parser);

  cp_parser_end_tentative_firewall (parser, start, expr);
  location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
  return cp_expr (expr, combined_loc);
}

/* Expressions [gram.expr] */

/* Parse a fold-operator.

    fold-operator:
        -  *  /  %  ^  &  |  =  <  >  <<  >>
      =  -=  *=  /=  %=  ^=  &=  |=  <<=  >>=
      ==  !=  <=  >=  &&  ||  ,  .*  ->*

   This returns the tree code corresponding to the matched operator
   as an int. When the current token matches a compound assignment
   operator, the resulting tree code is the negative value of the
   non-assignment operator. */

static int
cp_parser_fold_operator (cp_token *token)
{
  switch (token->type)
    {
    case CPP_PLUS: return PLUS_EXPR;
    case CPP_MINUS: return MINUS_EXPR;
    case CPP_MULT: return MULT_EXPR;
    case CPP_DIV: return TRUNC_DIV_EXPR;
    case CPP_MOD: return TRUNC_MOD_EXPR;
    case CPP_XOR: return BIT_XOR_EXPR;
    case CPP_AND: return BIT_AND_EXPR;
    case CPP_OR: return BIT_IOR_EXPR;
    case CPP_LSHIFT: return LSHIFT_EXPR;
    case CPP_RSHIFT: return RSHIFT_EXPR;

    case CPP_EQ: return -NOP_EXPR;
    case CPP_PLUS_EQ: return -PLUS_EXPR;
    case CPP_MINUS_EQ: return -MINUS_EXPR;
    case CPP_MULT_EQ: return -MULT_EXPR;
    case CPP_DIV_EQ: return -TRUNC_DIV_EXPR;
    case CPP_MOD_EQ: return -TRUNC_MOD_EXPR;
    case CPP_XOR_EQ: return -BIT_XOR_EXPR;
    case CPP_AND_EQ: return -BIT_AND_EXPR;
    case CPP_OR_EQ: return -BIT_IOR_EXPR;
    case CPP_LSHIFT_EQ: return -LSHIFT_EXPR;
    case CPP_RSHIFT_EQ: return -RSHIFT_EXPR;

    case CPP_EQ_EQ: return EQ_EXPR;
    case CPP_NOT_EQ: return NE_EXPR;
    case CPP_LESS: return LT_EXPR;
    case CPP_GREATER: return GT_EXPR;
    case CPP_LESS_EQ: return LE_EXPR;
    case CPP_GREATER_EQ: return GE_EXPR;

    case CPP_AND_AND: return TRUTH_ANDIF_EXPR;
    case CPP_OR_OR: return TRUTH_ORIF_EXPR;

    case CPP_COMMA: return COMPOUND_EXPR;

    case CPP_DOT_STAR: return DOTSTAR_EXPR;
    case CPP_DEREF_STAR: return MEMBER_REF;

    default: return ERROR_MARK;
    }
}

/* Returns true if CODE indicates a binary expression, which is not allowed in
   the LHS of a fold-expression.  More codes will need to be added to use this
   function in other contexts.  */

static bool
is_binary_op (tree_code code)
{
  switch (code)
    {
    case PLUS_EXPR:
    case POINTER_PLUS_EXPR:
    case MINUS_EXPR:
    case MULT_EXPR:
    case TRUNC_DIV_EXPR:
    case TRUNC_MOD_EXPR:
    case BIT_XOR_EXPR:
    case BIT_AND_EXPR:
    case BIT_IOR_EXPR:
    case LSHIFT_EXPR:
    case RSHIFT_EXPR:

    case MODOP_EXPR:

    case EQ_EXPR:
    case NE_EXPR:
    case LE_EXPR:
    case GE_EXPR:
    case LT_EXPR:
    case GT_EXPR:

    case TRUTH_ANDIF_EXPR:
    case TRUTH_ORIF_EXPR:

    case COMPOUND_EXPR:

    case DOTSTAR_EXPR:
    case MEMBER_REF:
      return true;

    default:
      return false;
    }
}

/* If the next token is a suitable fold operator, consume it and return as
   the function above.  */

static int
cp_parser_fold_operator (cp_parser *parser)
{
  cp_token* token = cp_lexer_peek_token (parser->lexer);
  int code = cp_parser_fold_operator (token);
  if (code != ERROR_MARK)
    cp_lexer_consume_token (parser->lexer);
  return code;
}

/* Parse a fold-expression.

     fold-expression:
       ( ... folding-operator cast-expression)
       ( cast-expression folding-operator ... )
       ( cast-expression folding operator ... folding-operator cast-expression)

   Note that the '(' and ')' are matched in primary expression. */

static cp_expr
cp_parser_fold_expression (cp_parser *parser, tree expr1)
{
  cp_id_kind pidk;

  // Left fold.
  if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    {
      if (expr1)
	return error_mark_node;
      cp_lexer_consume_token (parser->lexer);
      int op = cp_parser_fold_operator (parser);
      if (op == ERROR_MARK)
        {
          cp_parser_error (parser, "expected binary operator");
          return error_mark_node;
        }

      tree expr = cp_parser_cast_expression (parser, false, false,
					     false, &pidk);
      if (expr == error_mark_node)
        return error_mark_node;
      return finish_left_unary_fold_expr (expr, op);
    }

  const cp_token* token = cp_lexer_peek_token (parser->lexer);
  int op = cp_parser_fold_operator (parser);
  if (op == ERROR_MARK)
    {
      cp_parser_error (parser, "expected binary operator");
      return error_mark_node;
    }

  if (cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS))
    {
      cp_parser_error (parser, "expected ...");
      return error_mark_node;
    }
  cp_lexer_consume_token (parser->lexer);

  /* The operands of a fold-expression are cast-expressions, so binary or
     conditional expressions are not allowed.  We check this here to avoid
     tentative parsing.  */
  if (EXPR_P (expr1) && warning_suppressed_p (expr1, OPT_Wparentheses))
    /* OK, the expression was parenthesized.  */;
  else if (is_binary_op (TREE_CODE (expr1)))
    error_at (location_of (expr1),
	      "binary expression in operand of fold-expression");
  else if (TREE_CODE (expr1) == COND_EXPR
	   || (REFERENCE_REF_P (expr1)
	       && TREE_CODE (TREE_OPERAND (expr1, 0)) == COND_EXPR))
    error_at (location_of (expr1),
	      "conditional expression in operand of fold-expression");

  // Right fold.
  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
    return finish_right_unary_fold_expr (expr1, op);

  if (cp_lexer_next_token_is_not (parser->lexer, token->type))
    {
      cp_parser_error (parser, "mismatched operator in fold-expression");
      return error_mark_node;
    }
  cp_lexer_consume_token (parser->lexer);

  // Binary left or right fold.
  tree expr2 = cp_parser_cast_expression (parser, false, false, false, &pidk);
  if (expr2 == error_mark_node)
    return error_mark_node;
  return finish_binary_fold_expr (expr1, expr2, op);
}

/* Parse a primary-expression.

   primary-expression:
     literal
     this
     ( expression )
     id-expression
     lambda-expression (C++11)

   GNU Extensions:

   primary-expression:
     ( compound-statement )
     __builtin_va_arg ( assignment-expression , type-id )
     __builtin_offsetof ( type-id , offsetof-expression )

   C++ Extensions:
     __has_nothrow_assign ( type-id )
     __has_nothrow_constructor ( type-id )
     __has_nothrow_copy ( type-id )
     __has_trivial_assign ( type-id )
     __has_trivial_constructor ( type-id )
     __has_trivial_copy ( type-id )
     __has_trivial_destructor ( type-id )
     __has_virtual_destructor ( type-id )
     __is_abstract ( type-id )
     __is_base_of ( type-id , type-id )
     __is_class ( type-id )
     __is_empty ( type-id )
     __is_enum ( type-id )
     __is_final ( type-id )
     __is_literal_type ( type-id )
     __is_pod ( type-id )
     __is_polymorphic ( type-id )
     __is_std_layout ( type-id )
     __is_trivial ( type-id )
     __is_union ( type-id )

   Objective-C++ Extension:

   primary-expression:
     objc-expression

   literal:
     __null

   ADDRESS_P is true iff this expression was immediately preceded by
   "&" and therefore might denote a pointer-to-member.  CAST_P is true
   iff this expression is the target of a cast.  TEMPLATE_ARG_P is
   true iff this expression is a template argument.

   Returns a representation of the expression.  Upon return, *IDK
   indicates what kind of id-expression (if any) was present.  */

static cp_expr
cp_parser_primary_expression (cp_parser *parser,
			      bool address_p,
			      bool cast_p,
			      bool template_arg_p,
			      bool decltype_p,
			      cp_id_kind *idk)
{
  cp_token *token = NULL;

  /* Assume the primary expression is not an id-expression.  */
  *idk = CP_ID_KIND_NONE;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  switch ((int) token->type)
    {
      /* literal:
	   integer-literal
	   character-literal
	   floating-literal
	   string-literal
	   boolean-literal
	   pointer-literal
	   user-defined-literal  */
    case CPP_CHAR:
    case CPP_CHAR16:
    case CPP_CHAR32:
    case CPP_WCHAR:
    case CPP_UTF8CHAR:
    case CPP_NUMBER:
    case CPP_PREPARSED_EXPR:
      if (TREE_CODE (token->u.value) == USERDEF_LITERAL)
	return cp_parser_userdef_numeric_literal (parser);
      token = cp_lexer_consume_token (parser->lexer);
      if (TREE_CODE (token->u.value) == FIXED_CST)
	{
	  error_at (token->location,
		    "fixed-point types not supported in C++");
	  return error_mark_node;
	}
      /* Floating-point literals are only allowed in an integral
	 constant expression if they are cast to an integral or
	 enumeration type.  */
      if ((TREE_CODE (token->u.value) == REAL_CST
	   || (TREE_CODE (token->u.value) == EXCESS_PRECISION_EXPR
	       && TREE_CODE (TREE_OPERAND (token->u.value, 0)) == REAL_CST))
	  && parser->integral_constant_expression_p
	  && pedantic)
	{
	  /* CAST_P will be set even in invalid code like "int(2.7 +
	     ...)".   Therefore, we have to check that the next token
	     is sure to end the cast.  */
	  if (cast_p)
	    {
	      cp_token *next_token;

	      next_token = cp_lexer_peek_token (parser->lexer);
	      if (/* The comma at the end of an
		     enumerator-definition.  */
		  next_token->type != CPP_COMMA
		  /* The curly brace at the end of an enum-specifier.  */
		  && next_token->type != CPP_CLOSE_BRACE
		  /* The end of a statement.  */
		  && next_token->type != CPP_SEMICOLON
		  /* The end of the cast-expression.  */
		  && next_token->type != CPP_CLOSE_PAREN
		  /* The end of an array bound.  */
		  && next_token->type != CPP_CLOSE_SQUARE
		  /* The closing ">" in a template-argument-list.  */
		  && (next_token->type != CPP_GREATER
		      || parser->greater_than_is_operator_p)
		  /* C++0x only: A ">>" treated like two ">" tokens,
                     in a template-argument-list.  */
		  && (next_token->type != CPP_RSHIFT
                      || (cxx_dialect == cxx98)
		      || parser->greater_than_is_operator_p))
		cast_p = false;
	    }

	  /* If we are within a cast, then the constraint that the
	     cast is to an integral or enumeration type will be
	     checked at that point.  If we are not within a cast, then
	     this code is invalid.  */
	  if (!cast_p)
	    cp_parser_non_integral_constant_expression (parser, NIC_FLOAT);
	}
      return (cp_expr (token->u.value, token->location, token->flags & DECIMAL_INT)
	      .maybe_add_location_wrapper ());

    case CPP_CHAR_USERDEF:
    case CPP_CHAR16_USERDEF:
    case CPP_CHAR32_USERDEF:
    case CPP_WCHAR_USERDEF:
    case CPP_UTF8CHAR_USERDEF:
      return cp_parser_userdef_char_literal (parser);

    case CPP_STRING:
    case CPP_STRING16:
    case CPP_STRING32:
    case CPP_WSTRING:
    case CPP_UTF8STRING:
    case CPP_STRING_USERDEF:
    case CPP_STRING16_USERDEF:
    case CPP_STRING32_USERDEF:
    case CPP_WSTRING_USERDEF:
    case CPP_UTF8STRING_USERDEF:
      /* ??? Should wide strings be allowed when parser->translate_strings_p
	 is false (i.e. in attributes)?  If not, we can kill the third
	 argument to cp_parser_string_literal.  */
      if (parser->translate_strings_p)
	return (cp_parser_userdef_string_literal (parser,
						  /*lookup_udlit=*/true)
		.maybe_add_location_wrapper ());
      else
	return (cp_parser_string_literal (parser,
					  /*translate=*/false,
					  /*wide_ok=*/true)
		.maybe_add_location_wrapper ());

    case CPP_OPEN_PAREN:
      /* If we see `( { ' then we are looking at the beginning of
	 a GNU statement-expression.  */
      if (cp_parser_allow_gnu_extensions_p (parser)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_BRACE))
	{
	  /* Statement-expressions are not allowed by the standard.  */
	  pedwarn (token->location, OPT_Wpedantic,
		   "ISO C++ forbids braced-groups within expressions");

	  /* And they're not allowed outside of a function-body; you
	     cannot, for example, write:

	     int i = ({ int j = 3; j + 1; });

	     at class or namespace scope.  */
	  if (!parser->in_function_body
	      || parser->in_template_argument_list_p)
	    {
	      error_at (token->location,
			"statement-expressions are not allowed outside "
			"functions nor in template-argument lists");
	      cp_parser_skip_to_end_of_block_or_statement (parser);
	      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
		cp_lexer_consume_token (parser->lexer);
	      return error_mark_node;
	    }
	  else
	    return cp_parser_statement_expr (parser);
	}
      /* Otherwise it's a normal parenthesized expression.  */
      {
	cp_expr expr;
	bool saved_greater_than_is_operator_p;

	location_t open_paren_loc = token->location;

	/* Consume the `('.  */
	matching_parens parens;
	parens.consume_open (parser);
	/* Within a parenthesized expression, a `>' token is always
	   the greater-than operator.  */
	saved_greater_than_is_operator_p
	  = parser->greater_than_is_operator_p;
	parser->greater_than_is_operator_p = true;

	if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	  /* Left fold expression. */
	  expr = NULL_TREE;
	else
	  /* Parse the parenthesized expression.  */
	  expr = cp_parser_expression (parser, idk, cast_p, decltype_p);

	token = cp_lexer_peek_token (parser->lexer);
	if (token->type == CPP_ELLIPSIS || cp_parser_fold_operator (token))
	  {
	    expr = cp_parser_fold_expression (parser, expr);
	    if (expr != error_mark_node
		&& cxx_dialect < cxx17)
	      pedwarn (input_location, OPT_Wc__17_extensions,
		       "fold-expressions only available with %<-std=c++17%> "
		       "or %<-std=gnu++17%>");
	  }
	else
	  /* Let the front end know that this expression was
	     enclosed in parentheses. This matters in case, for
	     example, the expression is of the form `A::B', since
	     `&A::B' might be a pointer-to-member, but `&(A::B)' is
	     not.  */
	  expr = finish_parenthesized_expr (expr);

	/* DR 705: Wrapping an unqualified name in parentheses
	   suppresses arg-dependent lookup.  We want to pass back
	   CP_ID_KIND_QUALIFIED for suppressing vtable lookup
	   (c++/37862), but none of the others.  */
	if (*idk != CP_ID_KIND_QUALIFIED)
	  *idk = CP_ID_KIND_NONE;

	/* The `>' token might be the end of a template-id or
	   template-parameter-list now.  */
	parser->greater_than_is_operator_p
	  = saved_greater_than_is_operator_p;

	/* Consume the `)'.  */
	token = cp_lexer_peek_token (parser->lexer);
	location_t close_paren_loc = token->location;
	bool no_wparens = warning_suppressed_p (expr, OPT_Wparentheses);
	expr.set_range (open_paren_loc, close_paren_loc);
	if (no_wparens)
	  suppress_warning (expr, OPT_Wparentheses);
	if (!parens.require_close (parser)
	    && !cp_parser_uncommitted_to_tentative_parse_p (parser))
	  cp_parser_skip_to_end_of_statement (parser);

	return expr;
      }

    case CPP_OPEN_SQUARE:
      {
	if (c_dialect_objc ())
	  {
	    /* We might have an Objective-C++ message. */
	    cp_parser_parse_tentatively (parser);
	    tree msg = cp_parser_objc_message_expression (parser);
	    /* If that works out, we're done ... */
	    if (cp_parser_parse_definitely (parser))
	      return msg;
	    /* ... else, fall though to see if it's a lambda.  */
	  }
	cp_expr lam = cp_parser_lambda_expression (parser);
	/* Don't warn about a failed tentative parse.  */
	if (cp_parser_error_occurred (parser))
	  return error_mark_node;
	maybe_warn_cpp0x (CPP0X_LAMBDA_EXPR);
	return lam;
      }

    case CPP_OBJC_STRING:
      if (c_dialect_objc ())
	/* We have an Objective-C++ string literal. */
        return cp_parser_objc_expression (parser);
      cp_parser_error (parser, "expected primary-expression");
      return error_mark_node;

    case CPP_KEYWORD:
      switch (token->keyword)
	{
	  /* These two are the boolean literals.  */
	case RID_TRUE:
	  cp_lexer_consume_token (parser->lexer);
	  return cp_expr (boolean_true_node, token->location);
	case RID_FALSE:
	  cp_lexer_consume_token (parser->lexer);
	  return cp_expr (boolean_false_node, token->location);

	  /* The `__null' literal.  */
	case RID_NULL:
	  cp_lexer_consume_token (parser->lexer);
	  return cp_expr (null_node, token->location);

	  /* The `nullptr' literal.  */
	case RID_NULLPTR:
	  cp_lexer_consume_token (parser->lexer);
	  return cp_expr (nullptr_node, token->location);

	  /* Recognize the `this' keyword.  */
	case RID_THIS:
	  cp_lexer_consume_token (parser->lexer);
	  if (parser->local_variables_forbidden_p & THIS_FORBIDDEN)
	    {
	      error_at (token->location,
			"%<this%> may not be used in this context");
	      return error_mark_node;
	    }
	  /* Pointers cannot appear in constant-expressions.  */
	  if (cp_parser_non_integral_constant_expression (parser, NIC_THIS))
	    return error_mark_node;
	  return cp_expr (finish_this_expr (), token->location);

	  /* The `operator' keyword can be the beginning of an
	     id-expression.  */
	case RID_OPERATOR:
	  goto id_expression;

	case RID_FUNCTION_NAME:
	case RID_PRETTY_FUNCTION_NAME:
	case RID_C99_FUNCTION_NAME:
	  {
	    non_integral_constant name;

	    /* The symbols __FUNCTION__, __PRETTY_FUNCTION__, and
	       __func__ are the names of variables -- but they are
	       treated specially.  Therefore, they are handled here,
	       rather than relying on the generic id-expression logic
	       below.  Grammatically, these names are id-expressions.

	       Consume the token.  */
	    token = cp_lexer_consume_token (parser->lexer);

	    switch (token->keyword)
	      {
	      case RID_FUNCTION_NAME:
		name = NIC_FUNC_NAME;
		break;
	      case RID_PRETTY_FUNCTION_NAME:
		name = NIC_PRETTY_FUNC;
		break;
	      case RID_C99_FUNCTION_NAME:
		name = NIC_C99_FUNC;
		break;
	      default:
		gcc_unreachable ();
	      }

	    if (cp_parser_non_integral_constant_expression (parser, name))
	      return error_mark_node;

	    /* Look up the name.  */
	    return finish_fname (token->u.value);
	  }

	case RID_VA_ARG:
	  {
	    tree expression;
	    tree type;
	    location_t type_location;
	    location_t start_loc
	      = cp_lexer_peek_token (parser->lexer)->location;
	    /* The `__builtin_va_arg' construct is used to handle
	       `va_arg'.  Consume the `__builtin_va_arg' token.  */
	    cp_lexer_consume_token (parser->lexer);
	    /* Look for the opening `('.  */
	    matching_parens parens;
	    parens.require_open (parser);
	    /* Now, parse the assignment-expression.  */
	    expression = cp_parser_assignment_expression (parser);
	    /* Look for the `,'.  */
	    cp_parser_require (parser, CPP_COMMA, RT_COMMA);
	    type_location = cp_lexer_peek_token (parser->lexer)->location;
	    /* Parse the type-id.  */
	    {
	      type_id_in_expr_sentinel s (parser);
	      type = cp_parser_type_id (parser);
	    }
	    /* Look for the closing `)'.  */
	    location_t finish_loc
	      = cp_lexer_peek_token (parser->lexer)->location;
	    parens.require_close (parser);
	    /* Using `va_arg' in a constant-expression is not
	       allowed.  */
	    if (cp_parser_non_integral_constant_expression (parser,
							    NIC_VA_ARG))
	      return error_mark_node;
	    /* Construct a location of the form:
		 __builtin_va_arg (v, int)
		 ~~~~~~~~~~~~~~~~~~~~~^~~~
	       with the caret at the type, ranging from the start of the
	       "__builtin_va_arg" token to the close paren.  */
	    location_t combined_loc
	      = make_location (type_location, start_loc, finish_loc);
	    return build_x_va_arg (combined_loc, expression, type);
	  }

	case RID_OFFSETOF:
	  return cp_parser_builtin_offsetof (parser);

#define DEFTRAIT_EXPR(CODE, NAME, ARITY) \
	case RID_##CODE:
#include "cp-trait.def"
#undef DEFTRAIT_EXPR
	  return cp_parser_trait (parser, token->keyword);

	// C++ concepts
	case RID_REQUIRES:
	  return cp_parser_requires_expression (parser);

	/* Objective-C++ expressions.  */
	case RID_AT_ENCODE:
	case RID_AT_PROTOCOL:
	case RID_AT_SELECTOR:
	  return cp_parser_objc_expression (parser);

	case RID_OMP_ALL_MEMORY:
	  gcc_assert (flag_openmp);
	  cp_lexer_consume_token (parser->lexer);
	  error_at (token->location,
		    "%<omp_all_memory%> may only be used in OpenMP "
		    "%<depend%> clause");
	  return error_mark_node;

	case RID_TEMPLATE:
	  if (parser->in_function_body
	      && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
	      	  == CPP_LESS))
	    {
	      error_at (token->location,
			"a template declaration cannot appear at block scope");
	      cp_parser_skip_to_end_of_block_or_statement (parser);
	      return error_mark_node;
	    }
	  /* FALLTHRU */
	default:
	  cp_parser_error (parser, "expected primary-expression");
	  return error_mark_node;
	}

      /* An id-expression can start with either an identifier, a
	 `::' as the beginning of a qualified-id, or the "operator"
	 keyword.  */
    case CPP_NAME:
    case CPP_SCOPE:
    case CPP_TEMPLATE_ID:
    case CPP_NESTED_NAME_SPECIFIER:
      {
      id_expression:
	cp_expr id_expression;
	cp_expr decl;
	const char *error_msg;
	bool template_p;
	bool done;
	cp_token *id_expr_token;

	/* Parse the id-expression.  */
	id_expression
	  = cp_parser_id_expression (parser,
				     /*template_keyword_p=*/false,
				     /*check_dependency_p=*/true,
				     &template_p,
				     /*declarator_p=*/false,
				     /*optional_p=*/false);
	if (id_expression == error_mark_node)
	  return error_mark_node;
	id_expr_token = token;
	token = cp_lexer_peek_token (parser->lexer);
	done = (token->type != CPP_OPEN_SQUARE
		&& token->type != CPP_OPEN_PAREN
		&& token->type != CPP_DOT
		&& token->type != CPP_DEREF
		&& token->type != CPP_PLUS_PLUS
		&& token->type != CPP_MINUS_MINUS);
	/* If we have a template-id, then no further lookup is
	   required.  If the template-id was for a template-class, we
	   will sometimes have a TYPE_DECL at this point.  */
	if (TREE_CODE (id_expression) == TEMPLATE_ID_EXPR
		 || TREE_CODE (id_expression) == TYPE_DECL)
	  decl = id_expression;
	/* Look up the name.  */
	else
	  {
	    tree ambiguous_decls;

	    /* If we already know that this lookup is ambiguous, then
	       we've already issued an error message; there's no reason
	       to check again.  */
	    if (id_expr_token->type == CPP_NAME
		&& id_expr_token->error_reported)
	      {
		cp_parser_simulate_error (parser);
		return error_mark_node;
	      }

	    decl = cp_parser_lookup_name (parser, id_expression,
					  none_type,
					  template_p,
					  /*is_namespace=*/false,
					  /*check_dependency=*/true,
					  &ambiguous_decls,
					  id_expression.get_location ());
	    /* If the lookup was ambiguous, an error will already have
	       been issued.  */
	    if (ambiguous_decls)
	      return error_mark_node;

	    /* In Objective-C++, we may have an Objective-C 2.0
	       dot-syntax for classes here.  */
	    if (c_dialect_objc ()
		&& cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
		&& TREE_CODE (decl) == TYPE_DECL
		&& objc_is_class_name (decl))
	      {
		tree component;
		cp_lexer_consume_token (parser->lexer);
		component = cp_parser_identifier (parser);
		if (component == error_mark_node)
		  return error_mark_node;

		tree result = objc_build_class_component_ref (id_expression,
							      component);
		/* Build a location of the form:
		     expr.component
		     ~~~~~^~~~~~~~~
		   with caret at the start of the component name (at
		   input_location), ranging from the start of the id_expression
		   to the end of the component name.  */
		location_t combined_loc
		  = make_location (input_location, id_expression.get_start (),
				   get_finish (input_location));
		protected_set_expr_location (result, combined_loc);
		return result;
	      }

	    /* In Objective-C++, an instance variable (ivar) may be preferred
	       to whatever cp_parser_lookup_name() found.
	       Call objc_lookup_ivar.  To avoid exposing cp_expr to the
	       rest of c-family, we have to do a little extra work to preserve
	       any location information in cp_expr "decl".  Given that
	       objc_lookup_ivar is implemented in "c-family" and "objc", we
	       have a trip through the pure "tree" type, rather than cp_expr.
	       Naively copying it back to "decl" would implicitly give the
	       new cp_expr value an UNKNOWN_LOCATION for nodes that don't
	       store an EXPR_LOCATION.  Hence we only update "decl" (and
	       hence its location_t) if we get back a different tree node.  */
	    tree decl_tree = objc_lookup_ivar (decl.get_value (),
					       id_expression);
	    if (decl_tree != decl.get_value ())
	      decl = cp_expr (decl_tree);

	    /* If name lookup gives us a SCOPE_REF, then the
	       qualifying scope was dependent.  */
	    if (TREE_CODE (decl) == SCOPE_REF)
	      {
		/* At this point, we do not know if DECL is a valid
		   integral constant expression.  We assume that it is
		   in fact such an expression, so that code like:

		      template <int N> struct A {
			int a[B<N>::i];
		      };

		   is accepted.  At template-instantiation time, we
		   will check that B<N>::i is actually a constant.  */
		return decl;
	      }
	    /* Check to see if DECL is a local variable in a context
	       where that is forbidden.  */
	    if ((parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
		&& local_variable_p (decl)
		/* DR 2082 permits local variables in unevaluated contexts
		   within a default argument.  */
		&& !cp_unevaluated_operand)
	      {
		const char *msg
		  = (TREE_CODE (decl) == PARM_DECL
		     ? _("parameter %qD may not appear in this context")
		     : _("local variable %qD may not appear in this context"));
		error_at (id_expression.get_location (), msg,
			  decl.get_value ());
		return error_mark_node;
	      }
	  }

	decl = (finish_id_expression
		(id_expression, decl, parser->scope,
		 idk,
		 parser->integral_constant_expression_p,
		 parser->allow_non_integral_constant_expression_p,
		 &parser->non_integral_constant_expression_p,
		 template_p, done, address_p,
		 template_arg_p,
		 &error_msg,
		 id_expression.get_location ()));
	if (error_msg)
	  cp_parser_error (parser, error_msg);
	/* Build a location for an id-expression of the form:
	     ::ns::id
             ~~~~~~^~
	  or:
	     id
	     ^~
	   i.e. from the start of the first token to the end of the final
	   token, with the caret at the start of the unqualified-id.  */
	location_t caret_loc = get_pure_location (id_expression.get_location ());
	location_t start_loc = get_start (id_expr_token->location);
	location_t finish_loc = get_finish (id_expression.get_location ());
	location_t combined_loc
	  = make_location (caret_loc, start_loc, finish_loc);

	decl.set_location (combined_loc);
	return decl;
      }

      /* Anything else is an error.  */
    default:
      cp_parser_error (parser, "expected primary-expression");
      return error_mark_node;
    }
}

static inline cp_expr
cp_parser_primary_expression (cp_parser *parser,
			      bool address_p,
			      bool cast_p,
			      bool template_arg_p,
			      cp_id_kind *idk)
{
  return cp_parser_primary_expression (parser, address_p, cast_p, template_arg_p,
				       /*decltype*/false, idk);
}

/* Complain about missing template keyword when naming a dependent
   member template.  */

static void
missing_template_diag (location_t loc, diagnostic_t diag_kind = DK_WARNING)
{
  if (warning_suppressed_at (loc, OPT_Wmissing_template_keyword))
    return;

  gcc_rich_location richloc (loc);
  richloc.add_fixit_insert_before ("template");
  emit_diagnostic (diag_kind, &richloc, OPT_Wmissing_template_keyword,
		   "expected %qs keyword before dependent "
		   "template name", "template");
  suppress_warning_at (loc, OPT_Wmissing_template_keyword);
}

/* Parse an id-expression.

   id-expression:
     unqualified-id
     qualified-id

   qualified-id:
     :: [opt] nested-name-specifier template [opt] unqualified-id
     :: identifier
     :: operator-function-id
     :: template-id

   Return a representation of the unqualified portion of the
   identifier.  Sets PARSER->SCOPE to the qualifying scope if there is
   a `::' or nested-name-specifier.

   Often, if the id-expression was a qualified-id, the caller will
   want to make a SCOPE_REF to represent the qualified-id.  This
   function does not do this in order to avoid wastefully creating
   SCOPE_REFs when they are not required.

   If TEMPLATE_KEYWORD_P is true, then we have just seen the
   `template' keyword.

   If CHECK_DEPENDENCY_P is false, then names are looked up inside
   uninstantiated templates.

   If *TEMPLATE_P is non-NULL, it is set to true iff the
   `template' keyword is used to explicitly indicate that the entity
   named is a template.

   If DECLARATOR_P is true, the id-expression is appearing as part of
   a declarator, rather than as part of an expression.  */

static cp_expr
cp_parser_id_expression (cp_parser *parser,
			 bool template_keyword_p,
			 bool check_dependency_p,
			 bool *template_p,
			 bool declarator_p,
			 bool optional_p)
{
  bool global_scope_p;
  bool nested_name_specifier_p;

  /* Assume the `template' keyword was not used.  */
  if (template_p)
    *template_p = template_keyword_p;

  /* Look for the optional `::' operator.  */
  global_scope_p
    = (!template_keyword_p
       && (cp_parser_global_scope_opt (parser,
				       /*current_scope_valid_p=*/false)
	   != NULL_TREE));

  /* Look for the optional nested-name-specifier.  */
  nested_name_specifier_p
    = (cp_parser_nested_name_specifier_opt (parser,
					    /*typename_keyword_p=*/false,
					    check_dependency_p,
					    /*type_p=*/false,
					    declarator_p,
					    template_keyword_p)
       != NULL_TREE);

  cp_expr id = NULL_TREE;
  tree scope = parser->scope;

  /* Peek at the next token.  */
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* If there is a nested-name-specifier, then we are looking at
     the first qualified-id production.  */
  if (nested_name_specifier_p)
    {
      tree saved_object_scope;
      tree saved_qualifying_scope;

      /* See if the next token is the `template' keyword.  */
      if (!template_p)
	template_p = &template_keyword_p;
      *template_p = cp_parser_optional_template_keyword (parser);
      /* Name lookup we do during the processing of the
	 unqualified-id might obliterate SCOPE.  */
      saved_object_scope = parser->object_scope;
      saved_qualifying_scope = parser->qualifying_scope;
      /* Process the final unqualified-id.  */
      id = cp_parser_unqualified_id (parser, *template_p,
				     check_dependency_p,
				     declarator_p,
				     /*optional_p=*/false);
      /* Restore the SAVED_SCOPE for our caller.  */
      parser->scope = scope;
      parser->object_scope = saved_object_scope;
      parser->qualifying_scope = saved_qualifying_scope;
    }
  /* Otherwise, if we are in global scope, then we are looking at one
     of the other qualified-id productions.  */
  else if (global_scope_p)
    {
      /* If it's an identifier, and the next token is not a "<", then
	 we can avoid the template-id case.  This is an optimization
	 for this common case.  */
      if (token->type == CPP_NAME
	  && !cp_parser_nth_token_starts_template_argument_list_p
	       (parser, 2))
	return cp_parser_identifier (parser);

      cp_parser_parse_tentatively (parser);
      /* Try a template-id.  */
      id = cp_parser_template_id_expr (parser,
				       /*template_keyword_p=*/false,
				       /*check_dependency_p=*/true,
				       declarator_p);
      /* If that worked, we're done.  */
      if (cp_parser_parse_definitely (parser))
	return id;

      /* Peek at the next token.  (Changes in the token buffer may
	 have invalidated the pointer obtained above.)  */
      token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_NAME:
	  id = cp_parser_identifier (parser);
	  break;

	case CPP_KEYWORD:
	  if (token->keyword == RID_OPERATOR)
	    {
	      id = cp_parser_operator_function_id (parser);
	      break;
	    }
	  /* Fall through.  */

	default:
	  cp_parser_error (parser, "expected id-expression");
	  return error_mark_node;
	}
    }
  else
    {
      if (!scope)
	scope = parser->context->object_type;
      id = cp_parser_unqualified_id (parser, template_keyword_p,
				     /*check_dependency_p=*/true,
				     declarator_p,
				     optional_p);
    }

  if (id && TREE_CODE (id) == IDENTIFIER_NODE
      && warn_missing_template_keyword
      && !template_keyword_p
      /* Don't warn if we're looking inside templates.  */
      && check_dependency_p
      /* In a template argument list a > could be closing
	 the enclosing targs.  */
      && !parser->in_template_argument_list_p
      && scope && dependentish_scope_p (scope)
      /* Don't confuse an ill-formed constructor declarator for a missing
	 template keyword in a return type.  */
      && !(declarator_p && constructor_name_p (id, scope))
      && cp_parser_nth_token_starts_template_argument_list_p (parser, 1)
      && warning_enabled_at (token->location,
			     OPT_Wmissing_template_keyword))
    {
      saved_token_sentinel toks (parser->lexer, STS_ROLLBACK);
      if (cp_parser_skip_entire_template_parameter_list (parser)
	  /* An operator after the > suggests that the > ends a
	     template-id; a name or literal suggests that the > is an
	     operator.  */
	  && (cp_lexer_peek_token (parser->lexer)->type
	      <= CPP_LAST_PUNCTUATOR))
	missing_template_diag (token->location);
    }

  return id;
}

/* Parse an unqualified-id.

   unqualified-id:
     identifier
     operator-function-id
     conversion-function-id
     ~ class-name
     template-id

   If TEMPLATE_KEYWORD_P is TRUE, we have just seen the `template'
   keyword, in a construct like `A::template ...'.

   Returns a representation of unqualified-id.  For the `identifier'
   production, an IDENTIFIER_NODE is returned.  For the `~ class-name'
   production a BIT_NOT_EXPR is returned; the operand of the
   BIT_NOT_EXPR is an IDENTIFIER_NODE for the class-name.  For the
   other productions, see the documentation accompanying the
   corresponding parsing functions.  If CHECK_DEPENDENCY_P is false,
   names are looked up in uninstantiated templates.  If DECLARATOR_P
   is true, the unqualified-id is appearing as part of a declarator,
   rather than as part of an expression.  */

static cp_expr
cp_parser_unqualified_id (cp_parser* parser,
			  bool template_keyword_p,
			  bool check_dependency_p,
			  bool declarator_p,
			  bool optional_p)
{
  cp_token *token;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  switch ((int) token->type)
    {
    case CPP_NAME:
      {
	tree id;

	/* We don't know yet whether or not this will be a
	   template-id.  */
	cp_parser_parse_tentatively (parser);
	/* Try a template-id.  */
	id = cp_parser_template_id_expr (parser, template_keyword_p,
					 check_dependency_p,
					 declarator_p);
	/* If it worked, we're done.  */
	if (cp_parser_parse_definitely (parser))
	  return id;
	/* Otherwise, it's an ordinary identifier.  */
	return cp_parser_identifier (parser);
      }

    case CPP_TEMPLATE_ID:
      return cp_parser_template_id_expr (parser, template_keyword_p,
					 check_dependency_p,
					 declarator_p);

    case CPP_COMPL:
      {
	tree type_decl;
	tree qualifying_scope;
	tree object_scope;
	tree scope;
	bool done;
	location_t tilde_loc = token->location;

	/* Consume the `~' token.  */
	cp_lexer_consume_token (parser->lexer);
	/* Parse the class-name.  The standard, as written, seems to
	   say that:

	     template <typename T> struct S { ~S (); };
	     template <typename T> S<T>::~S() {}

	   is invalid, since `~' must be followed by a class-name, but
	   `S<T>' is dependent, and so not known to be a class.
	   That's not right; we need to look in uninstantiated
	   templates.  A further complication arises from:

	     template <typename T> void f(T t) {
	       t.T::~T();
	     }

	   Here, it is not possible to look up `T' in the scope of `T'
	   itself.  We must look in both the current scope, and the
	   scope of the containing complete expression.

	   Yet another issue is:

	     struct S {
	       int S;
	       ~S();
	     };

	     S::~S() {}

	   The standard does not seem to say that the `S' in `~S'
	   should refer to the type `S' and not the data member
	   `S::S'.  */

	/* DR 244 says that we look up the name after the "~" in the
	   same scope as we looked up the qualifying name.  That idea
	   isn't fully worked out; it's more complicated than that.  */
	scope = parser->scope;
	object_scope = parser->object_scope;
	qualifying_scope = parser->qualifying_scope;

	/* Check for invalid scopes.  */
	if (scope == error_mark_node)
	  {
	    if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	      cp_lexer_consume_token (parser->lexer);
	    return error_mark_node;
	  }
	if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
	  {
	    if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
	      error_at (token->location,
			"scope %qT before %<~%> is not a class-name",
			scope);
	    cp_parser_simulate_error (parser);
	    if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	      cp_lexer_consume_token (parser->lexer);
	    return error_mark_node;
	  }
	if (template_keyword_p)
	  {
	    if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
	      error_at (tilde_loc, "%<template%> keyword not permitted in "
			"destructor name");
	    cp_parser_simulate_error (parser);
	    return error_mark_node;
	  }

	gcc_assert (!scope || TYPE_P (scope));

	token = cp_lexer_peek_token (parser->lexer);

	/* Create a location with caret == start at the tilde,
	   finishing at the end of the peeked token, e.g:
	   ~token
	   ^~~~~~.  */
	location_t loc
	  = make_location (tilde_loc, tilde_loc, token->location);

	/* If the name is of the form "X::~X" it's OK even if X is a
	   typedef.  */

	if (scope
	    && token->type == CPP_NAME
	    && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
		!= CPP_LESS)
	    && (token->u.value == TYPE_IDENTIFIER (scope)
		|| (CLASS_TYPE_P (scope)
		    && constructor_name_p (token->u.value, scope))))
	  {
	    cp_lexer_consume_token (parser->lexer);
	    return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
	  }

	/* ~auto means the destructor of whatever the object is.  */
	if (cp_parser_is_keyword (token, RID_AUTO))
	  {
	    if (cxx_dialect < cxx14)
	      pedwarn (loc, OPT_Wc__14_extensions,
		       "%<~auto%> only available with "
		       "%<-std=c++14%> or %<-std=gnu++14%>");
	    cp_lexer_consume_token (parser->lexer);
	    return build_min_nt_loc (loc, BIT_NOT_EXPR, make_auto ());
	  }

	/* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
	   declarator-id of a constructor or destructor.  */
	if (token->type == CPP_TEMPLATE_ID && declarator_p
	    && cxx_dialect >= cxx20)
	  {
	    if (!cp_parser_simulate_error (parser))
	      error_at (tilde_loc, "template-id not allowed for destructor");
	    return error_mark_node;
	  }

	/* If there was an explicit qualification (S::~T), first look
	   in the scope given by the qualification (i.e., S).

	   Note: in the calls to cp_parser_class_name below we pass
	   typename_type so that lookup finds the injected-class-name
	   rather than the constructor.  */
	done = false;
	type_decl = NULL_TREE;
	if (scope)
	  {
	    cp_parser_parse_tentatively (parser);
	    type_decl = cp_parser_class_name (parser,
					      /*typename_keyword_p=*/false,
					      /*template_keyword_p=*/false,
					      typename_type,
					      /*check_dependency=*/false,
					      /*class_head_p=*/false,
					      declarator_p);
	    if (cp_parser_parse_definitely (parser))
	      done = true;
	  }
	/* In "N::S::~S", look in "N" as well.  */
	if (!done && scope && qualifying_scope)
	  {
	    cp_parser_parse_tentatively (parser);
	    parser->scope = qualifying_scope;
	    parser->object_scope = NULL_TREE;
	    parser->qualifying_scope = NULL_TREE;
	    type_decl
	      = cp_parser_class_name (parser,
				      /*typename_keyword_p=*/false,
				      /*template_keyword_p=*/false,
				      typename_type,
				      /*check_dependency=*/false,
				      /*class_head_p=*/false,
				      declarator_p);
	    if (cp_parser_parse_definitely (parser))
	      done = true;
	  }
	/* In "p->S::~T", look in the scope given by "*p" as well.  */
	else if (!done && object_scope)
	  {
	    cp_parser_parse_tentatively (parser);
	    parser->scope = object_scope;
	    parser->object_scope = NULL_TREE;
	    parser->qualifying_scope = NULL_TREE;
	    type_decl
	      = cp_parser_class_name (parser,
				      /*typename_keyword_p=*/false,
				      /*template_keyword_p=*/false,
				      typename_type,
				      /*check_dependency=*/false,
				      /*class_head_p=*/false,
				      declarator_p);
	    if (cp_parser_parse_definitely (parser))
	      done = true;
	  }
	/* Look in the surrounding context.  */
	if (!done)
	  {
	    parser->scope = NULL_TREE;
	    parser->object_scope = NULL_TREE;
	    parser->qualifying_scope = NULL_TREE;
	    if (processing_template_decl)
	      cp_parser_parse_tentatively (parser);
	    type_decl
	      = cp_parser_class_name (parser,
				      /*typename_keyword_p=*/false,
				      /*template_keyword_p=*/false,
				      typename_type,
				      /*check_dependency=*/false,
				      /*class_head_p=*/false,
				      declarator_p);
	    if (processing_template_decl
		&& ! cp_parser_parse_definitely (parser))
	      {
		/* We couldn't find a type with this name.  If we're parsing
		   tentatively, fail and try something else.  */
		if (cp_parser_uncommitted_to_tentative_parse_p (parser))
		  {
		    cp_parser_simulate_error (parser);
		    return error_mark_node;
		  }
		/* Otherwise, accept it and check for a match at instantiation
		   time.  */
		type_decl = cp_parser_identifier (parser);
		if (type_decl != error_mark_node)
		  type_decl = build_min_nt_loc (loc, BIT_NOT_EXPR, type_decl);
		return type_decl;
	      }
	  }
	/* If an error occurred, assume that the name of the
	   destructor is the same as the name of the qualifying
	   class.  That allows us to keep parsing after running
	   into ill-formed destructor names.  */
	if (type_decl == error_mark_node && scope)
	  return build_min_nt_loc (loc, BIT_NOT_EXPR, scope);
	else if (type_decl == error_mark_node)
	  return error_mark_node;

	/* Check that destructor name and scope match.  */
	if (declarator_p && scope && !check_dtor_name (scope, type_decl))
	  {
	    if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
	      error_at (loc,
			"declaration of %<~%T%> as member of %qT",
			type_decl, scope);
	    cp_parser_simulate_error (parser);
	    return error_mark_node;
	  }

	/* [class.dtor]

	   A typedef-name that names a class shall not be used as the
	   identifier in the declarator for a destructor declaration.  */
	if (declarator_p
	    && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
	    && !DECL_SELF_REFERENCE_P (type_decl)
	    && !cp_parser_uncommitted_to_tentative_parse_p (parser))
	  error_at (loc,
		    "typedef-name %qD used as destructor declarator",
		    type_decl);

	return build_min_nt_loc (loc, BIT_NOT_EXPR, TREE_TYPE (type_decl));
      }

    case CPP_KEYWORD:
      if (token->keyword == RID_OPERATOR)
	{
	  cp_expr id;

	  /* This could be a template-id, so we try that first.  */
	  cp_parser_parse_tentatively (parser);
	  /* Try a template-id.  */
	  id = cp_parser_template_id_expr (parser, template_keyword_p,
					   /*check_dependency_p=*/true,
					   declarator_p);
	  /* If that worked, we're done.  */
	  if (cp_parser_parse_definitely (parser))
	    return id;
	  /* We still don't know whether we're looking at an
	     operator-function-id or a conversion-function-id.  */
	  cp_parser_parse_tentatively (parser);
	  /* Try an operator-function-id.  */
	  id = cp_parser_operator_function_id (parser);
	  /* If that didn't work, try a conversion-function-id.  */
	  if (!cp_parser_parse_definitely (parser))
	    id = cp_parser_conversion_function_id (parser);

	  return id;
	}
      /* Fall through.  */

    default:
      if (optional_p)
	return NULL_TREE;
      cp_parser_error (parser, "expected unqualified-id");
      return error_mark_node;
    }
}

/* Check [temp.names]/5: A name prefixed by the keyword template shall
   be a template-id or the name shall refer to a class template or an
   alias template.  */

static void
check_template_keyword_in_nested_name_spec (tree name)
{
  if (CLASS_TYPE_P (name)
      && ((CLASSTYPE_USE_TEMPLATE (name)
	   && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (name)))
	  || CLASSTYPE_IS_TEMPLATE (name)))
    return;

  if (TREE_CODE (name) == TYPENAME_TYPE
      && TREE_CODE (TYPENAME_TYPE_FULLNAME (name)) == TEMPLATE_ID_EXPR)
    return;
  /* Alias templates are also OK.  */
  else if (alias_template_specialization_p (name, nt_opaque))
    return;

  permerror (input_location, TYPE_P (name)
	     ? G_("%qT is not a template")
	     : G_("%qD is not a template"),
	     name);
}

/* Parse an (optional) nested-name-specifier.

   nested-name-specifier: [C++98]
     class-or-namespace-name :: nested-name-specifier [opt]
     class-or-namespace-name :: template nested-name-specifier [opt]

   nested-name-specifier: [C++0x]
     type-name ::
     namespace-name ::
     nested-name-specifier identifier ::
     nested-name-specifier template [opt] simple-template-id ::

   PARSER->SCOPE should be set appropriately before this function is
   called.  TYPENAME_KEYWORD_P is TRUE if the `typename' keyword is in
   effect.  TYPE_P is TRUE if we non-type bindings should be ignored
   in name lookups.

   Sets PARSER->SCOPE to the class (TYPE) or namespace
   (NAMESPACE_DECL) specified by the nested-name-specifier, or leaves
   it unchanged if there is no nested-name-specifier.  Returns the new
   scope iff there is a nested-name-specifier, or NULL_TREE otherwise.

   If CHECK_DEPENDENCY_P is FALSE, names are looked up in dependent scopes.

   If IS_DECLARATION is TRUE, the nested-name-specifier is known to be
   part of a declaration and/or decl-specifier.  */

static tree
cp_parser_nested_name_specifier_opt (cp_parser *parser,
				     bool typename_keyword_p,
				     bool check_dependency_p,
				     bool type_p,
				     bool is_declaration,
				     bool template_keyword_p /* = false */)
{
  bool success = false;
  cp_token_position start = 0;
  cp_token *token;

  /* Remember where the nested-name-specifier starts.  */
  if (cp_parser_uncommitted_to_tentative_parse_p (parser)
      && cp_lexer_next_token_is_not (parser->lexer, CPP_NESTED_NAME_SPECIFIER))
    {
      start = cp_lexer_token_position (parser->lexer, false);
      push_deferring_access_checks (dk_deferred);
    }

  while (true)
    {
      tree new_scope;
      tree old_scope;
      tree saved_qualifying_scope;

      /* Spot cases that cannot be the beginning of a
	 nested-name-specifier.  */
      token = cp_lexer_peek_token (parser->lexer);

      /* If the next token is CPP_NESTED_NAME_SPECIFIER, just process
	 the already parsed nested-name-specifier.  */
      if (token->type == CPP_NESTED_NAME_SPECIFIER)
	{
	  /* Grab the nested-name-specifier and continue the loop.  */
	  cp_parser_pre_parsed_nested_name_specifier (parser);
	  /* If we originally encountered this nested-name-specifier
	     with CHECK_DEPENDENCY_P set to true, we will not have
	     resolved TYPENAME_TYPEs, so we must do so here.  */
	  if (is_declaration
	      && !check_dependency_p
	      && TREE_CODE (parser->scope) == TYPENAME_TYPE)
	    {
	      new_scope = resolve_typename_type (parser->scope,
						 /*only_current_p=*/false);
	      if (TREE_CODE (new_scope) != TYPENAME_TYPE)
		parser->scope = new_scope;
	    }
	  success = true;
	  continue;
	}

      /* Spot cases that cannot be the beginning of a
	 nested-name-specifier.  On the second and subsequent times
	 through the loop, we look for the `template' keyword.  */
      if (success && token->keyword == RID_TEMPLATE)
	;
      /* A template-id can start a nested-name-specifier.  */
      else if (token->type == CPP_TEMPLATE_ID)
	;
      /* DR 743: decltype can be used in a nested-name-specifier.  */
      else if (token_is_decltype (token))
	;
      else
	{
	  /* If the next token is not an identifier, then it is
	     definitely not a type-name or namespace-name.  */
	  if (token->type != CPP_NAME)
	    break;
	  /* If the following token is neither a `<' (to begin a
	     template-id), nor a `::', then we are not looking at a
	     nested-name-specifier.  */
	  token = cp_lexer_peek_nth_token (parser->lexer, 2);

	  if (token->type == CPP_COLON
	      && parser->colon_corrects_to_scope_p
	      && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_NAME
	      /* name:name is a valid sequence in an Objective C message.  */
	      && !parser->objective_c_message_context_p)
	    {
	      gcc_rich_location richloc (token->location);
	      richloc.add_fixit_replace ("::");
	      error_at (&richloc,
			"found %<:%> in nested-name-specifier, "
			"expected %<::%>");
	      token->type = CPP_SCOPE;
	    }

	  if (token->type != CPP_SCOPE
	      && !cp_parser_nth_token_starts_template_argument_list_p
		  (parser, 2))
	    break;
	}

      /* The nested-name-specifier is optional, so we parse
	 tentatively.  */
      cp_parser_parse_tentatively (parser);

      /* Look for the optional `template' keyword, if this isn't the
	 first time through the loop.  */
      if (success)
	{
	  template_keyword_p = cp_parser_optional_template_keyword (parser);
	  /* DR1710: "In a qualified-id used as the name in
	     a typename-specifier, elaborated-type-specifier, using-declaration,
	     or class-or-decltype, an optional keyword template appearing at
	     the top level is ignored."  */
	  if (!template_keyword_p
	      && typename_keyword_p
	      && cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
	    template_keyword_p = true;
	}

      /* Save the old scope since the name lookup we are about to do
	 might destroy it.  */
      old_scope = parser->scope;
      saved_qualifying_scope = parser->qualifying_scope;
      /* In a declarator-id like "X<T>::I::Y<T>" we must be able to
	 look up names in "X<T>::I" in order to determine that "Y" is
	 a template.  So, if we have a typename at this point, we make
	 an effort to look through it.  */
      if (is_declaration
	  && !check_dependency_p
	  && !typename_keyword_p
	  && parser->scope
	  && TREE_CODE (parser->scope) == TYPENAME_TYPE)
	parser->scope = resolve_typename_type (parser->scope,
					       /*only_current_p=*/false);
      /* Parse the qualifying entity.  */
      new_scope
	= cp_parser_qualifying_entity (parser,
                                       typename_keyword_p,
                                       template_keyword_p,
                                       check_dependency_p,
                                       type_p,
                                       is_declaration);
      /* Look for the `::' token.  */
      cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);

      /* If we found what we wanted, we keep going; otherwise, we're
	 done.  */
      if (!cp_parser_parse_definitely (parser))
	{
	  bool error_p = false;

	  /* Restore the OLD_SCOPE since it was valid before the
	     failed attempt at finding the last
	     class-or-namespace-name.  */
	  parser->scope = old_scope;
	  parser->qualifying_scope = saved_qualifying_scope;

	  /* If the next token is a decltype, and the one after that is a
	     `::', then the decltype has failed to resolve to a class or
	     enumeration type.  Give this error even when parsing
	     tentatively since it can't possibly be valid--and we're going
	     to replace it with a CPP_NESTED_NAME_SPECIFIER below, so we
	     won't get another chance.*/
	  if (cp_lexer_next_token_is (parser->lexer, CPP_DECLTYPE)
	      && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
		  == CPP_SCOPE))
	    {
	      token = cp_lexer_consume_token (parser->lexer);
	      tree dtype = token->u.tree_check_value->value;
	      if (dtype != error_mark_node)
		error_at (token->location, "%<decltype%> evaluates to %qT, "
			  "which is not a class or enumeration type",
			  dtype);
	      parser->scope = error_mark_node;
	      error_p = true;
	      /* As below.  */
	      success = true;
	      cp_lexer_consume_token (parser->lexer);
	    }

	  if (cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID)
	      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SCOPE))
	    {
	      /* If we have a non-type template-id followed by ::, it can't
		 possibly be valid.  */
	      token = cp_lexer_peek_token (parser->lexer);
	      tree tid = token->u.tree_check_value->value;
	      if (TREE_CODE (tid) == TEMPLATE_ID_EXPR
		  && TREE_CODE (TREE_OPERAND (tid, 0)) != IDENTIFIER_NODE)
		{
		  tree tmpl = NULL_TREE;
		  if (is_overloaded_fn (tid))
		    {
		      tree fns = get_fns (tid);
		      if (OVL_SINGLE_P (fns))
			tmpl = OVL_FIRST (fns);
		      if (function_concept_p (fns))
			error_at (token->location, "concept-id %qD "
				  "in nested-name-specifier", tid);
		      else
			error_at (token->location, "function template-id "
				  "%qD in nested-name-specifier", tid);
		    }
		  else
		    {
		      tmpl = TREE_OPERAND (tid, 0);
		      if (variable_concept_p (tmpl)
			  || standard_concept_p (tmpl))
			error_at (token->location, "concept-id %qD "
				  "in nested-name-specifier", tid);
		      else
			{
			  /* Variable template.  */
			  gcc_assert (variable_template_p (tmpl));
			  error_at (token->location, "variable template-id "
				    "%qD in nested-name-specifier", tid);
			}
		    }
		  if (tmpl)
		    inform (DECL_SOURCE_LOCATION (tmpl),
			    "%qD declared here", tmpl);

		  parser->scope = error_mark_node;
		  error_p = true;
		  /* As below.  */
		  success = true;
		  cp_lexer_consume_token (parser->lexer);
		  cp_lexer_consume_token (parser->lexer);
		}
	    }

	  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
	    break;
	  /* If the next token is an identifier, and the one after
	     that is a `::', then any valid interpretation would have
	     found a class-or-namespace-name.  */
	  while (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
		 && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
		     == CPP_SCOPE)
		 && (cp_lexer_peek_nth_token (parser->lexer, 3)->type
		     != CPP_COMPL))
	    {
	      token = cp_lexer_consume_token (parser->lexer);
	      if (!error_p)
		{
		  if (!token->error_reported)
		    {
		      tree decl;
		      tree ambiguous_decls;

		      decl = cp_parser_lookup_name (parser, token->u.value,
						    none_type,
						    /*is_template=*/false,
						    /*is_namespace=*/false,
						    /*check_dependency=*/true,
						    &ambiguous_decls,
						    token->location);
		      if (TREE_CODE (decl) == TEMPLATE_DECL)
			error_at (token->location,
				  "%qD used without template arguments",
				  decl);
		      else if (ambiguous_decls)
			{
			  // cp_parser_lookup_name has the same diagnostic,
			  // thus make sure to emit it at most once.
			  if (cp_parser_uncommitted_to_tentative_parse_p
			      (parser))
			    {
			      error_at (token->location,
					"reference to %qD is ambiguous",
					token->u.value);
			      print_candidates (ambiguous_decls);
			    }
			  decl = error_mark_node;
			}
		      else
                        {
                          if (cxx_dialect != cxx98)
                            cp_parser_name_lookup_error
                            (parser, token->u.value, decl, NLE_NOT_CXX98,
	  		     token->location);
			  else
			    cp_parser_name_lookup_error
			    (parser, token->u.value, decl, NLE_CXX98,
			     token->location);
                        }
		    }
		  parser->scope = error_mark_node;
		  error_p = true;
		  /* Treat this as a successful nested-name-specifier
		     due to:

		     [basic.lookup.qual]

		     If the name found is not a class-name (clause
		     _class_) or namespace-name (_namespace.def_), the
		     program is ill-formed.  */
		  success = true;
		}
	      cp_lexer_consume_token (parser->lexer);
	    }
	  break;
	}
      /* We've found one valid nested-name-specifier.  */
      success = true;
      /* Name lookup always gives us a DECL.  */
      if (TREE_CODE (new_scope) == TYPE_DECL)
	new_scope = TREE_TYPE (new_scope);
      /* Uses of "template" must be followed by actual templates.  */
      if (template_keyword_p)
	check_template_keyword_in_nested_name_spec (new_scope);
      /* If it is a class scope, try to complete it; we are about to
	 be looking up names inside the class.  */
      if (TYPE_P (new_scope)
	  /* Since checking types for dependency can be expensive,
	     avoid doing it if the type is already complete.  */
	  && !COMPLETE_TYPE_P (new_scope)
	  /* Do not try to complete dependent types.  */
	  && !dependent_type_p (new_scope))
	{
	  new_scope = complete_type (new_scope);
	  /* If it is a typedef to current class, use the current
	     class instead, as the typedef won't have any names inside
	     it yet.  */
	  if (!COMPLETE_TYPE_P (new_scope)
	      && currently_open_class (new_scope))
	    new_scope = TYPE_MAIN_VARIANT (new_scope);
	}
      /* Make sure we look in the right scope the next time through
	 the loop.  */
      parser->scope = new_scope;
    }

  /* If parsing tentatively, replace the sequence of tokens that makes
     up the nested-name-specifier with a CPP_NESTED_NAME_SPECIFIER
     token.  That way, should we re-parse the token stream, we will
     not have to repeat the effort required to do the parse, nor will
     we issue duplicate error messages.  */
  if (success && start)
    {
      cp_token *token;

      token = cp_lexer_token_at (parser->lexer, start);
      /* Reset the contents of the START token.  */
      token->type = CPP_NESTED_NAME_SPECIFIER;
      /* Retrieve any deferred checks.  Do not pop this access checks yet
	 so the memory will not be reclaimed during token replacing below.  */
      token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
      token->tree_check_p = true;
      token->u.tree_check_value->value = parser->scope;
      token->u.tree_check_value->checks = get_deferred_access_checks ();
      token->u.tree_check_value->qualifying_scope =
	parser->qualifying_scope;
      token->keyword = RID_MAX;

      /* Purge all subsequent tokens.  */
      cp_lexer_purge_tokens_after (parser->lexer, start);
    }

  if (start)
    pop_to_parent_deferring_access_checks ();

  return success ? parser->scope : NULL_TREE;
}

/* Parse a nested-name-specifier.  See
   cp_parser_nested_name_specifier_opt for details.  This function
   behaves identically, except that it will an issue an error if no
   nested-name-specifier is present.  */

static tree
cp_parser_nested_name_specifier (cp_parser *parser,
				 bool typename_keyword_p,
				 bool check_dependency_p,
				 bool type_p,
				 bool is_declaration)
{
  tree scope;

  /* Look for the nested-name-specifier.  */
  scope = cp_parser_nested_name_specifier_opt (parser,
					       typename_keyword_p,
					       check_dependency_p,
					       type_p,
					       is_declaration);
  /* If it was not present, issue an error message.  */
  if (!scope)
    {
      cp_parser_error (parser, "expected nested-name-specifier");
      parser->scope = NULL_TREE;
    }

  return scope;
}

/* Parse the qualifying entity in a nested-name-specifier. For C++98,
   this is either a class-name or a namespace-name (which corresponds
   to the class-or-namespace-name production in the grammar). For
   C++0x, it can also be a type-name that refers to an enumeration
   type or a simple-template-id.

   TYPENAME_KEYWORD_P is TRUE iff the `typename' keyword is in effect.
   TEMPLATE_KEYWORD_P is TRUE iff the `template' keyword is in effect.
   CHECK_DEPENDENCY_P is FALSE iff dependent names should be looked up.
   TYPE_P is TRUE iff the next name should be taken as a class-name,
   even the same name is declared to be another entity in the same
   scope.

   Returns the class (TYPE_DECL) or namespace (NAMESPACE_DECL)
   specified by the class-or-namespace-name.  If neither is found the
   ERROR_MARK_NODE is returned.  */

static tree
cp_parser_qualifying_entity (cp_parser *parser,
			     bool typename_keyword_p,
			     bool template_keyword_p,
			     bool check_dependency_p,
			     bool type_p,
			     bool is_declaration)
{
  tree saved_scope;
  tree saved_qualifying_scope;
  tree saved_object_scope;
  tree scope;
  bool only_class_p;
  bool successful_parse_p;

  /* DR 743: decltype can appear in a nested-name-specifier.  */
  if (cp_lexer_next_token_is_decltype (parser->lexer))
    {
      scope = cp_parser_decltype (parser);
      if (TREE_CODE (scope) != ENUMERAL_TYPE
	  && !MAYBE_CLASS_TYPE_P (scope))
	{
	  cp_parser_simulate_error (parser);
	  return error_mark_node;
	}
      if (TYPE_NAME (scope))
	scope = TYPE_NAME (scope);
      return scope;
    }

  /* Before we try to parse the class-name, we must save away the
     current PARSER->SCOPE since cp_parser_class_name will destroy
     it.  */
  saved_scope = parser->scope;
  saved_qualifying_scope = parser->qualifying_scope;
  saved_object_scope = parser->object_scope;
  /* Try for a class-name first.  If the SAVED_SCOPE is a type, then
     there is no need to look for a namespace-name.  */
  only_class_p = template_keyword_p
    || (saved_scope && TYPE_P (saved_scope) && cxx_dialect == cxx98);
  if (!only_class_p)
    cp_parser_parse_tentatively (parser);
  scope = cp_parser_class_name (parser,
				typename_keyword_p,
				template_keyword_p,
				type_p ? class_type : none_type,
				check_dependency_p,
				/*class_head_p=*/false,
				is_declaration,
				/*enum_ok=*/cxx_dialect > cxx98);
  successful_parse_p = only_class_p || cp_parser_parse_definitely (parser);
  /* If that didn't work, try for a namespace-name.  */
  if (!only_class_p && !successful_parse_p)
    {
      /* Restore the saved scope.  */
      parser->scope = saved_scope;
      parser->qualifying_scope = saved_qualifying_scope;
      parser->object_scope = saved_object_scope;
      /* If we are not looking at an identifier followed by the scope
	 resolution operator, then this is not part of a
	 nested-name-specifier.  (Note that this function is only used
	 to parse the components of a nested-name-specifier.)  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME)
	  || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
	return error_mark_node;
      scope = cp_parser_namespace_name (parser);
    }

  return scope;
}

/* Return true if we are looking at a compound-literal, false otherwise.  */

static bool
cp_parser_compound_literal_p (cp_parser *parser)
{
  cp_lexer_save_tokens (parser->lexer);

  /* Skip tokens until the next token is a closing parenthesis.
     If we find the closing `)', and the next token is a `{', then
     we are looking at a compound-literal.  */
  bool compound_literal_p
    = (cp_parser_skip_to_closing_parenthesis (parser, false, false,
					      /*consume_paren=*/true)
       && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE));

  /* Roll back the tokens we skipped.  */
  cp_lexer_rollback_tokens (parser->lexer);

  return compound_literal_p;
}

/* Return true if EXPR is the integer constant zero or a complex constant
   of zero, without any folding, but ignoring location wrappers.  */

bool
literal_integer_zerop (const_tree expr)
{
  return (location_wrapper_p (expr)
	  && integer_zerop (TREE_OPERAND (expr, 0)));
}

/* Parse a postfix-expression.

   postfix-expression:
     primary-expression
     postfix-expression [ expression ]
     postfix-expression ( expression-list [opt] )
     simple-type-specifier ( expression-list [opt] )
     typename :: [opt] nested-name-specifier identifier
       ( expression-list [opt] )
     typename :: [opt] nested-name-specifier template [opt] template-id
       ( expression-list [opt] )
     postfix-expression . template [opt] id-expression
     postfix-expression -> template [opt] id-expression
     postfix-expression . pseudo-destructor-name
     postfix-expression -> pseudo-destructor-name
     postfix-expression ++
     postfix-expression --
     dynamic_cast < type-id > ( expression )
     static_cast < type-id > ( expression )
     reinterpret_cast < type-id > ( expression )
     const_cast < type-id > ( expression )
     typeid ( expression )
     typeid ( type-id )

   GNU Extension:

   postfix-expression:
     ( type-id ) { initializer-list , [opt] }

   This extension is a GNU version of the C99 compound-literal
   construct.  (The C99 grammar uses `type-name' instead of `type-id',
   but they are essentially the same concept.)

   If ADDRESS_P is true, the postfix expression is the operand of the
   `&' operator.  CAST_P is true if this expression is the target of a
   cast.

   If MEMBER_ACCESS_ONLY_P, we only allow postfix expressions that are
   class member access expressions [expr.ref].

   Returns a representation of the expression.  */

static cp_expr
cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                              bool member_access_only_p, bool decltype_p,
			      cp_id_kind * pidk_return)
{
  cp_token *token;
  location_t loc;
  enum rid keyword;
  cp_id_kind idk = CP_ID_KIND_NONE;
  cp_expr postfix_expression = NULL_TREE;
  bool is_member_access = false;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  loc = token->location;
  location_t start_loc = get_range_from_loc (line_table, loc).m_start;

  /* Some of the productions are determined by keywords.  */
  keyword = token->keyword;
  switch (keyword)
    {
    case RID_DYNCAST:
    case RID_STATCAST:
    case RID_REINTCAST:
    case RID_CONSTCAST:
      {
	tree type;
	cp_expr expression;
	const char *saved_message;
	bool saved_in_type_id_in_expr_p;

	/* All of these can be handled in the same way from the point
	   of view of parsing.  Begin by consuming the token
	   identifying the cast.  */
	cp_lexer_consume_token (parser->lexer);

	/* New types cannot be defined in the cast.  */
	saved_message = parser->type_definition_forbidden_message;
	parser->type_definition_forbidden_message
	  = G_("types may not be defined in casts");

	/* Look for the opening `<'.  */
	cp_parser_require (parser, CPP_LESS, RT_LESS);
	/* Parse the type to which we are casting.  */
	saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
	parser->in_type_id_in_expr_p = true;
	type = cp_parser_type_id (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
				  NULL);
	parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
	/* Look for the closing `>'.  */
	cp_parser_require (parser, CPP_GREATER, RT_GREATER);
	/* Restore the old message.  */
	parser->type_definition_forbidden_message = saved_message;

	bool saved_greater_than_is_operator_p
	  = parser->greater_than_is_operator_p;
	parser->greater_than_is_operator_p = true;

	/* And the expression which is being cast.  */
	matching_parens parens;
	parens.require_open (parser);
	expression = cp_parser_expression (parser, & idk, /*cast_p=*/true);
	cp_token *close_paren = cp_parser_require (parser, CPP_CLOSE_PAREN,
						   RT_CLOSE_PAREN);
	location_t end_loc = close_paren ?
	  close_paren->location : UNKNOWN_LOCATION;

	parser->greater_than_is_operator_p
	  = saved_greater_than_is_operator_p;

	/* Only type conversions to integral or enumeration types
	   can be used in constant-expressions.  */
	if (!cast_valid_in_integral_constant_expression_p (type)
	    && cp_parser_non_integral_constant_expression (parser, NIC_CAST))
	  {
	    postfix_expression = error_mark_node;
	    break;
	  }

	/* Construct a location e.g. :
	     reinterpret_cast <int *> (expr)
	     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	   ranging from the start of the "*_cast" token to the final closing
	   paren, with the caret at the start.  */
	location_t cp_cast_loc = make_location (start_loc, start_loc, end_loc);

	switch (keyword)
	  {
	  case RID_DYNCAST:
	    postfix_expression
	      = build_dynamic_cast (cp_cast_loc, type, expression,
				    tf_warning_or_error);
	    break;
	  case RID_STATCAST:
	    postfix_expression
	      = build_static_cast (cp_cast_loc, type, expression,
				   tf_warning_or_error);
	    break;
	  case RID_REINTCAST:
	    postfix_expression
	      = build_reinterpret_cast (cp_cast_loc, type, expression,
                                        tf_warning_or_error);
	    break;
	  case RID_CONSTCAST:
	    postfix_expression
	      = build_const_cast (cp_cast_loc, type, expression,
				  tf_warning_or_error);
	    break;
	  default:
	    gcc_unreachable ();
	  }
      }
      break;

    case RID_TYPEID:
      {
	tree type;
	const char *saved_message;
	bool saved_in_type_id_in_expr_p;

	/* Consume the `typeid' token.  */
	cp_lexer_consume_token (parser->lexer);
	/* Look for the `(' token.  */
	matching_parens parens;
	parens.require_open (parser);
	/* Types cannot be defined in a `typeid' expression.  */
	saved_message = parser->type_definition_forbidden_message;
	parser->type_definition_forbidden_message
	  = G_("types may not be defined in a %<typeid%> expression");
	/* We can't be sure yet whether we're looking at a type-id or an
	   expression.  */
	cp_parser_parse_tentatively (parser);
	/* Try a type-id first.  */
	saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
	parser->in_type_id_in_expr_p = true;
	type = cp_parser_type_id (parser);
	parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
	/* Look for the `)' token.  Otherwise, we can't be sure that
	   we're not looking at an expression: consider `typeid (int
	   (3))', for example.  */
	cp_token *close_paren = parens.require_close (parser);
	/* If all went well, simply lookup the type-id.  */
	if (cp_parser_parse_definitely (parser))
	  postfix_expression = get_typeid (type, tf_warning_or_error);
	/* Otherwise, fall back to the expression variant.  */
	else
	  {
	    tree expression;

	    /* Look for an expression.  */
	    expression = cp_parser_expression (parser, & idk);
	    /* Compute its typeid.  */
	    postfix_expression = build_typeid (expression, tf_warning_or_error);
	    /* Look for the `)' token.  */
	    close_paren = parens.require_close (parser);
	  }
	/* Restore the saved message.  */
	parser->type_definition_forbidden_message = saved_message;
	/* `typeid' may not appear in an integral constant expression.  */
	if (cp_parser_non_integral_constant_expression (parser, NIC_TYPEID))
	  postfix_expression = error_mark_node;

	/* Construct a location e.g. :
	     typeid (expr)
	     ^~~~~~~~~~~~~
	   ranging from the start of the "typeid" token to the final closing
	   paren, with the caret at the start.  */
	if (close_paren)
	  {
	    location_t typeid_loc
	      = make_location (start_loc, start_loc, close_paren->location);
	    postfix_expression.set_location (typeid_loc);
	    postfix_expression.maybe_add_location_wrapper ();
	  }
      }
      break;

    case RID_TYPENAME:
      {
	tree type;
	/* The syntax permitted here is the same permitted for an
	   elaborated-type-specifier.  */
        ++parser->prevent_constrained_type_specifiers;
	type = cp_parser_elaborated_type_specifier (parser,
						    /*is_friend=*/false,
						    /*is_declaration=*/false);
        --parser->prevent_constrained_type_specifiers;
	postfix_expression = cp_parser_functional_cast (parser, type);
      }
      break;

    case RID_ADDRESSOF:
    case RID_BUILTIN_SHUFFLE:
    case RID_BUILTIN_SHUFFLEVECTOR:
    case RID_BUILTIN_LAUNDER:
    case RID_BUILTIN_ASSOC_BARRIER:
      {
	vec<tree, va_gc> *vec;

	cp_lexer_consume_token (parser->lexer);
	vec = cp_parser_parenthesized_expression_list (parser, non_attr,
		    /*cast_p=*/false, /*allow_expansion_p=*/true,
		    /*non_constant_p=*/NULL);
	if (vec == NULL)
	  {
	    postfix_expression = error_mark_node;
	    break;
	  }

	for (tree p : *vec)
	  mark_exp_read (p);

	switch (keyword)
	  {
	  case RID_ADDRESSOF:
	    if (vec->length () == 1)
	      postfix_expression
		= cp_build_addressof (loc, (*vec)[0], tf_warning_or_error);
	    else
	      {
		error_at (loc, "wrong number of arguments to "
			       "%<__builtin_addressof%>");
		postfix_expression = error_mark_node;
	      }
	    break;

	  case RID_BUILTIN_LAUNDER:
	    if (vec->length () == 1)
	      postfix_expression = finish_builtin_launder (loc, (*vec)[0],
							   tf_warning_or_error);
	    else
	      {
		error_at (loc, "wrong number of arguments to "
			       "%<__builtin_launder%>");
		postfix_expression = error_mark_node;
	      }
	    break;

	  case RID_BUILTIN_ASSOC_BARRIER:
	    if (vec->length () == 1)
	      postfix_expression = build1_loc (loc, PAREN_EXPR,
					       TREE_TYPE ((*vec)[0]),
					       (*vec)[0]);
	    else
	      {
		error_at (loc, "wrong number of arguments to "
			       "%<__builtin_assoc_barrier%>");
		postfix_expression = error_mark_node;
	      }
	    break;

	  case RID_BUILTIN_SHUFFLE:
	    if (vec->length () == 2)
	      postfix_expression
		= build_x_vec_perm_expr (loc, (*vec)[0], NULL_TREE,
					 (*vec)[1], tf_warning_or_error);
	    else if (vec->length () == 3)
	      postfix_expression
		= build_x_vec_perm_expr (loc, (*vec)[0], (*vec)[1],
					 (*vec)[2], tf_warning_or_error);
	    else
	      {
		error_at (loc, "wrong number of arguments to "
			       "%<__builtin_shuffle%>");
		postfix_expression = error_mark_node;
	      }
	    break;

	  case RID_BUILTIN_SHUFFLEVECTOR:
	    if (vec->length () < 3)
	      {
		error_at (loc, "wrong number of arguments to "
			       "%<__builtin_shufflevector%>");
		postfix_expression = error_mark_node;
	      }
	    else
	      {
		postfix_expression
		  = build_x_shufflevector (loc, vec, tf_warning_or_error);
	      }
	    break;

	  default:
	    gcc_unreachable ();
	  }
	break;
      }

    case RID_BUILTIN_CONVERTVECTOR:
      {
	tree expression;
	tree type;
	/* Consume the `__builtin_convertvector' token.  */
	cp_lexer_consume_token (parser->lexer);
	/* Look for the opening `('.  */
	matching_parens parens;
	parens.require_open (parser);
	/* Now, parse the assignment-expression.  */
	expression = cp_parser_assignment_expression (parser);
	/* Look for the `,'.  */
	cp_parser_require (parser, CPP_COMMA, RT_COMMA);
	location_t type_location
	  = cp_lexer_peek_token (parser->lexer)->location;
	/* Parse the type-id.  */
	{
	  type_id_in_expr_sentinel s (parser);
	  type = cp_parser_type_id (parser);
	}
	/* Look for the closing `)'.  */
	parens.require_close (parser);
	postfix_expression
	  = cp_build_vec_convert (expression, type_location, type,
				  tf_warning_or_error);
	break;
      }

    case RID_BUILTIN_BIT_CAST:
      {
	tree expression;
	tree type;
	/* Consume the `__builtin_bit_cast' token.  */
	cp_lexer_consume_token (parser->lexer);
	/* Look for the opening `('.  */
	matching_parens parens;
	parens.require_open (parser);
	location_t type_location
	  = cp_lexer_peek_token (parser->lexer)->location;
	/* Parse the type-id.  */
	{
	  type_id_in_expr_sentinel s (parser);
	  type = cp_parser_type_id (parser);
	}
	/* Look for the `,'.  */
	cp_parser_require (parser, CPP_COMMA, RT_COMMA);
	/* Now, parse the assignment-expression.  */
	expression = cp_parser_assignment_expression (parser);
	/* Look for the closing `)'.  */
	parens.require_close (parser);
	postfix_expression
	  = cp_build_bit_cast (type_location, type, expression,
			       tf_warning_or_error);
	break;
      }

    default:
      {
	tree type;

	/* If the next thing is a simple-type-specifier, we may be
	   looking at a functional cast.  We could also be looking at
	   an id-expression.  So, we try the functional cast, and if
	   that doesn't work we fall back to the primary-expression.  */
	cp_parser_parse_tentatively (parser);
	/* Look for the simple-type-specifier.  */
        ++parser->prevent_constrained_type_specifiers;
	type = cp_parser_simple_type_specifier (parser,
						/*decl_specs=*/NULL,
						CP_PARSER_FLAGS_NONE);
        --parser->prevent_constrained_type_specifiers;
	/* Parse the cast itself.  */
	if (!cp_parser_error_occurred (parser))
	  postfix_expression
	    = cp_parser_functional_cast (parser, type);
	/* If that worked, we're done.  */
	if (cp_parser_parse_definitely (parser))
	  break;

	/* If the functional-cast didn't work out, try a
	   compound-literal.  */
	if (cp_parser_allow_gnu_extensions_p (parser)
	    && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
	  {
	    cp_expr initializer = NULL_TREE;

	    cp_parser_parse_tentatively (parser);

	    matching_parens parens;
	    parens.consume_open (parser);

	    /* Avoid calling cp_parser_type_id pointlessly, see comment
	       in cp_parser_cast_expression about c++/29234.  */
	    if (!cp_parser_compound_literal_p (parser))
	      cp_parser_simulate_error (parser);
	    else
	      {
		/* Parse the type.  */
		bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
		parser->in_type_id_in_expr_p = true;
		type = cp_parser_type_id (parser);
		parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
		parens.require_close (parser);
	      }

	    /* If things aren't going well, there's no need to
	       keep going.  */
	    if (!cp_parser_error_occurred (parser))
	      {
		bool non_constant_p;
		/* Parse the brace-enclosed initializer list.  */
		initializer = cp_parser_braced_list (parser,
						     &non_constant_p);
	      }
	    /* If that worked, we're definitely looking at a
	       compound-literal expression.  */
	    if (cp_parser_parse_definitely (parser))
	      {
		/* Warn the user that a compound literal is not
		   allowed in standard C++.  */
		pedwarn (input_location, OPT_Wpedantic,
			 "ISO C++ forbids compound-literals");
		/* For simplicity, we disallow compound literals in
		   constant-expressions.  We could
		   allow compound literals of integer type, whose
		   initializer was a constant, in constant
		   expressions.  Permitting that usage, as a further
		   extension, would not change the meaning of any
		   currently accepted programs.  (Of course, as
		   compound literals are not part of ISO C++, the
		   standard has nothing to say.)  */
		if (cp_parser_non_integral_constant_expression (parser,
								NIC_NCC))
		  {
		    postfix_expression = error_mark_node;
		    break;
		  }
		/* Form the representation of the compound-literal.  */
		postfix_expression
		  = finish_compound_literal (type, initializer,
					     tf_warning_or_error, fcl_c99);
		postfix_expression.set_location (initializer.get_location ());
		break;
	      }
	  }

	/* It must be a primary-expression.  */
	postfix_expression
	  = cp_parser_primary_expression (parser, address_p, cast_p,
					  /*template_arg_p=*/false,
					  decltype_p,
					  &idk);
      }
      break;
    }

  /* Note that we don't need to worry about calling build_cplus_new on a
     class-valued CALL_EXPR in decltype when it isn't the end of the
     postfix-expression; unary_complex_lvalue will take care of that for
     all these cases.  */

  /* Keep looping until the postfix-expression is complete.  */
  while (true)
    {
      if (idk == CP_ID_KIND_UNQUALIFIED
	  && identifier_p (postfix_expression)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
	/* It is not a Koenig lookup function call.  */
	postfix_expression
	  = unqualified_name_lookup_error (postfix_expression);

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_OPEN_SQUARE:
	  if (cp_next_tokens_can_be_std_attribute_p (parser))
	    {
	      cp_parser_error (parser,
			       "two consecutive %<[%> shall "
			       "only introduce an attribute");
	      return error_mark_node;
	    }
	  postfix_expression
	    = cp_parser_postfix_open_square_expression (parser,
							postfix_expression,
							false,
							decltype_p);
	  postfix_expression.set_range (start_loc,
					postfix_expression.get_location ());

	  idk = CP_ID_KIND_NONE;
          is_member_access = false;
	  break;

	case CPP_OPEN_PAREN:
	  /* postfix-expression ( expression-list [opt] ) */
	  {
	    bool koenig_p;
	    bool is_builtin_constant_p;
	    bool saved_integral_constant_expression_p = false;
	    bool saved_non_integral_constant_expression_p = false;
	    tsubst_flags_t complain = complain_flags (decltype_p);
	    vec<tree, va_gc> *args;
	    location_t close_paren_loc = UNKNOWN_LOCATION;
	    location_t combined_loc = UNKNOWN_LOCATION;

            is_member_access = false;

	    tree stripped_expression
	      = tree_strip_any_location_wrapper (postfix_expression);
	    is_builtin_constant_p
	      = DECL_IS_BUILTIN_CONSTANT_P (stripped_expression);
	    if (is_builtin_constant_p)
	      {
		/* The whole point of __builtin_constant_p is to allow
		   non-constant expressions to appear as arguments.  */
		saved_integral_constant_expression_p
		  = parser->integral_constant_expression_p;
		saved_non_integral_constant_expression_p
		  = parser->non_integral_constant_expression_p;
		parser->integral_constant_expression_p = false;
	      }
	    args = (cp_parser_parenthesized_expression_list
		    (parser, non_attr,
		     /*cast_p=*/false, /*allow_expansion_p=*/true,
		     /*non_constant_p=*/NULL,
		     /*close_paren_loc=*/&close_paren_loc,
		     /*wrap_locations_p=*/true));
	    if (is_builtin_constant_p)
	      {
		parser->integral_constant_expression_p
		  = saved_integral_constant_expression_p;
		parser->non_integral_constant_expression_p
		  = saved_non_integral_constant_expression_p;
	      }

	    if (args == NULL)
	      {
		postfix_expression = error_mark_node;
		break;
	      }

	    /* Function calls are not permitted in
	       constant-expressions.  */
	    if (! builtin_valid_in_constant_expr_p (postfix_expression)
		&& cp_parser_non_integral_constant_expression (parser,
							       NIC_FUNC_CALL))
	      {
		postfix_expression = error_mark_node;
		release_tree_vector (args);
		break;
	      }

	    koenig_p = false;
	    if (idk == CP_ID_KIND_UNQUALIFIED
		|| idk == CP_ID_KIND_TEMPLATE_ID)
	      {
		if (identifier_p (postfix_expression)
		    /* In C++20, we may need to perform ADL for a template
		       name.  */
		    || (TREE_CODE (postfix_expression) == TEMPLATE_ID_EXPR
			&& identifier_p (TREE_OPERAND (postfix_expression, 0))))
		  {
		    if (!args->is_empty ())
		      {
			koenig_p = true;
			if (!any_type_dependent_arguments_p (args))
			  postfix_expression
			    = perform_koenig_lookup (postfix_expression, args,
						     complain);
		      }
		    else
		      postfix_expression
			= unqualified_fn_lookup_error (postfix_expression);
		  }
		/* We do not perform argument-dependent lookup if
		   normal lookup finds a non-function, in accordance
		   with the expected resolution of DR 218.  */
		else if (!args->is_empty ()
			 && is_overloaded_fn (postfix_expression))
		  {
		    /* Do not do argument dependent lookup if regular
		       lookup finds a member function or a block-scope
		       function declaration.  [basic.lookup.argdep]/3  */
		    bool do_adl_p = true;
		    tree fns = get_fns (postfix_expression);
		    for (lkp_iterator iter (fns); iter; ++iter)
		      {
			tree fn = STRIP_TEMPLATE (*iter);
			if ((TREE_CODE (fn) == USING_DECL
			     && DECL_DEPENDENT_P (fn))
			    || DECL_FUNCTION_MEMBER_P (fn)
			    || DECL_LOCAL_DECL_P (fn))
			  {
			    do_adl_p = false;
			    break;
			  }
		      }

		    if (do_adl_p)
		      {
			koenig_p = true;
			if (!any_type_dependent_arguments_p (args))
			  postfix_expression
			    = perform_koenig_lookup (postfix_expression, args,
						     complain);
		      }
		  }
	      }

	    /* Temporarily set input_location to the combined location
	       with call expression range, as e.g. build_out_target_exprs
	       called from convert_default_arg relies on input_location,
	       so updating it only when the call is fully built results
	       in inconsistencies between location handling in templates
	       and outside of templates.  */
	    if (close_paren_loc != UNKNOWN_LOCATION)
	      combined_loc = make_location (token->location, start_loc,
					    close_paren_loc);
	    iloc_sentinel ils (combined_loc);

	    if (TREE_CODE (postfix_expression) == COMPONENT_REF)
	      {
		tree instance = TREE_OPERAND (postfix_expression, 0);
		tree fn = TREE_OPERAND (postfix_expression, 1);

		if (processing_template_decl
		    && (type_dependent_object_expression_p (instance)
			|| (!BASELINK_P (fn)
			    && TREE_CODE (fn) != FIELD_DECL)
			|| type_dependent_expression_p (fn)
			|| any_type_dependent_arguments_p (args)))
		  {
		    maybe_generic_this_capture (instance, fn);
		    postfix_expression
		      = build_min_nt_call_vec (postfix_expression, args);
		  }
		else if (BASELINK_P (fn))
		  {
		  postfix_expression
		    = (build_new_method_call
		       (instance, fn, &args, NULL_TREE,
			(idk == CP_ID_KIND_QUALIFIED
			 ? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
			 : LOOKUP_NORMAL),
			/*fn_p=*/NULL,
			complain));
		  }
		else
		  postfix_expression
		    = finish_call_expr (postfix_expression, &args,
					/*disallow_virtual=*/false,
					/*koenig_p=*/false,
					complain);
	      }
	    else if (TREE_CODE (postfix_expression) == OFFSET_REF
		     || TREE_CODE (postfix_expression) == MEMBER_REF
		     || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
	      postfix_expression = (build_offset_ref_call_from_tree
				    (postfix_expression, &args,
				     complain));
	    else if (idk == CP_ID_KIND_QUALIFIED)
	      /* A call to a static class member, or a namespace-scope
		 function.  */
	      postfix_expression
		= finish_call_expr (postfix_expression, &args,
				    /*disallow_virtual=*/true,
				    koenig_p,
				    complain);
	    else
	      /* All other function calls.  */
	      postfix_expression
		= finish_call_expr (postfix_expression, &args,
				    /*disallow_virtual=*/false,
				    koenig_p,
				    complain);

	    if (close_paren_loc != UNKNOWN_LOCATION)
	      postfix_expression.set_location (combined_loc);

	    /* The POSTFIX_EXPRESSION is certainly no longer an id.  */
	    idk = CP_ID_KIND_NONE;

	    release_tree_vector (args);
	  }
	  break;

	case CPP_DOT:
	case CPP_DEREF:
	  /* postfix-expression . template [opt] id-expression
	     postfix-expression . pseudo-destructor-name
	     postfix-expression -> template [opt] id-expression
	     postfix-expression -> pseudo-destructor-name */

	  /* Consume the `.' or `->' operator.  */
	  cp_lexer_consume_token (parser->lexer);

	  postfix_expression
	    = cp_parser_postfix_dot_deref_expression (parser, token->type,
						      postfix_expression,
						      false, &idk, loc);

          is_member_access = true;
	  break;

	case CPP_PLUS_PLUS:
	  /* postfix-expression ++  */
	  /* Consume the `++' token.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Generate a representation for the complete expression.  */
	  postfix_expression
	    = finish_increment_expr (postfix_expression,
				     POSTINCREMENT_EXPR);
	  /* Increments may not appear in constant-expressions.  */
	  if (cp_parser_non_integral_constant_expression (parser, NIC_INC))
	    postfix_expression = error_mark_node;
	  idk = CP_ID_KIND_NONE;
          is_member_access = false;
	  break;

	case CPP_MINUS_MINUS:
	  /* postfix-expression -- */
	  /* Consume the `--' token.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Generate a representation for the complete expression.  */
	  postfix_expression
	    = finish_increment_expr (postfix_expression,
				     POSTDECREMENT_EXPR);
	  /* Decrements may not appear in constant-expressions.  */
	  if (cp_parser_non_integral_constant_expression (parser, NIC_DEC))
	    postfix_expression = error_mark_node;
	  idk = CP_ID_KIND_NONE;
          is_member_access = false;
	  break;

	default:
	  if (pidk_return != NULL)
	    * pidk_return = idk;
          if (member_access_only_p)
            return is_member_access
              ? postfix_expression
              : cp_expr (error_mark_node);
          else
            return postfix_expression;
	}
    }
}

/* Helper function for cp_parser_parenthesized_expression_list and
   cp_parser_postfix_open_square_expression.  Parse a single element
   of parenthesized expression list.  */

static cp_expr
cp_parser_parenthesized_expression_list_elt (cp_parser *parser, bool cast_p,
					     bool allow_expansion_p,
					     bool *non_constant_p)
{
  cp_expr expr (NULL_TREE);
  bool expr_non_constant_p;

  /* Parse the next assignment-expression.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      /* A braced-init-list.  */
      cp_lexer_set_source_position (parser->lexer);
      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
      expr = cp_parser_braced_list (parser, &expr_non_constant_p);
      if (non_constant_p && expr_non_constant_p)
	*non_constant_p = true;
    }
  else if (non_constant_p)
    {
      expr = cp_parser_constant_expression (parser,
					    /*allow_non_constant_p=*/true,
					    &expr_non_constant_p);
      if (expr_non_constant_p)
	*non_constant_p = true;
    }
  else
    expr = cp_parser_assignment_expression (parser, /*pidk=*/NULL, cast_p);

  /* If we have an ellipsis, then this is an expression expansion.  */
  if (allow_expansion_p
      && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    {
      /* Consume the `...'.  */
      cp_lexer_consume_token (parser->lexer);

      /* Build the argument pack.  */
      expr = make_pack_expansion (expr);
    }
  return expr;
}

/* A subroutine of cp_parser_postfix_expression that also gets hijacked
   by cp_parser_builtin_offsetof.  We're looking for

     postfix-expression [ expression ]
     postfix-expression [ braced-init-list ] (C++11)
     postfix-expression [ expression-list[opt] ] (C++23)

   FOR_OFFSETOF is set if we're being called in that context, which
   changes how we deal with integer constant expressions.  */

static tree
cp_parser_postfix_open_square_expression (cp_parser *parser,
					  tree postfix_expression,
					  bool for_offsetof,
					  bool decltype_p)
{
  tree index = NULL_TREE;
  releasing_vec expression_list = NULL;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
  bool saved_greater_than_is_operator_p;

  /* Consume the `[' token.  */
  cp_lexer_consume_token (parser->lexer);

  saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
  parser->greater_than_is_operator_p = true;

  /* Parse the index expression.  */
  /* ??? For offsetof, there is a question of what to allow here.  If
     offsetof is not being used in an integral constant expression context,
     then we *could* get the right answer by computing the value at runtime.
     If we are in an integral constant expression context, then we might
     could accept any constant expression; hard to say without analysis.
     Rather than open the barn door too wide right away, allow only integer
     constant expressions here.  */
  if (for_offsetof)
    index = cp_parser_constant_expression (parser);
  else
    {
      if (cxx_dialect >= cxx23
	  && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
	*&expression_list = make_tree_vector ();
      else if (cxx_dialect >= cxx23)
	{
	  while (true)
	    {
	      cp_expr expr
		= cp_parser_parenthesized_expression_list_elt (parser,
							       /*cast_p=*/
							       false,
							       /*allow_exp_p=*/
							       true,
							       /*non_cst_p=*/
							       NULL);

	      if (expr == error_mark_node)
		index = error_mark_node;
	      else if (expression_list.get () == NULL
		       && !PACK_EXPANSION_P (expr.get_value ()))
		index = expr.get_value ();
	      else
		vec_safe_push (expression_list, expr.get_value ());

	      /* If the next token isn't a `,', then we are done.  */
	      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
		break;

	      if (expression_list.get () == NULL && index != error_mark_node)
		{
		  *&expression_list = make_tree_vector_single (index);
		  index = NULL_TREE;
		}

	      /* Otherwise, consume the `,' and keep going.  */
	      cp_lexer_consume_token (parser->lexer);
	    }
	  if (expression_list.get () && index == error_mark_node)
	    expression_list.release ();
	}
      else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	{
	  bool expr_nonconst_p;
	  cp_lexer_set_source_position (parser->lexer);
	  maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
	  index = cp_parser_braced_list (parser, &expr_nonconst_p);
	}
      else
	index = cp_parser_expression (parser, NULL, /*cast_p=*/false,
				      /*decltype_p=*/false,
				      /*warn_comma_p=*/warn_comma_subscript);
    }

  parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;

  /* Look for the closing `]'.  */
  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);

  /* Build the ARRAY_REF.  */
  postfix_expression = grok_array_decl (loc, postfix_expression,
					index, &expression_list,
					tf_warning_or_error
					| (decltype_p ? tf_decltype : 0));

  /* When not doing offsetof, array references are not permitted in
     constant-expressions.  */
  if (!for_offsetof
      && (cp_parser_non_integral_constant_expression (parser, NIC_ARRAY_REF)))
    postfix_expression = error_mark_node;

  return postfix_expression;
}

/* A subroutine of cp_parser_postfix_dot_deref_expression.  Handle dot
   dereference of incomplete type, returns true if error_mark_node should
   be returned from caller, otherwise adjusts *SCOPE, *POSTFIX_EXPRESSION
   and *DEPENDENT_P.  */

bool
cp_parser_dot_deref_incomplete (tree *scope, cp_expr *postfix_expression,
				bool *dependent_p)
{
  /* In a template, be permissive by treating an object expression
     of incomplete type as dependent (after a pedwarn).  */
  diagnostic_t kind = (processing_template_decl
		       && MAYBE_CLASS_TYPE_P (*scope) ? DK_PEDWARN : DK_ERROR);

  switch (TREE_CODE (*postfix_expression))
    {
    case CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case CONST_CAST_EXPR:
    case STATIC_CAST_EXPR:
    case DYNAMIC_CAST_EXPR:
    case IMPLICIT_CONV_EXPR:
    case VIEW_CONVERT_EXPR:
    case NON_LVALUE_EXPR:
      kind = DK_ERROR;
      break;
    case OVERLOAD:
      /* Don't emit any diagnostic for OVERLOADs.  */
      kind = DK_IGNORED;
      break;
    default:
      /* Avoid clobbering e.g. DECLs.  */
      if (!EXPR_P (*postfix_expression))
	kind = DK_ERROR;
      break;
    }

  if (kind == DK_IGNORED)
    return false;

  location_t exploc = location_of (*postfix_expression);
  cxx_incomplete_type_diagnostic (exploc, *postfix_expression, *scope, kind);
  if (!MAYBE_CLASS_TYPE_P (*scope))
    return true;
  if (kind == DK_ERROR)
    *scope = *postfix_expression = error_mark_node;
  else if (processing_template_decl)
    {
      *dependent_p = true;
      *scope = TREE_TYPE (*postfix_expression) = NULL_TREE;
    }
  return false;
}

/* A subroutine of cp_parser_postfix_expression that also gets hijacked
   by cp_parser_builtin_offsetof.  We're looking for

     postfix-expression . template [opt] id-expression
     postfix-expression . pseudo-destructor-name
     postfix-expression -> template [opt] id-expression
     postfix-expression -> pseudo-destructor-name

   FOR_OFFSETOF is set if we're being called in that context.  That sorta
   limits what of the above we'll actually accept, but nevermind.
   TOKEN_TYPE is the "." or "->" token, which will already have been
   removed from the stream.  */

static tree
cp_parser_postfix_dot_deref_expression (cp_parser *parser,
					enum cpp_ttype token_type,
					cp_expr postfix_expression,
					bool for_offsetof, cp_id_kind *idk,
					location_t location)
{
  tree name;
  bool dependent_p;
  bool pseudo_destructor_p;
  tree scope = NULL_TREE;
  location_t start_loc = postfix_expression.get_start ();

  /* If this is a `->' operator, dereference the pointer.  */
  if (token_type == CPP_DEREF)
    postfix_expression = build_x_arrow (location, postfix_expression,
					tf_warning_or_error);
  /* Check to see whether or not the expression is type-dependent and
     not the current instantiation.  */
  dependent_p = type_dependent_object_expression_p (postfix_expression);
  /* The identifier following the `->' or `.' is not qualified.  */
  parser->scope = NULL_TREE;
  parser->qualifying_scope = NULL_TREE;
  parser->object_scope = NULL_TREE;
  *idk = CP_ID_KIND_NONE;

  /* Enter the scope corresponding to the type of the object
     given by the POSTFIX_EXPRESSION.  */
  if (!dependent_p)
    {
      scope = TREE_TYPE (postfix_expression);
      /* According to the standard, no expression should ever have
	 reference type.  Unfortunately, we do not currently match
	 the standard in this respect in that our internal representation
	 of an expression may have reference type even when the standard
	 says it does not.  Therefore, we have to manually obtain the
	 underlying type here.  */
      scope = non_reference (scope);
      /* The type of the POSTFIX_EXPRESSION must be complete.  */
      /* Unlike the object expression in other contexts, *this is not
	 required to be of complete type for purposes of class member
	 access (5.2.5) outside the member function body.  */
      if (postfix_expression != current_class_ref
	  && scope != error_mark_node
	  && !currently_open_class (scope))
	{
	  scope = complete_type (scope);
	  if (!COMPLETE_TYPE_P (scope)
	      && cp_parser_dot_deref_incomplete (&scope, &postfix_expression,
						 &dependent_p))
	    return error_mark_node;
	}

      if (!dependent_p)
	{
	  /* Let the name lookup machinery know that we are processing a
	     class member access expression.  */
	  parser->context->object_type = scope;
	  /* If something went wrong, we want to be able to discern that case,
	     as opposed to the case where there was no SCOPE due to the type
	     of expression being dependent.  */
	  if (!scope)
	    scope = error_mark_node;
	  /* If the SCOPE was erroneous, make the various semantic analysis
	     functions exit quickly -- and without issuing additional error
	     messages.  */
	  if (scope == error_mark_node)
	    postfix_expression = error_mark_node;
	}
    }

  if (dependent_p)
    {
      tree type = TREE_TYPE (postfix_expression);
      /* If we don't have a (type-dependent) object of class type, use
	 typeof to figure out the type of the object.  */
      if (type == NULL_TREE || is_auto (type))
	type = finish_typeof (postfix_expression);
      parser->context->object_type = type;
    }

  /* Assume this expression is not a pseudo-destructor access.  */
  pseudo_destructor_p = false;

  /* If the SCOPE is a scalar type, then, if this is a valid program,
     we must be looking at a pseudo-destructor-name.  If POSTFIX_EXPRESSION
     is type dependent, it can be pseudo-destructor-name or something else.
     Try to parse it as pseudo-destructor-name first.  */
  if ((scope && SCALAR_TYPE_P (scope)) || dependent_p)
    {
      tree s;
      tree type;

      cp_parser_parse_tentatively (parser);
      /* Parse the pseudo-destructor-name.  */
      s = NULL_TREE;
      cp_parser_pseudo_destructor_name (parser, postfix_expression,
					&s, &type);
      if (dependent_p
	  && (cp_parser_error_occurred (parser)
	      || !SCALAR_TYPE_P (type)))
	cp_parser_abort_tentative_parse (parser);
      else if (cp_parser_parse_definitely (parser))
	{
	  pseudo_destructor_p = true;
	  postfix_expression
	    = finish_pseudo_destructor_expr (postfix_expression,
					     s, type, location);
	}
    }

  if (!pseudo_destructor_p)
    {
      /* If the SCOPE is not a scalar type, we are looking at an
	 ordinary class member access expression, rather than a
	 pseudo-destructor-name.  */
      bool template_p;
      cp_token *token = cp_lexer_peek_token (parser->lexer);
      /* Parse the id-expression.  */
      name = (cp_parser_id_expression
	      (parser,
	       cp_parser_optional_template_keyword (parser),
	       /*check_dependency_p=*/true,
	       &template_p,
	       /*declarator_p=*/false,
	       /*optional_p=*/false));
      /* In general, build a SCOPE_REF if the member name is qualified.
	 However, if the name was not dependent and has already been
	 resolved; there is no need to build the SCOPE_REF.  For example;

	     struct X { void f(); };
	     template <typename T> void f(T* t) { t->X::f(); }

	 Even though "t" is dependent, "X::f" is not and has been resolved
	 to a BASELINK; there is no need to include scope information.  */

      /* But we do need to remember that there was an explicit scope for
	 virtual function calls.  */
      if (parser->scope)
	*idk = CP_ID_KIND_QUALIFIED;

      /* If the name is a template-id that names a type, we will get a
	 TYPE_DECL here.  That is invalid code.  */
      if (TREE_CODE (name) == TYPE_DECL)
	{
	  error_at (token->location, "invalid use of %qD", name);
	  postfix_expression = error_mark_node;
	}
      else
	{
	  if (name != error_mark_node && !BASELINK_P (name) && parser->scope)
	    {
	      if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
		{
		  error_at (token->location, "%<%D::%D%> is not a class member",
			    parser->scope, name);
		  postfix_expression = error_mark_node;
		}
	      else
		name = build_qualified_name (/*type=*/NULL_TREE,
					     parser->scope,
					     name,
					     template_p);
	      parser->scope = NULL_TREE;
	      parser->qualifying_scope = NULL_TREE;
	      parser->object_scope = NULL_TREE;
	    }
	  if (parser->scope && name && BASELINK_P (name))
	    adjust_result_of_qualified_name_lookup
	      (name, parser->scope, scope);
	  postfix_expression
	    = finish_class_member_access_expr (postfix_expression, name,
					       template_p,
					       tf_warning_or_error);
	  /* Build a location e.g.:
	       ptr->access_expr
	       ~~~^~~~~~~~~~~~~
	     where the caret is at the deref token, ranging from
	     the start of postfix_expression to the end of the access expr.  */
	  location_t combined_loc
	    = make_location (input_location, start_loc, parser->lexer);
	  protected_set_expr_location (postfix_expression, combined_loc);
	}
    }

  /* We no longer need to look up names in the scope of the object on
     the left-hand side of the `.' or `->' operator.  */
  parser->context->object_type = NULL_TREE;

  /* Outside of offsetof, these operators may not appear in
     constant-expressions.  */
  if (!for_offsetof
      && (cp_parser_non_integral_constant_expression
	  (parser, token_type == CPP_DEREF ? NIC_ARROW : NIC_POINT)))
    postfix_expression = error_mark_node;

  return postfix_expression;
}

/* Parse a parenthesized expression-list.

   expression-list:
     assignment-expression
     expression-list, assignment-expression

   attribute-list:
     expression-list
     identifier
     identifier, expression-list

   CAST_P is true if this expression is the target of a cast.

   ALLOW_EXPANSION_P is true if this expression allows expansion of an
   argument pack.

   WRAP_LOCATIONS_P is true if expressions within this list for which
   CAN_HAVE_LOCATION_P is false should be wrapped with nodes expressing
   their source locations.

   Returns a vector of trees.  Each element is a representation of an
   assignment-expression.  NULL is returned if the ( and or ) are
   missing.  An empty, but allocated, vector is returned on no
   expressions.  The parentheses are eaten.  IS_ATTRIBUTE_LIST is id_attr
   if we are parsing an attribute list for an attribute that wants a
   plain identifier argument, normal_attr for an attribute that wants
   an expression, or non_attr if we aren't parsing an attribute list.  If
   NON_CONSTANT_P is non-NULL, *NON_CONSTANT_P indicates whether or
   not all of the expressions in the list were constant.
   If CLOSE_PAREN_LOC is non-NULL, and no errors occur, then *CLOSE_PAREN_LOC
   will be written to with the location of the closing parenthesis.  If
   an error occurs, it may or may not be written to.  */

static vec<tree, va_gc> *
cp_parser_parenthesized_expression_list (cp_parser* parser,
					 int is_attribute_list,
					 bool cast_p,
                                         bool allow_expansion_p,
					 bool *non_constant_p,
					 location_t *close_paren_loc,
					 bool wrap_locations_p)
{
  vec<tree, va_gc> *expression_list;
  bool saved_greater_than_is_operator_p;

  /* Assume all the expressions will be constant.  */
  if (non_constant_p)
    *non_constant_p = false;

  matching_parens parens;
  if (!parens.require_open (parser))
    return NULL;

  expression_list = make_tree_vector ();

  /* Within a parenthesized expression, a `>' token is always
     the greater-than operator.  */
  saved_greater_than_is_operator_p
    = parser->greater_than_is_operator_p;
  parser->greater_than_is_operator_p = true;

  cp_expr expr (NULL_TREE);

  /* Consume expressions until there are no more.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
    while (true)
      {
	/* At the beginning of attribute lists, check to see if the
	   next token is an identifier.  */
	if (is_attribute_list == id_attr
	    && cp_lexer_peek_token (parser->lexer)->type == CPP_NAME)
	  expr = cp_lexer_consume_token (parser->lexer)->u.value;
	else if (is_attribute_list == assume_attr)
	  expr = cp_parser_conditional_expression (parser);
	else
	  expr
	    = cp_parser_parenthesized_expression_list_elt (parser, cast_p,
							   allow_expansion_p,
							   non_constant_p);

	if (wrap_locations_p)
	  expr.maybe_add_location_wrapper ();

	/* Add it to the list.  We add error_mark_node
	   expressions to the list, so that we can still tell if
	   the correct form for a parenthesized expression-list
	   is found. That gives better errors.  */
	vec_safe_push (expression_list, expr.get_value ());

	if (expr == error_mark_node)
	  goto skip_comma;

	/* After the first item, attribute lists look the same as
	   expression lists.  */
	is_attribute_list = non_attr;

      get_comma:;
	/* If the next token isn't a `,', then we are done.  */
	if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	  break;

	/* Otherwise, consume the `,' and keep going.  */
	cp_lexer_consume_token (parser->lexer);
      }

  if (close_paren_loc)
    *close_paren_loc = cp_lexer_peek_token (parser->lexer)->location;

  if (!parens.require_close (parser))
    {
      int ending;

    skip_comma:;
      /* We try and resync to an unnested comma, as that will give the
	 user better diagnostics.  */
      ending = cp_parser_skip_to_closing_parenthesis (parser,
						      /*recovering=*/true,
						      /*or_comma=*/true,
						      /*consume_paren=*/true);
      if (ending < 0)
	goto get_comma;
      if (!ending)
	{
	  parser->greater_than_is_operator_p
	    = saved_greater_than_is_operator_p;
	  return NULL;
	}
    }

  parser->greater_than_is_operator_p
    = saved_greater_than_is_operator_p;

  return expression_list;
}

/* Parse a pseudo-destructor-name.

   pseudo-destructor-name:
     :: [opt] nested-name-specifier [opt] type-name :: ~ type-name
     :: [opt] nested-name-specifier template template-id :: ~ type-name
     :: [opt] nested-name-specifier [opt] ~ type-name

   If either of the first two productions is used, sets *SCOPE to the
   TYPE specified before the final `::'.  Otherwise, *SCOPE is set to
   NULL_TREE.  *TYPE is set to the TYPE_DECL for the final type-name,
   or ERROR_MARK_NODE if the parse fails.  */

static void
cp_parser_pseudo_destructor_name (cp_parser* parser,
				  tree object,
				  tree* scope,
				  tree* type)
{
  bool nested_name_specifier_p;

  /* Handle ~auto.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_COMPL)
      && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_AUTO)
      && !type_dependent_expression_p (object))
    {
      if (cxx_dialect < cxx14)
	pedwarn (input_location, OPT_Wc__14_extensions,
		 "%<~auto%> only available with "
		 "%<-std=c++14%> or %<-std=gnu++14%>");
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
      *scope = NULL_TREE;
      *type = TREE_TYPE (object);
      return;
    }

  /* Assume that things will not work out.  */
  *type = error_mark_node;

  /* Look for the optional `::' operator.  */
  cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/true);
  /* Look for the optional nested-name-specifier.  */
  nested_name_specifier_p
    = (cp_parser_nested_name_specifier_opt (parser,
					    /*typename_keyword_p=*/false,
					    /*check_dependency_p=*/true,
					    /*type_p=*/false,
					    /*is_declaration=*/false)
       != NULL_TREE);
  /* Now, if we saw a nested-name-specifier, we might be doing the
     second production.  */
  if (nested_name_specifier_p
      && cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
    {
      /* Consume the `template' keyword.  */
      cp_lexer_consume_token (parser->lexer);
      /* Parse the template-id.  */
      cp_parser_template_id (parser,
			     /*template_keyword_p=*/true,
			     /*check_dependency_p=*/false,
			     class_type,
			     /*is_declaration=*/true);
      /* Look for the `::' token.  */
      cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
    }
  /* If the next token is not a `~', then there might be some
     additional qualification.  */
  else if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMPL))
    {
      /* At this point, we're looking for "type-name :: ~".  The type-name
	 must not be a class-name, since this is a pseudo-destructor.  So,
	 it must be either an enum-name, or a typedef-name -- both of which
	 are just identifiers.  So, we peek ahead to check that the "::"
	 and "~" tokens are present; if they are not, then we can avoid
	 calling type_name.  */
      if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME
	  || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE
	  || cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_COMPL)
	{
	  cp_parser_error (parser, "non-scalar type");
	  return;
	}

      /* Look for the type-name.  */
      *scope = TREE_TYPE (cp_parser_nonclass_name (parser));
      if (*scope == error_mark_node)
	return;

      /* Look for the `::' token.  */
      cp_parser_require (parser, CPP_SCOPE, RT_SCOPE);
    }
  else
    *scope = NULL_TREE;

  /* Look for the `~'.  */
  cp_parser_require (parser, CPP_COMPL, RT_COMPL);

  /* Once we see the ~, this has to be a pseudo-destructor.  */
  if (!processing_template_decl && !cp_parser_error_occurred (parser))
    cp_parser_commit_to_topmost_tentative_parse (parser);

  /* Look for the type-name again.  We are not responsible for
     checking that it matches the first type-name.  */
  *type = TREE_TYPE (cp_parser_nonclass_name (parser));
}

/* Parse a unary-expression.

   unary-expression:
     postfix-expression
     ++ cast-expression
     -- cast-expression
     await-expression
     unary-operator cast-expression
     sizeof unary-expression
     sizeof ( type-id )
     alignof ( type-id )  [C++0x]
     new-expression
     delete-expression

   GNU Extensions:

   unary-expression:
     __extension__ cast-expression
     __alignof__ unary-expression
     __alignof__ ( type-id )
     alignof unary-expression  [C++0x]
     __real__ cast-expression
     __imag__ cast-expression
     && identifier
     sizeof ( type-id ) { initializer-list , [opt] }
     alignof ( type-id ) { initializer-list , [opt] } [C++0x]
     __alignof__ ( type-id ) { initializer-list , [opt] }

   ADDRESS_P is true iff the unary-expression is appearing as the
   operand of the `&' operator.   CAST_P is true if this expression is
   the target of a cast.

   Returns a representation of the expression.  */

static cp_expr
cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk,
			    bool address_p, bool cast_p, bool decltype_p)
{
  cp_token *token;
  enum tree_code unary_operator;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* Some keywords give away the kind of expression.  */
  if (token->type == CPP_KEYWORD)
    {
      enum rid keyword = token->keyword;

      switch (keyword)
	{
	case RID_ALIGNOF:
	case RID_SIZEOF:
	  {
	    tree operand, ret;
	    enum tree_code op;
	    location_t start_loc = token->location;

	    op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
	    bool std_alignof = id_equal (token->u.value, "alignof");

	    /* Consume the token.  */
	    cp_lexer_consume_token (parser->lexer);
	    /* Parse the operand.  */
	    operand = cp_parser_sizeof_operand (parser, keyword);

	    /* Construct a location e.g. :
              alignof (expr)
              ^~~~~~~~~~~~~~
              with start == caret at the start of the "alignof"/"sizeof"
              token, with the endpoint at the final closing paren.  */
	    location_t compound_loc
	      = make_location (start_loc, start_loc, parser->lexer);

	    if (TYPE_P (operand))
	      ret = cxx_sizeof_or_alignof_type (compound_loc, operand, op,
						std_alignof, true);
	    else
	      {
		/* ISO C++ defines alignof only with types, not with
		   expressions. So pedwarn if alignof is used with a non-
		   type expression. However, __alignof__ is ok.  */
		if (std_alignof)
		  pedwarn (token->location, OPT_Wpedantic,
			   "ISO C++ does not allow %<alignof%> "
			   "with a non-type");

		ret = cxx_sizeof_or_alignof_expr (compound_loc, operand, op,
						  std_alignof, true);
	      }
	    /* For SIZEOF_EXPR, just issue diagnostics, but keep
	       SIZEOF_EXPR with the original operand.  */
	    if (op == SIZEOF_EXPR && ret != error_mark_node)
	      {
		if (TREE_CODE (ret) != SIZEOF_EXPR || TYPE_P (operand))
		  {
		    if (!processing_template_decl && TYPE_P (operand))
		      {
			ret = build_min (SIZEOF_EXPR, size_type_node,
					 build1 (NOP_EXPR, operand,
						 error_mark_node));
			SIZEOF_EXPR_TYPE_P (ret) = 1;
		      }
		    else
		      ret = build_min (SIZEOF_EXPR, size_type_node, operand);
		    TREE_SIDE_EFFECTS (ret) = 0;
		    TREE_READONLY (ret) = 1;
		    SET_EXPR_LOCATION (ret, compound_loc);
		  }
	      }

	    cp_expr ret_expr (ret, compound_loc);
	    ret_expr = ret_expr.maybe_add_location_wrapper ();
	    return ret_expr;
	  }

	case RID_BUILTIN_HAS_ATTRIBUTE:
	  return cp_parser_has_attribute_expression (parser);

	case RID_NEW:
	  return cp_parser_new_expression (parser);

	case RID_DELETE:
	  return cp_parser_delete_expression (parser);

	case RID_EXTENSION:
	  {
	    /* The saved value of the PEDANTIC flag.  */
	    int saved_pedantic;
	    tree expr;

	    /* Save away the PEDANTIC flag.  */
	    cp_parser_extension_opt (parser, &saved_pedantic);
	    /* Parse the cast-expression.  */
	    expr = cp_parser_simple_cast_expression (parser);
	    /* Restore the PEDANTIC flag.  */
	    pedantic = saved_pedantic;

	    return expr;
	  }

	case RID_REALPART:
	case RID_IMAGPART:
	  {
	    tree expression;

	    /* Consume the `__real__' or `__imag__' token.  */
	    cp_lexer_consume_token (parser->lexer);
	    /* Parse the cast-expression.  */
	    expression = cp_parser_simple_cast_expression (parser);
	    /* Create the complete representation.  */
	    return build_x_unary_op (token->location,
				     (keyword == RID_REALPART
				      ? REALPART_EXPR : IMAGPART_EXPR),
				     expression, NULL_TREE,
                                     tf_warning_or_error);
	  }
	  break;

	case RID_TRANSACTION_ATOMIC:
	case RID_TRANSACTION_RELAXED:
	  return cp_parser_transaction_expression (parser, keyword);

	case RID_NOEXCEPT:
	  {
	    tree expr;
	    const char *saved_message;
	    bool saved_integral_constant_expression_p;
	    bool saved_non_integral_constant_expression_p;
	    bool saved_greater_than_is_operator_p;

	    location_t start_loc = token->location;

	    cp_lexer_consume_token (parser->lexer);
	    matching_parens parens;
	    parens.require_open (parser);

	    saved_message = parser->type_definition_forbidden_message;
	    parser->type_definition_forbidden_message
	      = G_("types may not be defined in %<noexcept%> expressions");

	    saved_integral_constant_expression_p
	      = parser->integral_constant_expression_p;
	    saved_non_integral_constant_expression_p
	      = parser->non_integral_constant_expression_p;
	    parser->integral_constant_expression_p = false;

	    saved_greater_than_is_operator_p
	      = parser->greater_than_is_operator_p;
	    parser->greater_than_is_operator_p = true;

	    ++cp_unevaluated_operand;
	    ++c_inhibit_evaluation_warnings;
	    ++cp_noexcept_operand;
	    expr = cp_parser_expression (parser);
	    --cp_noexcept_operand;
	    --c_inhibit_evaluation_warnings;
	    --cp_unevaluated_operand;

	    parser->greater_than_is_operator_p
	      = saved_greater_than_is_operator_p;

	    parser->integral_constant_expression_p
	      = saved_integral_constant_expression_p;
	    parser->non_integral_constant_expression_p
	      = saved_non_integral_constant_expression_p;

	    parser->type_definition_forbidden_message = saved_message;

	    parens.require_close (parser);

	    /* Construct a location of the form:
	       noexcept (expr)
	       ^~~~~~~~~~~~~~~
	       with start == caret, finishing at the close-paren.  */
	    location_t noexcept_loc
	      = make_location (start_loc, start_loc, parser->lexer);

	    return cp_expr (finish_noexcept_expr (expr, tf_warning_or_error),
			    noexcept_loc);
	  }

	case RID_CO_AWAIT:
	  {
	    tree expr;
	    location_t kw_loc = token->location;

	    /* Consume the `co_await' token.  */
	    cp_lexer_consume_token (parser->lexer);
	    /* Parse its cast-expression.  */
	    expr = cp_parser_simple_cast_expression (parser);
	    if (expr == error_mark_node)
	      return error_mark_node;

	    /* Handle [expr.await].  */
	    return cp_expr (finish_co_await_expr (kw_loc, expr));
	  }

	default:
	  break;
	}
    }

  /* Look for the `:: new' and `:: delete', which also signal the
     beginning of a new-expression, or delete-expression,
     respectively.  If the next token is `::', then it might be one of
     these.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
    {
      enum rid keyword;

      /* See if the token after the `::' is one of the keywords in
	 which we're interested.  */
      keyword = cp_lexer_peek_nth_token (parser->lexer, 2)->keyword;
      /* If it's `new', we have a new-expression.  */
      if (keyword == RID_NEW)
	return cp_parser_new_expression (parser);
      /* Similarly, for `delete'.  */
      else if (keyword == RID_DELETE)
	return cp_parser_delete_expression (parser);
    }

  /* Look for a unary operator.  */
  unary_operator = cp_parser_unary_operator (token);
  /* The `++' and `--' operators can be handled similarly, even though
     they are not technically unary-operators in the grammar.  */
  if (unary_operator == ERROR_MARK)
    {
      if (token->type == CPP_PLUS_PLUS)
	unary_operator = PREINCREMENT_EXPR;
      else if (token->type == CPP_MINUS_MINUS)
	unary_operator = PREDECREMENT_EXPR;
      /* Handle the GNU address-of-label extension.  */
      else if (cp_parser_allow_gnu_extensions_p (parser)
	       && token->type == CPP_AND_AND)
	{
	  tree identifier;
	  tree expression;
	  location_t start_loc = token->location;

	  /* Consume the '&&' token.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Look for the identifier.  */
	  identifier = cp_parser_identifier (parser);
	  /* Construct a location of the form:
	       &&label
	       ^~~~~~~
	     with caret==start at the "&&", finish at the end of the label.  */
	  location_t combined_loc
	    = make_location (start_loc, start_loc, parser->lexer);
	  /* Create an expression representing the address.  */
	  expression = finish_label_address_expr (identifier, combined_loc);
	  if (cp_parser_non_integral_constant_expression (parser,
							  NIC_ADDR_LABEL))
	    expression = error_mark_node;
	  return expression;
	}
    }
  if (unary_operator != ERROR_MARK)
    {
      cp_expr cast_expression;
      cp_expr expression = error_mark_node;
      non_integral_constant non_constant_p = NIC_NONE;
      location_t loc = token->location;
      tsubst_flags_t complain = complain_flags (decltype_p);

      /* Consume the operator token.  */
      token = cp_lexer_consume_token (parser->lexer);
      enum cpp_ttype op_ttype = cp_lexer_peek_token (parser->lexer)->type;

      /* Parse the cast-expression.  */
      cast_expression
	= cp_parser_cast_expression (parser,
				     unary_operator == ADDR_EXPR,
				     /*cast_p=*/false,
				     /*decltype*/false,
				     pidk);

      /* Make a location:
	    OP_TOKEN  CAST_EXPRESSION
	    ^~~~~~~~~~~~~~~~~~~~~~~~~
	 with start==caret at the operator token, and
	 extending to the end of the cast_expression.  */
      loc = make_location (loc, loc, cast_expression.get_finish ());

      /* Now, build an appropriate representation.  */
      switch (unary_operator)
	{
	case INDIRECT_REF:
	  non_constant_p = NIC_STAR;
	  expression = build_x_indirect_ref (loc, cast_expression,
					     RO_UNARY_STAR, NULL_TREE,
                                             complain);
          /* TODO: build_x_indirect_ref does not always honor the
             location, so ensure it is set.  */
          expression.set_location (loc);
	  break;

	case ADDR_EXPR:
	   non_constant_p = NIC_ADDR;
	  /* Fall through.  */
	case BIT_NOT_EXPR:
	  expression = build_x_unary_op (loc, unary_operator,
					 cast_expression,
					 NULL_TREE, complain);
          /* TODO: build_x_unary_op does not always honor the location,
             so ensure it is set.  */
          expression.set_location (loc);
	  break;

	case PREINCREMENT_EXPR:
	case PREDECREMENT_EXPR:
	  non_constant_p = unary_operator == PREINCREMENT_EXPR
			   ? NIC_PREINCREMENT : NIC_PREDECREMENT;
	  /* Fall through.  */
	case NEGATE_EXPR:
	  /* Immediately fold negation of a constant, unless the constant is 0
	     (since -0 == 0) or it would overflow.  */
	  if (unary_operator == NEGATE_EXPR && op_ttype == CPP_NUMBER)
	    {
	      tree stripped_expr
		= tree_strip_any_location_wrapper (cast_expression);
	      if (CONSTANT_CLASS_P (stripped_expr)
		  && !integer_zerop (stripped_expr)
		  && !TREE_OVERFLOW (stripped_expr))
		{
		  tree folded = fold_build1 (unary_operator,
					     TREE_TYPE (stripped_expr),
					     stripped_expr);
		  if (CONSTANT_CLASS_P (folded) && !TREE_OVERFLOW (folded))
		    {
		      expression = maybe_wrap_with_location (folded, loc);
		      break;
		    }
		}
	    }
	  /* Fall through.  */
	case UNARY_PLUS_EXPR:
	case TRUTH_NOT_EXPR:
	  expression = finish_unary_op_expr (loc, unary_operator,
					     cast_expression, complain);
	  break;

	default:
	  gcc_unreachable ();
	}

      if (non_constant_p != NIC_NONE
	  && cp_parser_non_integral_constant_expression (parser,
							 non_constant_p))
	expression = error_mark_node;

      return expression;
    }

  return cp_parser_postfix_expression (parser, address_p, cast_p,
                                       /*member_access_only_p=*/false,
				       decltype_p,
				       pidk);
}

/* Returns ERROR_MARK if TOKEN is not a unary-operator.  If TOKEN is a
   unary-operator, the corresponding tree code is returned.  */

static enum tree_code
cp_parser_unary_operator (cp_token* token)
{
  switch (token->type)
    {
    case CPP_MULT:
      return INDIRECT_REF;

    case CPP_AND:
      return ADDR_EXPR;

    case CPP_PLUS:
      return UNARY_PLUS_EXPR;

    case CPP_MINUS:
      return NEGATE_EXPR;

    case CPP_NOT:
      return TRUTH_NOT_EXPR;

    case CPP_COMPL:
      return BIT_NOT_EXPR;

    default:
      return ERROR_MARK;
    }
}

/* Parse a __builtin_has_attribute([expr|type], attribute-spec) expression.
   Returns a representation of the expression.  */

static tree
cp_parser_has_attribute_expression (cp_parser *parser)
{
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Consume the __builtin_has_attribute token.  */
  cp_lexer_consume_token (parser->lexer);

  matching_parens parens;
  if (!parens.require_open (parser))
    return error_mark_node;

  /* Types cannot be defined in a `sizeof' expression.  Save away the
     old message.  */
  const char *saved_message = parser->type_definition_forbidden_message;
  const char *saved_message_arg
    = parser->type_definition_forbidden_message_arg;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in %qs expressions");
  parser->type_definition_forbidden_message_arg
    = IDENTIFIER_POINTER (ridpointers[RID_BUILTIN_HAS_ATTRIBUTE]);

  /* The restrictions on constant-expressions do not apply inside
     sizeof expressions.  */
  bool saved_integral_constant_expression_p
    = parser->integral_constant_expression_p;
  bool saved_non_integral_constant_expression_p
    = parser->non_integral_constant_expression_p;
  parser->integral_constant_expression_p = false;

  /* Do not actually evaluate the expression.  */
  ++cp_unevaluated_operand;
  ++c_inhibit_evaluation_warnings;

  tree oper = NULL_TREE;

  /* We can't be sure yet whether we're looking at a type-id or an
     expression.  */
  cp_parser_parse_tentatively (parser);

  bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
  parser->in_type_id_in_expr_p = true;
  /* Look for the type-id.  */
  oper = cp_parser_type_id (parser);
  parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;

  cp_parser_parse_definitely (parser);

  /* If the type-id production did not work out, then we must be
     looking at an expression.  */
  if (!oper || oper == error_mark_node)
    oper = cp_parser_assignment_expression (parser);

  STRIP_ANY_LOCATION_WRAPPER (oper);

  /* Go back to evaluating expressions.  */
  --cp_unevaluated_operand;
  --c_inhibit_evaluation_warnings;

  /* And restore the old one.  */
  parser->type_definition_forbidden_message = saved_message;
  parser->type_definition_forbidden_message_arg = saved_message_arg;
  parser->integral_constant_expression_p
    = saved_integral_constant_expression_p;
  parser->non_integral_constant_expression_p
    = saved_non_integral_constant_expression_p;

  /* Consume the comma if it's there.  */
  if (!cp_parser_require (parser, CPP_COMMA, RT_COMMA))
    {
      cp_parser_skip_to_closing_parenthesis (parser, false, false,
					     /*consume_paren=*/true);
      return error_mark_node;
    }

  /* Parse the attribute specification.  */
  bool ret = false;
  location_t atloc = cp_lexer_peek_token (parser->lexer)->location;
  if (tree attr = cp_parser_gnu_attribute_list (parser, /*exactly_one=*/true))
    {
      if (oper == error_mark_node)
	/* Nothing.  */;
      else if (processing_template_decl && uses_template_parms (oper))
	sorry_at (atloc, "%<__builtin_has_attribute%> with dependent argument "
		  "not supported yet");
      else
	{
	  /* Fold constant expressions used in attributes first.  */
	  cp_check_const_attributes (attr);

	  /* Finally, see if OPER has been declared with ATTR.  */
	  ret = has_attribute (atloc, oper, attr, default_conversion);
	}

      parens.require_close (parser);
    }
  else
    {
      error_at (atloc, "expected identifier");
      cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
    }

  /* Construct a location e.g. :
     __builtin_has_attribute (oper, attr)
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     with start == caret at the start of the built-in token,
     and with the endpoint at the final closing paren.  */
  location_t compound_loc
    = make_location (start_loc, start_loc, parser->lexer);

  cp_expr ret_expr (ret ? boolean_true_node : boolean_false_node);
  ret_expr.set_location (compound_loc);
  ret_expr = ret_expr.maybe_add_location_wrapper ();
  return ret_expr;
}

/* Parse a new-expression.

   new-expression:
     :: [opt] new new-placement [opt] new-type-id new-initializer [opt]
     :: [opt] new new-placement [opt] ( type-id ) new-initializer [opt]

   Returns a representation of the expression.  */

static tree
cp_parser_new_expression (cp_parser* parser)
{
  bool global_scope_p;
  vec<tree, va_gc> *placement;
  tree type;
  vec<tree, va_gc> *initializer;
  tree nelts = NULL_TREE;
  tree ret;

  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Look for the optional `::' operator.  */
  global_scope_p
    = (cp_parser_global_scope_opt (parser,
				   /*current_scope_valid_p=*/false)
       != NULL_TREE);
  /* Look for the `new' operator.  */
  cp_parser_require_keyword (parser, RID_NEW, RT_NEW);
  /* There's no easy way to tell a new-placement from the
     `( type-id )' construct.  */
  cp_parser_parse_tentatively (parser);
  /* Look for a new-placement.  */
  placement = cp_parser_new_placement (parser);
  /* If that didn't work out, there's no new-placement.  */
  if (!cp_parser_parse_definitely (parser))
    {
      if (placement != NULL)
	release_tree_vector (placement);
      placement = NULL;
    }

  /* If the next token is a `(', then we have a parenthesized
     type-id.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      cp_token *token;
      const char *saved_message = parser->type_definition_forbidden_message;

      /* Consume the `('.  */
      matching_parens parens;
      parens.consume_open (parser);

      /* Parse the type-id.  */
      parser->type_definition_forbidden_message
	= G_("types may not be defined in a new-expression");
      {
	type_id_in_expr_sentinel s (parser);
	type = cp_parser_type_id (parser);
      }
      parser->type_definition_forbidden_message = saved_message;

      /* Look for the closing `)'.  */
      parens.require_close (parser);
      token = cp_lexer_peek_token (parser->lexer);
      /* There should not be a direct-new-declarator in this production,
	 but GCC used to allowed this, so we check and emit a sensible error
	 message for this case.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
	{
	  error_at (token->location,
		    "array bound forbidden after parenthesized type-id");
	  inform (token->location,
		  "try removing the parentheses around the type-id");
	  cp_parser_direct_new_declarator (parser);
	}
    }
  /* Otherwise, there must be a new-type-id.  */
  else
    type = cp_parser_new_type_id (parser, &nelts);

  /* If the next token is a `(' or '{', then we have a new-initializer.  */
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_OPEN_PAREN
      || token->type == CPP_OPEN_BRACE)
    initializer = cp_parser_new_initializer (parser);
  else
    initializer = NULL;

  /* A new-expression may not appear in an integral constant
     expression.  */
  if (cp_parser_non_integral_constant_expression (parser, NIC_NEW))
    ret = error_mark_node;
  /* 5.3.4/2: "If the auto type-specifier appears in the type-specifier-seq
     of a new-type-id or type-id of a new-expression, the new-expression shall
     contain a new-initializer of the form ( assignment-expression )".
     Additionally, consistently with the spirit of DR 1467, we want to accept
     'new auto { 2 }' too.  */
  else if ((ret = type_uses_auto (type))
	   && !CLASS_PLACEHOLDER_TEMPLATE (ret)
	   && (vec_safe_length (initializer) != 1
	       || (BRACE_ENCLOSED_INITIALIZER_P ((*initializer)[0])
		   && CONSTRUCTOR_NELTS ((*initializer)[0]) != 1)))
    {
      error_at (token->location,
		"initialization of new-expression for type %<auto%> "
		"requires exactly one element");
      ret = error_mark_node;
    }
  else
    {
      /* Construct a location e.g.:
           ptr = new int[100]
                 ^~~~~~~~~~~~
         with caret == start at the start of the "new" token, and the end
         at the end of the final token we consumed.  */
      location_t combined_loc = make_location (start_loc, start_loc,
					       parser->lexer);
      /* Create a representation of the new-expression.  */
      ret = build_new (combined_loc, &placement, type, nelts, &initializer,
		       global_scope_p, tf_warning_or_error);
    }

  if (placement != NULL)
    release_tree_vector (placement);
  if (initializer != NULL)
    release_tree_vector (initializer);

  return ret;
}

/* Parse a new-placement.

   new-placement:
     ( expression-list )

   Returns the same representation as for an expression-list.  */

static vec<tree, va_gc> *
cp_parser_new_placement (cp_parser* parser)
{
  vec<tree, va_gc> *expression_list;

  /* Parse the expression-list.  */
  expression_list = (cp_parser_parenthesized_expression_list
		     (parser, non_attr, /*cast_p=*/false,
		      /*allow_expansion_p=*/true,
		      /*non_constant_p=*/NULL));

  if (expression_list && expression_list->is_empty ())
    error ("expected expression-list or type-id");

  return expression_list;
}

/* Parse a new-type-id.

   new-type-id:
     type-specifier-seq new-declarator [opt]

   Returns the TYPE allocated.  If the new-type-id indicates an array
   type, *NELTS is set to the number of elements in the last array
   bound; the TYPE will not include the last array bound.  */

static tree
cp_parser_new_type_id (cp_parser* parser, tree *nelts)
{
  cp_decl_specifier_seq type_specifier_seq;
  cp_declarator *new_declarator;
  cp_declarator *declarator;
  cp_declarator *outer_declarator;
  const char *saved_message;

  /* The type-specifier sequence must not contain type definitions.
     (It cannot contain declarations of new types either, but if they
     are not definitions we will catch that because they are not
     complete.)  */
  saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in a new-type-id");
  /* Parse the type-specifier-seq.  */
  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
				/*is_declaration=*/false,
				/*is_trailing_return=*/false,
				&type_specifier_seq);
  /* Restore the old message.  */
  parser->type_definition_forbidden_message = saved_message;

  if (type_specifier_seq.type == error_mark_node)
    return error_mark_node;

  /* Parse the new-declarator.  */
  new_declarator = cp_parser_new_declarator_opt (parser);

  /* Determine the number of elements in the last array dimension, if
     any.  */
  *nelts = NULL_TREE;
  /* Skip down to the last array dimension.  */
  declarator = new_declarator;
  outer_declarator = NULL;
  while (declarator && (declarator->kind == cdk_pointer
			|| declarator->kind == cdk_ptrmem))
    {
      outer_declarator = declarator;
      declarator = declarator->declarator;
    }
  while (declarator
	 && declarator->kind == cdk_array
	 && declarator->declarator
	 && declarator->declarator->kind == cdk_array)
    {
      outer_declarator = declarator;
      declarator = declarator->declarator;
    }

  if (declarator && declarator->kind == cdk_array)
    {
      *nelts = declarator->u.array.bounds;
      if (*nelts == error_mark_node)
	*nelts = integer_one_node;

      if (*nelts == NULL_TREE)
	/* Leave [] in the declarator.  */;
      else if (outer_declarator)
	outer_declarator->declarator = declarator->declarator;
      else
	new_declarator = NULL;
    }

  return groktypename (&type_specifier_seq, new_declarator, false);
}

/* Parse an (optional) new-declarator.

   new-declarator:
     ptr-operator new-declarator [opt]
     direct-new-declarator

   Returns the declarator.  */

static cp_declarator *
cp_parser_new_declarator_opt (cp_parser* parser)
{
  enum tree_code code;
  tree type, std_attributes = NULL_TREE;
  cp_cv_quals cv_quals;

  /* We don't know if there's a ptr-operator next, or not.  */
  cp_parser_parse_tentatively (parser);
  /* Look for a ptr-operator.  */
  code = cp_parser_ptr_operator (parser, &type, &cv_quals, &std_attributes);
  /* If that worked, look for more new-declarators.  */
  if (cp_parser_parse_definitely (parser))
    {
      cp_declarator *declarator;

      /* Parse another optional declarator.  */
      declarator = cp_parser_new_declarator_opt (parser);

      declarator = cp_parser_make_indirect_declarator
	(code, type, cv_quals, declarator, std_attributes);

      return declarator;
    }

  /* If the next token is a `[', there is a direct-new-declarator.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
    return cp_parser_direct_new_declarator (parser);

  return NULL;
}

/* Parse a direct-new-declarator.

   direct-new-declarator:
     [ expression ]
     direct-new-declarator [constant-expression]

   */

static cp_declarator *
cp_parser_direct_new_declarator (cp_parser* parser)
{
  cp_declarator *declarator = NULL;
  bool first_p = true;

  while (true)
    {
      tree expression;
      cp_token *token;

      /* Look for the opening `['.  */
      cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);

      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_CLOSE_SQUARE && first_p)
	expression = NULL_TREE;
      else
	expression = cp_parser_expression (parser);
      /* The standard requires that the expression have integral
	 type.  DR 74 adds enumeration types.  We believe that the
	 real intent is that these expressions be handled like the
	 expression in a `switch' condition, which also allows
	 classes with a single conversion to integral or
	 enumeration type.  */
      if (expression && !processing_template_decl)
	{
	  expression
	    = build_expr_type_conversion (WANT_INT | WANT_ENUM,
					  expression,
					  /*complain=*/true);
	  if (!expression)
	    {
	      error_at (token->location,
			"expression in new-declarator must have integral "
			"or enumeration type");
	      expression = error_mark_node;
	    }
	}

      /* Look for the closing `]'.  */
      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);

      /* Add this bound to the declarator.  */
      declarator = make_array_declarator (declarator, expression);

      /* If the next token is not a `[', then there are no more
	 bounds.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
	break;
      first_p = false;
    }

  return declarator;
}

/* Parse a new-initializer.

   new-initializer:
     ( expression-list [opt] )
     braced-init-list

   Returns a representation of the expression-list.  */

static vec<tree, va_gc> *
cp_parser_new_initializer (cp_parser* parser)
{
  vec<tree, va_gc> *expression_list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      tree t;
      bool expr_non_constant_p;
      cp_lexer_set_source_position (parser->lexer);
      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
      t = cp_parser_braced_list (parser, &expr_non_constant_p);
      CONSTRUCTOR_IS_DIRECT_INIT (t) = 1;
      expression_list = make_tree_vector_single (t);
    }
  else
    expression_list = (cp_parser_parenthesized_expression_list
		       (parser, non_attr, /*cast_p=*/false,
			/*allow_expansion_p=*/true,
			/*non_constant_p=*/NULL));

  return expression_list;
}

/* Parse a delete-expression.

   delete-expression:
     :: [opt] delete cast-expression
     :: [opt] delete [ ] cast-expression

   Returns a representation of the expression.  */

static tree
cp_parser_delete_expression (cp_parser* parser)
{
  bool global_scope_p;
  bool array_p;
  tree expression;
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Look for the optional `::' operator.  */
  global_scope_p
    = (cp_parser_global_scope_opt (parser,
				   /*current_scope_valid_p=*/false)
       != NULL_TREE);
  /* Look for the `delete' keyword.  */
  cp_parser_require_keyword (parser, RID_DELETE, RT_DELETE);
  /* See if the array syntax is in use.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
    {
      /* Consume the `[' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Look for the `]' token.  */
      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
      /* Remember that this is the `[]' construct.  */
      array_p = true;
    }
  else
    array_p = false;

  /* Parse the cast-expression.  */
  expression = cp_parser_simple_cast_expression (parser);

  /* A delete-expression may not appear in an integral constant
     expression.  */
  if (cp_parser_non_integral_constant_expression (parser, NIC_DEL))
    return error_mark_node;

  /* Construct a location e.g.:
       delete [ ] ptr
       ^~~~~~~~~~~~~~
     with caret == start at the start of the "delete" token, and
     the end at the end of the final token we consumed.  */
  location_t combined_loc = make_location (start_loc, start_loc,
					   parser->lexer);
  expression = delete_sanity (combined_loc, expression, NULL_TREE, array_p,
			      global_scope_p, tf_warning_or_error);

  return expression;
}

/* Returns 1 if TOKEN may start a cast-expression and isn't '++', '--',
   neither '[' in C++11; -1 if TOKEN is '++', '--', or '[' in C++11;
   0 otherwise.  */

static int
cp_parser_tokens_start_cast_expression (cp_parser *parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  switch (token->type)
    {
    case CPP_COMMA:
    case CPP_SEMICOLON:
    case CPP_QUERY:
    case CPP_COLON:
    case CPP_CLOSE_SQUARE:
    case CPP_CLOSE_PAREN:
    case CPP_CLOSE_BRACE:
    case CPP_OPEN_BRACE:
    case CPP_DOT:
    case CPP_DOT_STAR:
    case CPP_DEREF:
    case CPP_DEREF_STAR:
    case CPP_DIV:
    case CPP_MOD:
    case CPP_LSHIFT:
    case CPP_RSHIFT:
    case CPP_LESS:
    case CPP_GREATER:
    case CPP_LESS_EQ:
    case CPP_GREATER_EQ:
    case CPP_EQ_EQ:
    case CPP_NOT_EQ:
    case CPP_EQ:
    case CPP_MULT_EQ:
    case CPP_DIV_EQ:
    case CPP_MOD_EQ:
    case CPP_PLUS_EQ:
    case CPP_MINUS_EQ:
    case CPP_RSHIFT_EQ:
    case CPP_LSHIFT_EQ:
    case CPP_AND_EQ:
    case CPP_XOR_EQ:
    case CPP_OR_EQ:
    case CPP_XOR:
    case CPP_OR:
    case CPP_OR_OR:
    case CPP_EOF:
    case CPP_ELLIPSIS:
      return 0;

    case CPP_OPEN_PAREN:
      /* In ((type ()) () the last () isn't a valid cast-expression,
	 so the whole must be parsed as postfix-expression.  */
      return cp_lexer_peek_nth_token (parser->lexer, 2)->type
	     != CPP_CLOSE_PAREN;

    case CPP_OPEN_SQUARE:
      /* '[' may start a primary-expression in obj-c++ and in C++11,
	 as a lambda-expression, eg, '(void)[]{}'.  */
      if (cxx_dialect >= cxx11)
	return -1;
      return c_dialect_objc ();

    case CPP_PLUS_PLUS:
    case CPP_MINUS_MINUS:
      /* '++' and '--' may or may not start a cast-expression:

	 struct T { void operator++(int); };
	 void f() { (T())++; }

	 vs

	 int a;
	 (int)++a;  */
      return -1;

    default:
      return 1;
    }
}

/* Try to find a legal C++-style cast to DST_TYPE for ORIG_EXPR, trying them
   in the order: const_cast, static_cast, reinterpret_cast.

   Don't suggest dynamic_cast.

   Return the first legal cast kind found, or NULL otherwise.  */

static const char *
get_cast_suggestion (tree dst_type, tree orig_expr)
{
  tree trial;

  /* Reuse the parser logic by attempting to build the various kinds of
     cast, with "complain" disabled.
     Identify the first such cast that is valid.  */

  /* Don't attempt to run such logic within template processing.  */
  if (processing_template_decl)
    return NULL;

  /* First try const_cast.  */
  trial = build_const_cast (input_location, dst_type, orig_expr, tf_none);
  if (trial != error_mark_node)
    return "const_cast";

  /* If that fails, try static_cast.  */
  trial = build_static_cast (input_location, dst_type, orig_expr, tf_none);
  if (trial != error_mark_node)
    return "static_cast";

  /* Finally, try reinterpret_cast.  */
  trial = build_reinterpret_cast (input_location, dst_type, orig_expr,
				  tf_none);
  if (trial != error_mark_node)
    return "reinterpret_cast";

  /* No such cast possible.  */
  return NULL;
}

/* If -Wold-style-cast is enabled, add fix-its to RICHLOC,
   suggesting how to convert a C-style cast of the form:

     (DST_TYPE)ORIG_EXPR

   to a C++-style cast.

   The primary range of RICHLOC is asssumed to be that of the original
   expression.  OPEN_PAREN_LOC and CLOSE_PAREN_LOC give the locations
   of the parens in the C-style cast.  */

static void
maybe_add_cast_fixit (rich_location *rich_loc, location_t open_paren_loc,
		      location_t close_paren_loc, tree orig_expr,
		      tree dst_type)
{
  /* This function is non-trivial, so bail out now if the warning isn't
     going to be emitted.  */
  if (!warn_old_style_cast)
    return;

  /* Try to find a legal C++ cast, trying them in order:
     const_cast, static_cast, reinterpret_cast.  */
  const char *cast_suggestion = get_cast_suggestion (dst_type, orig_expr);
  if (!cast_suggestion)
    return;

  /* Replace the open paren with "CAST_SUGGESTION<".  */
  pretty_printer pp;
  pp_string (&pp, cast_suggestion);
  pp_less (&pp);
  rich_loc->add_fixit_replace (open_paren_loc, pp_formatted_text (&pp));

  /* Replace the close paren with "> (".  */
  rich_loc->add_fixit_replace (close_paren_loc, "> (");

  /* Add a closing paren after the expr (the primary range of RICH_LOC).  */
  rich_loc->add_fixit_insert_after (")");
}


/* Parse a cast-expression.

   cast-expression:
     unary-expression
     ( type-id ) cast-expression

   ADDRESS_P is true iff the unary-expression is appearing as the
   operand of the `&' operator.   CAST_P is true if this expression is
   the target of a cast.

   Returns a representation of the expression.  */

static cp_expr
cp_parser_cast_expression (cp_parser *parser, bool address_p, bool cast_p,
			   bool decltype_p, cp_id_kind * pidk)
{
  /* If it's a `(', then we might be looking at a cast.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      tree type = NULL_TREE;
      cp_expr expr (NULL_TREE);
      int cast_expression = 0;
      const char *saved_message;

      /* There's no way to know yet whether or not this is a cast.
	 For example, `(int (3))' is a unary-expression, while `(int)
	 3' is a cast.  So, we resort to parsing tentatively.  */
      cp_parser_parse_tentatively (parser);
      /* Types may not be defined in a cast.  */
      saved_message = parser->type_definition_forbidden_message;
      parser->type_definition_forbidden_message
	= G_("types may not be defined in casts");
      /* Consume the `('.  */
      matching_parens parens;
      cp_token *open_paren = parens.consume_open (parser);
      location_t open_paren_loc = open_paren->location;
      location_t close_paren_loc = UNKNOWN_LOCATION;

      /* A very tricky bit is that `(struct S) { 3 }' is a
	 compound-literal (which we permit in C++ as an extension).
	 But, that construct is not a cast-expression -- it is a
	 postfix-expression.  (The reason is that `(struct S) { 3 }.i'
	 is legal; if the compound-literal were a cast-expression,
	 you'd need an extra set of parentheses.)  But, if we parse
	 the type-id, and it happens to be a class-specifier, then we
	 will commit to the parse at that point, because we cannot
	 undo the action that is done when creating a new class.  So,
	 then we cannot back up and do a postfix-expression.

	 Another tricky case is the following (c++/29234):

         struct S { void operator () (); };

         void foo ()
         {
           ( S()() );
         }

	 As a type-id we parse the parenthesized S()() as a function
	 returning a function, groktypename complains and we cannot
	 back up in this case either.

	 Therefore, we scan ahead to the closing `)', and check to see
	 if the tokens after the `)' can start a cast-expression.  Otherwise
	 we are dealing with an unary-expression, a postfix-expression
	 or something else.

	 Yet another tricky case, in C++11, is the following (c++/54891):

	 (void)[]{};

         The issue is that usually, besides the case of lambda-expressions,
	 the parenthesized type-id cannot be followed by '[', and, eg, we
	 want to parse '(C ())[2];' in parse/pr26997.C as unary-expression.
	 Thus, if cp_parser_tokens_start_cast_expression returns -1, below
	 we don't commit, we try a cast-expression, then an unary-expression.

	 Save tokens so that we can put them back.  */
      cp_lexer_save_tokens (parser->lexer);

      /* We may be looking at a cast-expression.  */
      if (cp_parser_skip_to_closing_parenthesis (parser, false, false,
						 /*consume_paren=*/true))
	cast_expression
	  = cp_parser_tokens_start_cast_expression (parser);

      /* Roll back the tokens we skipped.  */
      cp_lexer_rollback_tokens (parser->lexer);
      /* If we aren't looking at a cast-expression, simulate an error so
	 that the call to cp_parser_error_occurred below returns true.  */
      if (!cast_expression)
	cp_parser_simulate_error (parser);
      else
	{
	  bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
	  parser->in_type_id_in_expr_p = true;
	  /* Look for the type-id.  */
	  type = cp_parser_type_id (parser);
	  /* Look for the closing `)'.  */
	  cp_token *close_paren = parens.require_close (parser);
	  if (close_paren)
	    close_paren_loc = close_paren->location;
	  parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
	}

      /* Restore the saved message.  */
      parser->type_definition_forbidden_message = saved_message;

      /* At this point this can only be either a cast or a
	 parenthesized ctor such as `(T ())' that looks like a cast to
	 function returning T.  */
      if (!cp_parser_error_occurred (parser))
	{
	  /* Only commit if the cast-expression doesn't start with
	     '++', '--', or '[' in C++11.  */
	  if (cast_expression > 0)
	    cp_parser_commit_to_topmost_tentative_parse (parser);

	  expr = cp_parser_cast_expression (parser,
					    /*address_p=*/false,
					    /*cast_p=*/true,
					    /*decltype_p=*/false,
					    pidk);

	  if (cp_parser_parse_definitely (parser))
	    {
	      /* Warn about old-style casts, if so requested.  */
	      if (warn_old_style_cast
		  && !in_system_header_at (input_location)
		  && !VOID_TYPE_P (type)
		  && current_lang_name != lang_name_c)
		{
		  gcc_rich_location rich_loc (input_location);
		  maybe_add_cast_fixit (&rich_loc, open_paren_loc, close_paren_loc,
					expr, type);
		  warning_at (&rich_loc, OPT_Wold_style_cast,
			      "use of old-style cast to %q#T", type);
		}

	      /* Only type conversions to integral or enumeration types
		 can be used in constant-expressions.  */
	      if (!cast_valid_in_integral_constant_expression_p (type)
		  && cp_parser_non_integral_constant_expression (parser,
								 NIC_CAST))
		return error_mark_node;

	      /* Perform the cast.  */
	      /* Make a location:
		   (TYPE) EXPR
		   ^~~~~~~~~~~
		 with start==caret at the open paren, extending to the
		 end of "expr".  */
	      location_t cast_loc = make_location (open_paren_loc,
						   open_paren_loc,
						   expr.get_finish ());
	      expr = build_c_cast (cast_loc, type, expr);
	      return expr;
	    }
	}
      else
        cp_parser_abort_tentative_parse (parser);
    }

  /* If we get here, then it's not a cast, so it must be a
     unary-expression.  */
  return cp_parser_unary_expression (parser, pidk, address_p,
				     cast_p, decltype_p);
}

/* Parse a binary expression of the general form:

   pm-expression:
     cast-expression
     pm-expression .* cast-expression
     pm-expression ->* cast-expression

   multiplicative-expression:
     pm-expression
     multiplicative-expression * pm-expression
     multiplicative-expression / pm-expression
     multiplicative-expression % pm-expression

   additive-expression:
     multiplicative-expression
     additive-expression + multiplicative-expression
     additive-expression - multiplicative-expression

   shift-expression:
     additive-expression
     shift-expression << additive-expression
     shift-expression >> additive-expression

   relational-expression:
     shift-expression
     relational-expression < shift-expression
     relational-expression > shift-expression
     relational-expression <= shift-expression
     relational-expression >= shift-expression

  GNU Extension:

   relational-expression:
     relational-expression <? shift-expression
     relational-expression >? shift-expression

   equality-expression:
     relational-expression
     equality-expression == relational-expression
     equality-expression != relational-expression

   and-expression:
     equality-expression
     and-expression & equality-expression

   exclusive-or-expression:
     and-expression
     exclusive-or-expression ^ and-expression

   inclusive-or-expression:
     exclusive-or-expression
     inclusive-or-expression | exclusive-or-expression

   logical-and-expression:
     inclusive-or-expression
     logical-and-expression && inclusive-or-expression

   logical-or-expression:
     logical-and-expression
     logical-or-expression || logical-and-expression

   All these are implemented with a single function like:

   binary-expression:
     simple-cast-expression
     binary-expression <token> binary-expression

   CAST_P is true if this expression is the target of a cast.

   The binops_by_token map is used to get the tree codes for each <token> type.
   binary-expressions are associated according to a precedence table.  */

#define TOKEN_PRECEDENCE(token)				     \
(((token->type == CPP_GREATER				     \
   || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)) \
  && !parser->greater_than_is_operator_p)		     \
 ? PREC_NOT_OPERATOR					     \
 : binops_by_token[token->type].prec)

static cp_expr
cp_parser_binary_expression (cp_parser* parser, bool cast_p,
			     bool no_toplevel_fold_p,
			     bool decltype_p,
			     enum cp_parser_prec prec,
			     cp_id_kind * pidk)
{
  cp_parser_expression_stack stack;
  cp_parser_expression_stack_entry *sp = &stack[0];
  cp_parser_expression_stack_entry *disable_warnings_sp = NULL;
  cp_parser_expression_stack_entry current;
  cp_expr rhs;
  cp_token *token;
  enum tree_code rhs_type;
  enum cp_parser_prec new_prec, lookahead_prec;
  tree overload;

  /* Parse the first expression.  */
  current.lhs_type = (cp_lexer_next_token_is (parser->lexer, CPP_NOT)
		      ? TRUTH_NOT_EXPR : ERROR_MARK);
  current.lhs = cp_parser_cast_expression (parser, /*address_p=*/false,
					   cast_p, decltype_p, pidk);
  current.prec = prec;

  if (cp_parser_error_occurred (parser))
    return error_mark_node;

  for (;;)
    {
      /* Get an operator token.  */
      token = cp_lexer_peek_token (parser->lexer);

      if (warn_cxx11_compat
          && token->type == CPP_RSHIFT
          && !parser->greater_than_is_operator_p)
        {
          if (warning_at (token->location, OPT_Wc__11_compat,
			  "%<>>%> operator is treated"
			  " as two right angle brackets in C++11"))
	    inform (token->location,
		    "suggest parentheses around %<>>%> expression");
        }

      new_prec = TOKEN_PRECEDENCE (token);
      if (new_prec != PREC_NOT_OPERATOR
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
	/* This is a fold-expression; handle it later.  */
	new_prec = PREC_NOT_OPERATOR;

      /* Popping an entry off the stack means we completed a subexpression:
	 - either we found a token which is not an operator (`>' where it is not
	   an operator, or prec == PREC_NOT_OPERATOR), in which case popping
	   will happen repeatedly;
	 - or, we found an operator which has lower priority.  This is the case
	   where the recursive descent *ascends*, as in `3 * 4 + 5' after
	   parsing `3 * 4'.  */
      if (new_prec <= current.prec)
	{
	  if (sp == stack)
	    break;
	  else
	    goto pop;
	}

     get_rhs:
      current.tree_type = binops_by_token[token->type].tree_type;
      current.loc = token->location;
      current.flags = token->flags;

      /* We used the operator token.  */
      cp_lexer_consume_token (parser->lexer);

      /* For "false && x" or "true || x", x will never be executed;
	 disable warnings while evaluating it.  */
      if ((current.tree_type == TRUTH_ANDIF_EXPR
	   && cp_fully_fold (current.lhs) == truthvalue_false_node)
	  || (current.tree_type == TRUTH_ORIF_EXPR
	      && cp_fully_fold (current.lhs) == truthvalue_true_node))
	{
	  disable_warnings_sp = sp;
	  ++c_inhibit_evaluation_warnings;
	}

      /* Extract another operand.  It may be the RHS of this expression
	 or the LHS of a new, higher priority expression.  */
      rhs_type = (cp_lexer_next_token_is (parser->lexer, CPP_NOT)
		  ? TRUTH_NOT_EXPR : ERROR_MARK);
      rhs = cp_parser_simple_cast_expression (parser);

      /* Get another operator token.  Look up its precedence to avoid
	 building a useless (immediately popped) stack entry for common
	 cases such as 3 + 4 + 5 or 3 * 4 + 5.  */
      token = cp_lexer_peek_token (parser->lexer);
      lookahead_prec = TOKEN_PRECEDENCE (token);
      if (lookahead_prec != PREC_NOT_OPERATOR
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
	lookahead_prec = PREC_NOT_OPERATOR;
      if (lookahead_prec > new_prec)
	{
	  /* ... and prepare to parse the RHS of the new, higher priority
	     expression.  Since precedence levels on the stack are
	     monotonically increasing, we do not have to care about
	     stack overflows.  */
	  *sp = current;
	  ++sp;
	  current.lhs = rhs;
	  current.lhs_type = rhs_type;
	  current.prec = new_prec;
	  new_prec = lookahead_prec;
	  goto get_rhs;

	 pop:
	  lookahead_prec = new_prec;
	  /* If the stack is not empty, we have parsed into LHS the right side
	     (`4' in the example above) of an expression we had suspended.
	     We can use the information on the stack to recover the LHS (`3')
	     from the stack together with the tree code (`MULT_EXPR'), and
	     the precedence of the higher level subexpression
	     (`PREC_ADDITIVE_EXPRESSION').  TOKEN is the CPP_PLUS token,
	     which will be used to actually build the additive expression.  */
	  rhs = current.lhs;
	  rhs_type = current.lhs_type;
	  --sp;
	  current = *sp;
	}

      /* Undo the disabling of warnings done above.  */
      if (sp == disable_warnings_sp)
	{
	  disable_warnings_sp = NULL;
	  --c_inhibit_evaluation_warnings;
	}

      if (warn_logical_not_paren
	  && TREE_CODE_CLASS (current.tree_type) == tcc_comparison
	  && current.lhs_type == TRUTH_NOT_EXPR
	  /* Avoid warning for !!x == y.  */
	  && (TREE_CODE (current.lhs) != NE_EXPR
	      || !integer_zerop (TREE_OPERAND (current.lhs, 1)))
	  && (TREE_CODE (current.lhs) != TRUTH_NOT_EXPR
	      || (TREE_CODE (TREE_OPERAND (current.lhs, 0)) != TRUTH_NOT_EXPR
		  /* Avoid warning for !b == y where b is boolean.  */
		  && (TREE_TYPE (TREE_OPERAND (current.lhs, 0)) == NULL_TREE
		      || (TREE_CODE (TREE_TYPE (TREE_OPERAND (current.lhs, 0)))
			  != BOOLEAN_TYPE))))
	  /* Avoid warning for !!b == y where b is boolean.  */
	  && (!(DECL_P (tree_strip_any_location_wrapper (current.lhs))
		|| (TREE_CODE (current.lhs) == NON_LVALUE_EXPR
		    && DECL_P (tree_strip_any_location_wrapper
					    (TREE_OPERAND (current.lhs, 0)))))
	      || TREE_TYPE (current.lhs) == NULL_TREE
	      || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))
	warn_logical_not_parentheses (current.loc, current.tree_type,
				      current.lhs, maybe_constant_value (rhs));

      if (warn_xor_used_as_pow
	  && current.tree_type == BIT_XOR_EXPR
	  /* Don't warn for named "xor" (as opposed to '^').  */
	  && !(current.flags & NAMED_OP)
	  && current.lhs.decimal_p ()
	  && rhs.decimal_p ())
	check_for_xor_used_as_pow
	  (current.lhs.get_location (),
	   tree_strip_any_location_wrapper (current.lhs),
	   current.loc,
	   tree_strip_any_location_wrapper (rhs));

      overload = NULL;

      location_t combined_loc = make_location (current.loc,
					       current.lhs.get_start (),
					       rhs.get_finish ());

      /* ??? Currently we pass lhs_type == ERROR_MARK and rhs_type ==
	 ERROR_MARK for everything that is not a binary expression.
	 This makes warn_about_parentheses miss some warnings that
	 involve unary operators.  For unary expressions we should
	 pass the correct tree_code unless the unary expression was
	 surrounded by parentheses.
      */
      if (no_toplevel_fold_p
	  && lookahead_prec <= current.prec
	  && sp == stack)
	{
	  if (current.lhs == error_mark_node || rhs == error_mark_node)
	    current.lhs = error_mark_node;
	  else
	    {
	      current.lhs.maybe_add_location_wrapper ();
	      rhs.maybe_add_location_wrapper ();
	      current.lhs
		= build_min (current.tree_type,
			     TREE_CODE_CLASS (current.tree_type)
			     == tcc_comparison
			     ? boolean_type_node : TREE_TYPE (current.lhs),
			     current.lhs.get_value (), rhs.get_value ());
	      SET_EXPR_LOCATION (current.lhs, combined_loc);
	    }
	}
      else
        {
	  op_location_t op_loc (current.loc, combined_loc);
	  current.lhs = build_x_binary_op (op_loc, current.tree_type,
                                           current.lhs, current.lhs_type,
					   rhs, rhs_type, NULL_TREE, &overload,
                                           complain_flags (decltype_p));
          /* TODO: build_x_binary_op doesn't always honor the location.  */
          current.lhs.set_location (combined_loc);
        }
      current.lhs_type = current.tree_type;

      /* If the binary operator required the use of an overloaded operator,
	 then this expression cannot be an integral constant-expression.
	 An overloaded operator can be used even if both operands are
	 otherwise permissible in an integral constant-expression if at
	 least one of the operands is of enumeration type.  */

      if (overload
	  && cp_parser_non_integral_constant_expression (parser,
							 NIC_OVERLOADED))
	return error_mark_node;
    }

  return current.lhs;
}

static cp_expr
cp_parser_binary_expression (cp_parser* parser, bool cast_p,
			     bool no_toplevel_fold_p,
			     enum cp_parser_prec prec,
			     cp_id_kind * pidk)
{
  return cp_parser_binary_expression (parser, cast_p, no_toplevel_fold_p,
				      /*decltype*/false, prec, pidk);
}

/* Parse the `? expression : assignment-expression' part of a
   conditional-expression.  The LOGICAL_OR_EXPR is the
   logical-or-expression that started the conditional-expression.
   Returns a representation of the entire conditional-expression.

   This routine is used by cp_parser_assignment_expression
   and cp_parser_conditional_expression.

     ? expression : assignment-expression

   GNU Extensions:

     ? : assignment-expression */

static tree
cp_parser_question_colon_clause (cp_parser* parser, cp_expr logical_or_expr)
{
  tree expr, folded_logical_or_expr = cp_fully_fold (logical_or_expr);
  cp_expr assignment_expr;
  struct cp_token *token;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Consume the `?' token.  */
  cp_lexer_consume_token (parser->lexer);
  token = cp_lexer_peek_token (parser->lexer);
  if (cp_parser_allow_gnu_extensions_p (parser)
      && token->type == CPP_COLON)
    {
      pedwarn (token->location, OPT_Wpedantic,
	       "ISO C++ does not allow %<?:%> with omitted middle operand");
      /* Implicit true clause.  */
      expr = NULL_TREE;
      c_inhibit_evaluation_warnings +=
	folded_logical_or_expr == truthvalue_true_node;
      warn_for_omitted_condop (token->location, logical_or_expr);
    }
  else
    {
      bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
      parser->colon_corrects_to_scope_p = false;
      /* Parse the expression.  */
      c_inhibit_evaluation_warnings +=
	folded_logical_or_expr == truthvalue_false_node;
      expr = cp_parser_expression (parser);
      c_inhibit_evaluation_warnings +=
	((folded_logical_or_expr == truthvalue_true_node)
	 - (folded_logical_or_expr == truthvalue_false_node));
      parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
    }

  /* The next token should be a `:'.  */
  cp_parser_require (parser, CPP_COLON, RT_COLON);
  /* Parse the assignment-expression.  */
  assignment_expr = cp_parser_assignment_expression (parser);
  c_inhibit_evaluation_warnings -=
    folded_logical_or_expr == truthvalue_true_node;

  /* Make a location:
       LOGICAL_OR_EXPR ? EXPR : ASSIGNMENT_EXPR
       ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
     with the caret at the "?", ranging from the start of
     the logical_or_expr to the end of the assignment_expr.  */
  loc = make_location (loc,
		       logical_or_expr.get_start (),
		       assignment_expr.get_finish ());

  /* Build the conditional-expression.  */
  return build_x_conditional_expr (loc, logical_or_expr,
				   expr,
				   assignment_expr,
                                   tf_warning_or_error);
}

/* Parse a conditional-expression.

   conditional-expression:
     logical-or-expression
     logical-or-expression ? expression : assignment-expression

   GNU Extensions:

     logical-or-expression ? : assignment-expression  */

static cp_expr
cp_parser_conditional_expression (cp_parser *parser)
{
  cp_expr expr = cp_parser_binary_expression (parser, false, false, false,
					      PREC_NOT_OPERATOR, NULL);
  /* If the next token is a `?' then we're actually looking at
     a conditional-expression; otherwise we're done.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
    return cp_parser_question_colon_clause (parser, expr);
  return expr;
}

/* Parse an assignment-expression.

   assignment-expression:
     conditional-expression
     logical-or-expression assignment-operator assignment_expression
     throw-expression
     yield-expression

   CAST_P is true if this expression is the target of a cast.
   DECLTYPE_P is true if this expression is the operand of decltype.

   Returns a representation for the expression.  */

static cp_expr
cp_parser_assignment_expression (cp_parser* parser, cp_id_kind * pidk,
				 bool cast_p, bool decltype_p)
{
  cp_expr expr;

  /* If the next token is the `throw' keyword, then we're looking at
     a throw-expression.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THROW))
    expr = cp_parser_throw_expression (parser);
  /* If the next token is the `co_yield' keyword, then we're looking at
     a yield-expression.  */
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CO_YIELD))
    expr = cp_parser_yield_expression (parser);
  /* Otherwise, it must be that we are looking at a
     logical-or-expression.  */
  else
    {
      /* Parse the binary expressions (logical-or-expression).  */
      expr = cp_parser_binary_expression (parser, cast_p, false,
					  decltype_p,
					  PREC_NOT_OPERATOR, pidk);
      /* If the next token is a `?' then we're actually looking at a
	 conditional-expression.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
	return cp_parser_question_colon_clause (parser, expr);
      else
	{
	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

	  /* If it's an assignment-operator, we're using the second
	     production.  */
	  enum tree_code assignment_operator
	    = cp_parser_assignment_operator_opt (parser);
	  if (assignment_operator != ERROR_MARK)
	    {
	      bool non_constant_p;

	      /* Parse the right-hand side of the assignment.  */
	      cp_expr rhs = cp_parser_initializer_clause (parser,
							  &non_constant_p);

	      if (BRACE_ENCLOSED_INITIALIZER_P (rhs))
		maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);

	      /* An assignment may not appear in a
		 constant-expression.  */
	      if (cp_parser_non_integral_constant_expression (parser,
							      NIC_ASSIGNMENT))
		return error_mark_node;
	      /* Build the assignment expression.  Its default
		 location:
		   LHS = RHS
		   ~~~~^~~~~
		 is the location of the '=' token as the
		 caret, ranging from the start of the lhs to the
		 end of the rhs.  */
	      loc = make_location (loc,
				   expr.get_start (),
				   rhs.get_finish ());
	      expr = build_x_modify_expr (loc, expr,
					  assignment_operator,
					  rhs, NULL_TREE,
					  complain_flags (decltype_p));
              /* TODO: build_x_modify_expr doesn't honor the location,
                 so we must set it here.  */
              expr.set_location (loc);
	    }
	}
    }

  return expr;
}

/* Parse an (optional) assignment-operator.

   assignment-operator: one of
     = *= /= %= += -= >>= <<= &= ^= |=

   GNU Extension:

   assignment-operator: one of
     <?= >?=

   If the next token is an assignment operator, the corresponding tree
   code is returned, and the token is consumed.  For example, for
   `+=', PLUS_EXPR is returned.  For `=' itself, the code returned is
   NOP_EXPR.  For `/', TRUNC_DIV_EXPR is returned; for `%',
   TRUNC_MOD_EXPR is returned.  If TOKEN is not an assignment
   operator, ERROR_MARK is returned.  */

static enum tree_code
cp_parser_assignment_operator_opt (cp_parser* parser)
{
  enum tree_code op;
  cp_token *token;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  switch (token->type)
    {
    case CPP_EQ:
      op = NOP_EXPR;
      break;

    case CPP_MULT_EQ:
      op = MULT_EXPR;
      break;

    case CPP_DIV_EQ:
      op = TRUNC_DIV_EXPR;
      break;

    case CPP_MOD_EQ:
      op = TRUNC_MOD_EXPR;
      break;

    case CPP_PLUS_EQ:
      op = PLUS_EXPR;
      break;

    case CPP_MINUS_EQ:
      op = MINUS_EXPR;
      break;

    case CPP_RSHIFT_EQ:
      op = RSHIFT_EXPR;
      break;

    case CPP_LSHIFT_EQ:
      op = LSHIFT_EXPR;
      break;

    case CPP_AND_EQ:
      op = BIT_AND_EXPR;
      break;

    case CPP_XOR_EQ:
      op = BIT_XOR_EXPR;
      break;

    case CPP_OR_EQ:
      op = BIT_IOR_EXPR;
      break;

    default:
      /* Nothing else is an assignment operator.  */
      op = ERROR_MARK;
    }

  /* An operator followed by ... is a fold-expression, handled elsewhere.  */
  if (op != ERROR_MARK
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
    op = ERROR_MARK;

  /* If it was an assignment operator, consume it.  */
  if (op != ERROR_MARK)
    cp_lexer_consume_token (parser->lexer);

  return op;
}

/* Parse an expression.

   expression:
     assignment-expression
     expression , assignment-expression

   CAST_P is true if this expression is the target of a cast.
   DECLTYPE_P is true if this expression is the immediate operand of decltype,
     except possibly parenthesized or on the RHS of a comma (N3276).
   WARN_COMMA_P is true if a comma should be diagnosed.

   Returns a representation of the expression.  */

static cp_expr
cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
		      bool cast_p, bool decltype_p, bool warn_comma_p)
{
  cp_expr expression = NULL_TREE;
  location_t loc = UNKNOWN_LOCATION;

  while (true)
    {
      cp_expr assignment_expression;

      /* Parse the next assignment-expression.  */
      assignment_expression
	= cp_parser_assignment_expression (parser, pidk, cast_p, decltype_p);

      /* We don't create a temporary for a call that is the immediate operand
	 of decltype or on the RHS of a comma.  But when we see a comma, we
	 need to create a temporary for a call on the LHS.  */
      if (decltype_p && !processing_template_decl
	  && TREE_CODE (assignment_expression) == CALL_EXPR
	  && CLASS_TYPE_P (TREE_TYPE (assignment_expression))
	  && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	assignment_expression
	  = build_cplus_new (TREE_TYPE (assignment_expression),
			     assignment_expression, tf_warning_or_error);

      /* If this is the first assignment-expression, we can just
	 save it away.  */
      if (!expression)
	expression = assignment_expression;
      else
	{
	  /* Create a location with caret at the comma, ranging
	     from the start of the LHS to the end of the RHS.  */
	  loc = make_location (loc,
			       expression.get_start (),
			       assignment_expression.get_finish ());
	  expression = build_x_compound_expr (loc, expression,
					      assignment_expression, NULL_TREE,
					      complain_flags (decltype_p));
	  expression.set_location (loc);
	}
      /* If the next token is not a comma, or we're in a fold-expression, then
	 we are done with the expression.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
	  || cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS))
	break;
      /* Consume the `,'.  */
      loc = cp_lexer_peek_token (parser->lexer)->location;
      if (warn_comma_p)
	{
	  /* [depr.comma.subscript]: A comma expression appearing as
	     the expr-or-braced-init-list of a subscripting expression
	     is deprecated.  A parenthesized comma expression is not
	     deprecated.  */
	  warning_at (loc, OPT_Wcomma_subscript,
		      "top-level comma expression in array subscript "
		      "is deprecated");
	  warn_comma_p = false;
	}
      cp_lexer_consume_token (parser->lexer);
      /* A comma operator cannot appear in a constant-expression.  */
      if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
	expression = error_mark_node;
    }

  return expression;
}

/* Parse a constant-expression.

   constant-expression:
     conditional-expression

  If ALLOW_NON_CONSTANT_P a non-constant expression is silently
  accepted.  If ALLOW_NON_CONSTANT_P is true and the expression is not
  constant, *NON_CONSTANT_P is set to TRUE.  If ALLOW_NON_CONSTANT_P
  is false, NON_CONSTANT_P should be NULL.  If ALLOW_NON_CONSTANT_P is
  greater than 1, this isn't really a constant-expression, only a
  potentially constant-evaluated expression.  If STRICT_P is true,
  only parse a conditional-expression, otherwise parse an
  assignment-expression.  See below for rationale.  */

static cp_expr
cp_parser_constant_expression (cp_parser* parser,
			       int allow_non_constant_p,
			       bool *non_constant_p,
			       bool strict_p)
{
  bool saved_integral_constant_expression_p;
  bool saved_allow_non_integral_constant_expression_p;
  bool saved_non_integral_constant_expression_p;
  cp_expr expression;

  /* It might seem that we could simply parse the
     conditional-expression, and then check to see if it were
     TREE_CONSTANT.  However, an expression that is TREE_CONSTANT is
     one that the compiler can figure out is constant, possibly after
     doing some simplifications or optimizations.  The standard has a
     precise definition of constant-expression, and we must honor
     that, even though it is somewhat more restrictive.

     For example:

       int i[(2, 3)];

     is not a legal declaration, because `(2, 3)' is not a
     constant-expression.  The `,' operator is forbidden in a
     constant-expression.  However, GCC's constant-folding machinery
     will fold this operation to an INTEGER_CST for `3'.  */

  /* Save the old settings.  */
  saved_integral_constant_expression_p = parser->integral_constant_expression_p;
  saved_allow_non_integral_constant_expression_p
    = parser->allow_non_integral_constant_expression_p;
  saved_non_integral_constant_expression_p = parser->non_integral_constant_expression_p;
  /* We are now parsing a constant-expression.  */
  parser->integral_constant_expression_p = true;
  parser->allow_non_integral_constant_expression_p
    = (allow_non_constant_p || cxx_dialect >= cxx11);
  parser->non_integral_constant_expression_p = false;

  /* A manifestly constant-evaluated expression is evaluated even in an
     unevaluated operand.  */
  cp_evaluated ev (/*reset if*/allow_non_constant_p <= 1);

  /* Although the grammar says "conditional-expression", when not STRICT_P,
     we parse an "assignment-expression", which also permits
     "throw-expression" and the use of assignment operators.  In the case
     that ALLOW_NON_CONSTANT_P is false, we get better errors than we would
     otherwise.  In the case that ALLOW_NON_CONSTANT_P is true, it is
     actually essential that we look for an assignment-expression.
     For example, cp_parser_initializer_clauses uses this function to
     determine whether a particular assignment-expression is in fact
     constant.  */
  if (strict_p)
    expression = cp_parser_conditional_expression (parser);
  else
    expression = cp_parser_assignment_expression (parser);
  /* Restore the old settings.  */
  parser->integral_constant_expression_p
    = saved_integral_constant_expression_p;
  parser->allow_non_integral_constant_expression_p
    = saved_allow_non_integral_constant_expression_p;
  if (cxx_dialect >= cxx11)
    {
      /* Require an rvalue constant expression here; that's what our
	 callers expect.  Reference constant expressions are handled
	 separately in e.g. cp_parser_template_argument.  */
      tree decay = expression;
      if (TREE_TYPE (expression)
	  && TREE_CODE (TREE_TYPE (expression)) == ARRAY_TYPE)
	decay = build_address (expression);
      bool is_const = is_rvalue_constant_expression (decay);
      parser->non_integral_constant_expression_p = !is_const;
      if (!is_const && !allow_non_constant_p)
	require_rvalue_constant_expression (decay);
    }
  if (allow_non_constant_p)
    *non_constant_p = parser->non_integral_constant_expression_p;
  parser->non_integral_constant_expression_p
    = saved_non_integral_constant_expression_p;

  return expression;
}

/* Parse __builtin_offsetof.

   offsetof-expression:
     "__builtin_offsetof" "(" type-id "," offsetof-member-designator ")"

   offsetof-member-designator:
     id-expression
     | offsetof-member-designator "." id-expression
     | offsetof-member-designator "[" expression "]"
     | offsetof-member-designator "->" id-expression  */

static cp_expr
cp_parser_builtin_offsetof (cp_parser *parser)
{
  int save_ice_p, save_non_ice_p;
  tree type;
  cp_expr expr;
  cp_id_kind dummy;
  cp_token *token;
  location_t finish_loc;

  /* We're about to accept non-integral-constant things, but will
     definitely yield an integral constant expression.  Save and
     restore these values around our local parsing.  */
  save_ice_p = parser->integral_constant_expression_p;
  save_non_ice_p = parser->non_integral_constant_expression_p;

  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Consume the "__builtin_offsetof" token.  */
  cp_lexer_consume_token (parser->lexer);
  /* Consume the opening `('.  */
  matching_parens parens;
  parens.require_open (parser);
  /* Parse the type-id.  */
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
  {
    const char *saved_message = parser->type_definition_forbidden_message;
    parser->type_definition_forbidden_message
      = G_("types may not be defined within %<__builtin_offsetof%>");
    type = cp_parser_type_id (parser);
    parser->type_definition_forbidden_message = saved_message;
  }
  /* Look for the `,'.  */
  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
  token = cp_lexer_peek_token (parser->lexer);

  /* Build the (type *)null that begins the traditional offsetof macro.  */
  tree object_ptr
    = build_static_cast (input_location, build_pointer_type (type),
			 null_pointer_node, tf_warning_or_error);

  /* Parse the offsetof-member-designator.  We begin as if we saw "expr->".  */
  expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DEREF, object_ptr,
						 true, &dummy, token->location);
  while (true)
    {
      token = cp_lexer_peek_token (parser->lexer);
      switch (token->type)
	{
	case CPP_OPEN_SQUARE:
	  /* offsetof-member-designator "[" expression "]" */
	  expr = cp_parser_postfix_open_square_expression (parser, expr,
							   true, false);
	  break;

	case CPP_DEREF:
	  /* offsetof-member-designator "->" identifier */
	  expr = grok_array_decl (token->location, expr, integer_zero_node,
				  NULL, tf_warning_or_error);
	  /* FALLTHRU */

	case CPP_DOT:
	  /* offsetof-member-designator "." identifier */
	  cp_lexer_consume_token (parser->lexer);
	  expr = cp_parser_postfix_dot_deref_expression (parser, CPP_DOT,
							 expr, true, &dummy,
							 token->location);
	  break;

	case CPP_CLOSE_PAREN:
	  /* Consume the ")" token.  */
	  finish_loc = cp_lexer_peek_token (parser->lexer)->location;
	  cp_lexer_consume_token (parser->lexer);
	  goto success;

	default:
	  /* Error.  We know the following require will fail, but
	     that gives the proper error message.  */
	  parens.require_close (parser);
	  cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
	  expr = error_mark_node;
	  goto failure;
	}
    }

 success:
  /* Make a location of the form:
       __builtin_offsetof (struct s, f)
       ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~
     with caret at the type-id, ranging from the start of the
     "_builtin_offsetof" token to the close paren.  */
  loc = make_location (loc, start_loc, finish_loc);
  /* The result will be an INTEGER_CST, so we need to explicitly
     preserve the location.  */
  expr = cp_expr (finish_offsetof (object_ptr, expr, loc), loc);

 failure:
  parser->integral_constant_expression_p = save_ice_p;
  parser->non_integral_constant_expression_p = save_non_ice_p;

  expr = expr.maybe_add_location_wrapper ();
  return expr;
}

/* Parse a builtin trait expression or type.  */

static cp_expr
cp_parser_trait (cp_parser* parser, enum rid keyword)
{
  cp_trait_kind kind;
  tree type1, type2 = NULL_TREE;
  bool binary = false;
  bool variadic = false;
  bool type = false;

  switch (keyword)
    {
#define DEFTRAIT(TCC, CODE, NAME, ARITY) \
    case RID_##CODE:			 \
      kind = CPTK_##CODE;		 \
      binary = (ARITY == 2);		 \
      variadic = (ARITY == -1);		 \
      type = (TCC == tcc_type);		 \
      break;
#include "cp-trait.def"
#undef DEFTRAIT
    default:
      gcc_unreachable ();
    }

  /* Get location of initial token.  */
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Consume the token.  */
  cp_lexer_consume_token (parser->lexer);

  matching_parens parens;
  parens.require_open (parser);

  {
    type_id_in_expr_sentinel s (parser);
    type1 = cp_parser_type_id (parser);
  }

  if (type1 == error_mark_node)
    return error_mark_node;

  if (binary)
    {
      cp_parser_require (parser, CPP_COMMA, RT_COMMA);

      {
	type_id_in_expr_sentinel s (parser);
	type2 = cp_parser_type_id (parser);
      }

      if (type2 == error_mark_node)
	return error_mark_node;
    }
  else if (variadic)
    {
      while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	{
	  cp_lexer_consume_token (parser->lexer);
	  tree elt = cp_parser_type_id (parser);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      elt = make_pack_expansion (elt);
	    }
	  if (elt == error_mark_node)
	    return error_mark_node;
	  type2 = tree_cons (NULL_TREE, elt, type2);
	}
      type2 = nreverse (type2);
    }

  location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
  parens.require_close (parser);

  /* Construct a location of the form:
       __is_trivially_copyable(_Tp)
       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
     with start == caret, finishing at the close-paren.  */
  location_t trait_loc = make_location (start_loc, start_loc, finish_loc);

  /* Complete the trait expression, which may mean either processing
     the trait expr now or saving it for template instantiation.  */
  switch (kind)
    {
    case CPTK_BASES:
      return cp_expr (finish_bases (type1, false), trait_loc);
    case CPTK_DIRECT_BASES:
      return cp_expr (finish_bases (type1, true), trait_loc);
    default:
      if (type)
	return finish_trait_type (kind, type1, type2);
      else
	return finish_trait_expr (trait_loc, kind, type1, type2);
    }
}

/* Parse a lambda expression.

   lambda-expression:
     lambda-introducer lambda-declarator [opt] compound-statement
     lambda-introducer < template-parameter-list > requires-clause [opt]
       lambda-declarator [opt] compound-statement

   Returns a representation of the expression.  */

static cp_expr
cp_parser_lambda_expression (cp_parser* parser)
{
  tree lambda_expr = build_lambda_expr ();
  tree type;
  bool ok = true;
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  cp_token_position start = 0;

  LAMBDA_EXPR_LOCATION (lambda_expr) = token->location;

  if (cxx_dialect >= cxx20)
    {
      /* C++20 allows lambdas in unevaluated context, but one in the type of a
	 non-type parameter is nonsensical.

	 Distinguish a lambda in the parameter type from a lambda in the
	 default argument by looking at local_variables_forbidden_p, which is
	 only set in default arguments.  */
      if (processing_template_parmlist && !parser->local_variables_forbidden_p)
	{
	  error_at (token->location,
		    "lambda-expression in template parameter type");
	  token->error_reported = true;
	  ok = false;
	}
    }
  else if (cp_unevaluated_operand)
    {
      if (!token->error_reported)
	{
	  error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
		    "lambda-expression in unevaluated context"
		    " only available with %<-std=c++20%> or %<-std=gnu++20%>");
	  token->error_reported = true;
	}
      ok = false;
    }
  else if (parser->in_template_argument_list_p || processing_template_parmlist)
    {
      if (!token->error_reported)
	{
	  error_at (token->location, "lambda-expression in template-argument"
		    " only available with %<-std=c++20%> or %<-std=gnu++20%>");
	  token->error_reported = true;
	}
      ok = false;
    }

  /* We may be in the middle of deferred access check.  Disable
     it now.  */
  push_deferring_access_checks (dk_no_deferred);

  cp_parser_lambda_introducer (parser, lambda_expr);
  if (cp_parser_error_occurred (parser))
    return error_mark_node;

  type = begin_lambda_type (lambda_expr);
  if (type == error_mark_node)
    return error_mark_node;

  record_lambda_scope (lambda_expr);
  record_lambda_scope_discriminator (lambda_expr);

  /* Do this again now that LAMBDA_EXPR_EXTRA_SCOPE is set.  */
  determine_visibility (TYPE_NAME (type));

  /* Now that we've started the type, add the capture fields for any
     explicit captures.  */
  register_capture_members (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));

  {
    /* Inside the class, surrounding template-parameter-lists do not apply.  */
    unsigned int saved_num_template_parameter_lists
        = parser->num_template_parameter_lists;
    unsigned char in_statement = parser->in_statement;
    bool in_switch_statement_p = parser->in_switch_statement_p;
    bool fully_implicit_function_template_p
        = parser->fully_implicit_function_template_p;
    tree implicit_template_parms = parser->implicit_template_parms;
    cp_binding_level* implicit_template_scope = parser->implicit_template_scope;
    bool auto_is_implicit_function_template_parm_p
        = parser->auto_is_implicit_function_template_parm_p;

    parser->num_template_parameter_lists = 0;
    parser->in_statement = 0;
    parser->in_switch_statement_p = false;
    parser->fully_implicit_function_template_p = false;
    parser->implicit_template_parms = 0;
    parser->implicit_template_scope = 0;
    parser->auto_is_implicit_function_template_parm_p = false;

    /* The body of a lambda in a discarded statement is not discarded.  */
    bool discarded = in_discarded_stmt;
    in_discarded_stmt = 0;

    /* Similarly the body of a lambda in immediate function context is not
       in immediate function context.  */
    bool save_in_consteval_if_p = in_consteval_if_p;
    in_consteval_if_p = false;

    /* By virtue of defining a local class, a lambda expression has access to
       the private variables of enclosing classes.  */

    if (cp_parser_start_tentative_firewall (parser))
      start = token;

    ok &= cp_parser_lambda_declarator_opt (parser, lambda_expr);

    if (ok && cp_parser_error_occurred (parser))
      ok = false;

    if (ok)
      cp_parser_lambda_body (parser, lambda_expr);
    else if (cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
      {
	if (cp_parser_skip_to_closing_brace (parser))
	  cp_lexer_consume_token (parser->lexer);
      }

    /* The capture list was built up in reverse order; fix that now.  */
    LAMBDA_EXPR_CAPTURE_LIST (lambda_expr)
      = nreverse (LAMBDA_EXPR_CAPTURE_LIST (lambda_expr));

    if (ok)
      maybe_add_lambda_conv_op (type);

    finish_struct (type, /*attributes=*/NULL_TREE);

    in_consteval_if_p = save_in_consteval_if_p;
    in_discarded_stmt = discarded;

    parser->num_template_parameter_lists = saved_num_template_parameter_lists;
    parser->in_statement = in_statement;
    parser->in_switch_statement_p = in_switch_statement_p;
    parser->fully_implicit_function_template_p
	= fully_implicit_function_template_p;
    parser->implicit_template_parms = implicit_template_parms;
    parser->implicit_template_scope = implicit_template_scope;
    parser->auto_is_implicit_function_template_parm_p
	= auto_is_implicit_function_template_parm_p;
  }

  /* This field is only used during parsing of the lambda.  */
  LAMBDA_EXPR_THIS_CAPTURE (lambda_expr) = NULL_TREE;

  /* This lambda shouldn't have any proxies left at this point.  */
  gcc_assert (LAMBDA_EXPR_PENDING_PROXIES (lambda_expr) == NULL);
  /* And now that we're done, push proxies for an enclosing lambda.  */
  insert_pending_capture_proxies ();

  /* Update the lambda expression to a range.  */
  LAMBDA_EXPR_LOCATION (lambda_expr) = make_location (token->location,
						      token->location,
						      parser->lexer);

  if (ok)
    lambda_expr = build_lambda_object (lambda_expr);
  else
    lambda_expr = error_mark_node;

  cp_parser_end_tentative_firewall (parser, start, lambda_expr);

  pop_deferring_access_checks ();

  return lambda_expr;
}

/* Parse the beginning of a lambda expression.

   lambda-introducer:
     [ lambda-capture [opt] ]

   LAMBDA_EXPR is the current representation of the lambda expression.  */

static void
cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
{
  /* Need commas after the first capture.  */
  bool first = true;

  /* Eat the leading `['.  */
  cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);

  /* Record default capture mode.  "[&" "[=" "[&," "[=,"  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
      && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_ELLIPSIS)
      && !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)
      && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
    LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_REFERENCE;
  else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
    LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) = CPLD_COPY;

  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE)
    {
      cp_lexer_consume_token (parser->lexer);
      first = false;

      if (!(at_function_scope_p () || parsing_nsdmi ()))
	error ("non-local lambda expression cannot have a capture-default");
    }

  hash_set<tree, true> ids;
  tree first_capture_id = NULL_TREE;
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_SQUARE))
    {
      cp_token* capture_token;
      tree capture_id;
      tree capture_init_expr;
      cp_id_kind idk = CP_ID_KIND_NONE;
      bool explicit_init_p = false;

      enum capture_kind_type
      {
	BY_COPY,
	BY_REFERENCE
      };
      enum capture_kind_type capture_kind = BY_COPY;

      if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
	{
	  error ("expected end of capture-list");
	  return;
	}

      if (first)
	first = false;
      else
	cp_parser_require (parser, CPP_COMMA, RT_COMMA);

      /* Possibly capture `this'.  */
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_THIS))
	{
	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
	  if (cxx_dialect < cxx20 && pedantic
	      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY)
	    pedwarn (loc, OPT_Wc__20_extensions,
		     "explicit by-copy capture of %<this%> "
		     "with by-copy capture default only available with "
		     "%<-std=c++20%> or %<-std=gnu++20%>");
	  cp_lexer_consume_token (parser->lexer);
	  if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
	    pedwarn (input_location, 0,
		     "already captured %qD in lambda expression",
		     this_identifier);
	  else
	    add_capture (lambda_expr, /*id=*/this_identifier,
			 /*initializer=*/finish_this_expr (),
			 /*by_reference_p=*/true, explicit_init_p);
	  continue;
	}

      /* Possibly capture `*this'.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_MULT)
	  && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
	{
	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
	  if (cxx_dialect < cxx17)
	    pedwarn (loc, OPT_Wc__17_extensions,
		     "%<*this%> capture only available with "
		     "%<-std=c++17%> or %<-std=gnu++17%>");
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
	    pedwarn (input_location, 0,
		     "already captured %qD in lambda expression",
		     this_identifier);
	  else
	    add_capture (lambda_expr, /*id=*/this_identifier,
			 /*initializer=*/finish_this_expr (),
			 /*by_reference_p=*/false, explicit_init_p);
	  continue;
	}

      /* But reject `&this'.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_AND)
	  && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_THIS))
	{
	  error_at (cp_lexer_peek_token (parser->lexer)->location,
		    "%<this%> cannot be captured by reference");
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  continue;
	}

      /* Remember whether we want to capture as a reference or not.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_AND))
	{
	  capture_kind = BY_REFERENCE;
	  cp_lexer_consume_token (parser->lexer);
	}

      bool init_pack_expansion = false;
      location_t ellipsis_loc = UNKNOWN_LOCATION;
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	{
	  ellipsis_loc = cp_lexer_peek_token (parser->lexer)->location;
	  if (cxx_dialect < cxx20)
	    pedwarn (ellipsis_loc, OPT_Wc__20_extensions,
		     "pack init-capture only available with "
		     "%<-std=c++20%> or %<-std=gnu++20%>");
	  cp_lexer_consume_token (parser->lexer);
	  init_pack_expansion = true;
	}

      /* Early C++20 drafts had ...& instead of &...; be forgiving.  */
      if (init_pack_expansion && capture_kind != BY_REFERENCE
	  && cp_lexer_next_token_is (parser->lexer, CPP_AND))
	{
	  pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		   0, "%<&%> should come before %<...%>");
	  capture_kind = BY_REFERENCE;
	  cp_lexer_consume_token (parser->lexer);
	}

      /* Get the identifier.  */
      capture_token = cp_lexer_peek_token (parser->lexer);
      capture_id = cp_parser_identifier (parser);

      if (capture_id == error_mark_node)
	/* Would be nice to have a cp_parser_skip_to_closing_x for general
           delimiters, but I modified this to stop on unnested ']' as well.  It
           was already changed to stop on unnested '}', so the
           "closing_parenthesis" name is no more misleading with my change.  */
	{
	  cp_parser_skip_to_closing_parenthesis (parser,
						 /*recovering=*/true,
						 /*or_comma=*/true,
						 /*consume_paren=*/true);
	  break;
	}

      /* Find the initializer for this capture.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
	  || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
	  || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	{
	  bool direct, non_constant;
	  /* An explicit initializer exists.  */
	  if (cxx_dialect < cxx14)
	    pedwarn (input_location, OPT_Wc__14_extensions,
		     "lambda capture initializers "
		     "only available with %<-std=c++14%> or %<-std=gnu++14%>");
	  capture_init_expr = cp_parser_initializer (parser, &direct,
						     &non_constant, true);
	  explicit_init_p = true;
	  if (capture_init_expr == NULL_TREE)
	    {
	      error ("empty initializer for lambda init-capture");
	      capture_init_expr = error_mark_node;
	    }
	  if (init_pack_expansion)
	    capture_init_expr = make_pack_expansion (capture_init_expr);
	}
      else
	{
	  const char* error_msg;

	  /* Turn the identifier into an id-expression.  */
	  capture_init_expr
	    = cp_parser_lookup_name_simple (parser, capture_id,
					    capture_token->location);

	  if (capture_init_expr == error_mark_node)
	    {
	      unqualified_name_lookup_error (capture_id);
	      continue;
	    }
	  else if (!VAR_P (capture_init_expr)
		   && TREE_CODE (capture_init_expr) != PARM_DECL)
	    {
	      error_at (capture_token->location,
			"capture of non-variable %qE",
			capture_init_expr);
	      if (DECL_P (capture_init_expr))
		inform (DECL_SOURCE_LOCATION (capture_init_expr),
			"%q#D declared here", capture_init_expr);
	      continue;
	    }
	  if (VAR_P (capture_init_expr)
	      && decl_storage_duration (capture_init_expr) != dk_auto)
	    {
	      if (pedwarn (capture_token->location, 0, "capture of variable "
			   "%qD with non-automatic storage duration",
			   capture_init_expr))
		inform (DECL_SOURCE_LOCATION (capture_init_expr),
			"%q#D declared here", capture_init_expr);
	      continue;
	    }

	  capture_init_expr
            = finish_id_expression
                (capture_id,
		 capture_init_expr,
                 parser->scope,
                 &idk,
                 /*integral_constant_expression_p=*/false,
                 /*allow_non_integral_constant_expression_p=*/false,
                 /*non_integral_constant_expression_p=*/NULL,
                 /*template_p=*/false,
                 /*done=*/true,
                 /*address_p=*/false,
                 /*template_arg_p=*/false,
                 &error_msg,
                 capture_token->location);

	  if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	    {
	      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
	      cp_lexer_consume_token (parser->lexer);
	      capture_init_expr = make_pack_expansion (capture_init_expr);
	      if (init_pack_expansion)
		{
		  /* If what follows is an initializer, the second '...' is
		     invalid.  But for cases like [...xs...], the first one
		     is invalid.  */
		  if (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
		      || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
		      || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
		    ellipsis_loc = loc;
		  error_at (ellipsis_loc, "too many %<...%> in lambda capture");
		  continue;
		}
	    }
	}

      if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
	  && !explicit_init_p)
	{
	  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY
	      && capture_kind == BY_COPY)
	    pedwarn (capture_token->location, 0, "explicit by-copy capture "
		     "of %qD redundant with by-copy capture default",
		     capture_id);
	  if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_REFERENCE
	      && capture_kind == BY_REFERENCE)
	    pedwarn (capture_token->location, 0, "explicit by-reference "
		     "capture of %qD redundant with by-reference capture "
		     "default", capture_id);
	}

      /* Check for duplicates.
	 Optimize for the zero or one explicit captures cases and only create
	 the hash_set after adding second capture.  */
      bool found = false;
      if (!ids.is_empty ())
	found = ids.add (capture_id);
      else if (first_capture_id == NULL_TREE)
	first_capture_id = capture_id;
      else if (capture_id == first_capture_id)
	found = true;
      else
	{
	  ids.add (first_capture_id);
	  ids.add (capture_id);
	}
      if (found)
	pedwarn (input_location, 0,
		 "already captured %qD in lambda expression", capture_id);
      else
	add_capture (lambda_expr, capture_id, capture_init_expr,
		     /*by_reference_p=*/capture_kind == BY_REFERENCE,
		     explicit_init_p);

      /* If there is any qualification still in effect, clear it
	 now; we will be starting fresh with the next capture.  */
      parser->scope = NULL_TREE;
      parser->qualifying_scope = NULL_TREE;
      parser->object_scope = NULL_TREE;
    }

  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
}

/* Parse the (optional) middle of a lambda expression.

   lambda-declarator:
     ( parameter-declaration-clause ) lambda-specifiers requires-clause [opt]
     lambda-specifiers (C++23)

   lambda-specifiers:
     decl-specifier-seq [opt] noexcept-specifier [opt]
       attribute-specifier-seq [opt] trailing-return-type [opt]

   LAMBDA_EXPR is the current representation of the lambda expression.  */

static bool
cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
{
  /* 5.1.1.4 of the standard says:
       If a lambda-expression does not include a lambda-declarator, it is as if
       the lambda-declarator were ().
     This means an empty parameter list, no attributes, and no exception
     specification.  */
  tree param_list = void_list_node;
  tree std_attrs = NULL_TREE;
  tree gnu_attrs = NULL_TREE;
  tree exception_spec = NULL_TREE;
  tree template_param_list = NULL_TREE;
  tree tx_qual = NULL_TREE;
  tree return_type = NULL_TREE;
  tree trailing_requires_clause = NULL_TREE;
  bool has_param_list = false;
  location_t omitted_parms_loc = UNKNOWN_LOCATION;
  cp_decl_specifier_seq lambda_specs;
  clear_decl_specs (&lambda_specs);
  /* A lambda op() is const unless explicitly 'mutable'.  */
  cp_cv_quals quals = TYPE_QUAL_CONST;

  /* The template-parameter-list is optional, but must begin with
     an opening angle if present.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    {
      if (cxx_dialect < cxx14)
	pedwarn (parser->lexer->next_token->location, OPT_Wc__14_extensions,
		 "lambda templates are only available with "
		 "%<-std=c++14%> or %<-std=gnu++14%>");
      else if (pedantic && cxx_dialect < cxx20)
	pedwarn (parser->lexer->next_token->location, OPT_Wc__20_extensions,
		 "lambda templates are only available with "
		 "%<-std=c++20%> or %<-std=gnu++20%>");

      cp_lexer_consume_token (parser->lexer);

      template_param_list = cp_parser_template_parameter_list (parser);
      cp_parser_require_end_of_template_parameter_list (parser);

      /* We may have a constrained generic lambda; parse the requires-clause
	 immediately after the template-parameter-list and combine with any
	 shorthand constraints present.  */
      tree dreqs = cp_parser_requires_clause_opt (parser, true);
      if (flag_concepts)
	{
	  tree reqs = get_shorthand_constraints (current_template_parms);
	  if (dreqs)
	    reqs = combine_constraint_expressions (reqs, dreqs);
	  TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
	}

      /* We just processed one more parameter list.  */
      ++parser->num_template_parameter_lists;
    }

  /* Committee discussion supports allowing attributes here.  */
  lambda_specs.attributes = cp_parser_attributes_opt (parser);

  /* The parameter-declaration-clause is optional (unless
     template-parameter-list was given), but must begin with an
     opening parenthesis if present.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      matching_parens parens;
      parens.consume_open (parser);

      begin_scope (sk_function_parms, /*entity=*/NULL_TREE);

      /* Parse parameters.  */
      param_list
	= cp_parser_parameter_declaration_clause
	    (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL);

      /* Default arguments shall not be specified in the
	 parameter-declaration-clause of a lambda-declarator.  */
      if (pedantic && cxx_dialect < cxx14)
	for (tree t = param_list; t; t = TREE_CHAIN (t))
	  if (TREE_PURPOSE (t) && DECL_P (TREE_VALUE (t)))
	    pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)),
		     OPT_Wc__14_extensions,
		     "default argument specified for lambda parameter");

      parens.require_close (parser);
      has_param_list = true;
    }
  else if (cxx_dialect < cxx23)
    omitted_parms_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* In the decl-specifier-seq of the lambda-declarator, each
     decl-specifier shall either be mutable or constexpr.  */
  int declares_class_or_enum;
  if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
    cp_parser_decl_specifier_seq (parser,
				  CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
				  &lambda_specs, &declares_class_or_enum);

  if (omitted_parms_loc && lambda_specs.any_specifiers_p)
    {
      pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
	       "parameter declaration before lambda declaration "
	       "specifiers only optional with %<-std=c++2b%> or "
	       "%<-std=gnu++2b%>");
      omitted_parms_loc = UNKNOWN_LOCATION;
    }

  if (lambda_specs.storage_class == sc_mutable)
    {
      LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
      quals = TYPE_UNQUALIFIED;
    }
  else if (lambda_specs.storage_class == sc_static)
    {
      if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE
	  || LAMBDA_EXPR_CAPTURE_LIST (lambda_expr))
	error_at (lambda_specs.locations[ds_storage_class],
		  "%<static%> lambda specifier with lambda capture");
      else
	{
	  LAMBDA_EXPR_STATIC_P (lambda_expr) = 1;
	  quals = TYPE_UNQUALIFIED;
	}
    }

  tx_qual = cp_parser_tx_qualifier_opt (parser);
  if (omitted_parms_loc && tx_qual)
    {
      pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
	       "parameter declaration before lambda transaction "
	       "qualifier only optional with %<-std=c++2b%> or "
	       "%<-std=gnu++2b%>");
      omitted_parms_loc = UNKNOWN_LOCATION;
    }

  /* Parse optional exception specification.  */
  exception_spec
    = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);

  if (omitted_parms_loc && exception_spec)
    {
      pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
	       "parameter declaration before lambda exception "
	       "specification only optional with %<-std=c++2b%> or "
	       "%<-std=gnu++2b%>");
      omitted_parms_loc = UNKNOWN_LOCATION;
    }

  /* GCC 8 accepted attributes here, and this is the place for standard C++11
     attributes that appertain to the function type.  */
  if (cp_next_tokens_can_be_gnu_attribute_p (parser))
    gnu_attrs = cp_parser_gnu_attributes_opt (parser);
  else
    std_attrs = cp_parser_std_attribute_spec_seq (parser);

  /* Parse optional trailing return type.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
    {
      if (omitted_parms_loc)
	pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
		 "parameter declaration before lambda trailing "
		 "return type only optional with %<-std=c++2b%> or "
		 "%<-std=gnu++2b%>");
      cp_lexer_consume_token (parser->lexer);
      return_type = cp_parser_trailing_type_id (parser);
    }

  /* Also allow GNU attributes at the very end of the declaration, the usual
     place for GNU attributes.  */
  if (cp_next_tokens_can_be_gnu_attribute_p (parser))
    gnu_attrs = chainon (gnu_attrs, cp_parser_gnu_attributes_opt (parser));

  if (has_param_list)
    {
      /* Parse optional trailing requires clause.  */
      trailing_requires_clause = cp_parser_requires_clause_opt (parser, false);

      /* The function parameters must be in scope all the way until after the
         trailing-return-type in case of decltype.  */
      pop_bindings_and_leave_scope ();
    }

  /* Create the function call operator.

     Messing with declarators like this is no uglier than building up the
     FUNCTION_DECL by hand, and this is less likely to get out of sync with
     other code.  */
  {
    cp_decl_specifier_seq return_type_specs;
    cp_declarator* declarator;
    tree fco;
    void *p;

    clear_decl_specs (&return_type_specs);
    return_type_specs.type = make_auto ();

    if (lambda_specs.locations[ds_constexpr])
      {
	if (cxx_dialect >= cxx17)
	  return_type_specs.locations[ds_constexpr]
	    = lambda_specs.locations[ds_constexpr];
	else
	  error_at (lambda_specs.locations[ds_constexpr], "%<constexpr%> "
		    "lambda only available with %<-std=c++17%> or "
		    "%<-std=gnu++17%>");
      }
    if (lambda_specs.locations[ds_consteval])
      return_type_specs.locations[ds_consteval]
	= lambda_specs.locations[ds_consteval];
    if (LAMBDA_EXPR_STATIC_P (lambda_expr))
      {
	return_type_specs.storage_class = sc_static;
	return_type_specs.locations[ds_storage_class]
	  = lambda_specs.locations[ds_storage_class];
      }

    p = obstack_alloc (&declarator_obstack, 0);

    declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none,
				     LAMBDA_EXPR_LOCATION (lambda_expr));

    declarator = make_call_declarator (declarator, param_list, quals,
				       VIRT_SPEC_UNSPECIFIED,
				       REF_QUAL_NONE,
				       tx_qual,
				       exception_spec,
				       return_type,
				       trailing_requires_clause,
				       std_attrs,
				       UNKNOWN_LOCATION);

    fco = grokmethod (&return_type_specs,
		      declarator,
		      chainon (gnu_attrs, lambda_specs.attributes));
    if (fco != error_mark_node)
      {
	DECL_INITIALIZED_IN_CLASS_P (fco) = 1;
	DECL_ARTIFICIAL (fco) = 1;
	if (!LAMBDA_EXPR_STATIC_P (lambda_expr))
	  /* Give the object parameter a different name.  */
	  DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
	DECL_SET_LAMBDA_FUNCTION (fco, true);
      }
    if (template_param_list)
      {
	fco = finish_member_template_decl (fco);
	finish_template_decl (template_param_list);
	--parser->num_template_parameter_lists;
      }
    else if (parser->fully_implicit_function_template_p)
      fco = finish_fully_implicit_template (parser, fco);

    finish_member_declaration (fco);
    record_lambda_scope_sig_discriminator (lambda_expr, fco);

    obstack_free (&declarator_obstack, p);

    return (fco != error_mark_node);
  }
}

/* Parse the body of a lambda expression, which is simply

   compound-statement

   but which requires special handling.
   LAMBDA_EXPR is the current representation of the lambda expression.  */

static void
cp_parser_lambda_body (cp_parser* parser, tree lambda_expr)
{
  bool nested = (current_function_decl != NULL_TREE);
  unsigned char local_variables_forbidden_p
    = parser->local_variables_forbidden_p;
  bool in_function_body = parser->in_function_body;

  /* The body of a lambda-expression is not a subexpression of the enclosing
     expression.  */
  cp_evaluated ev;

  if (nested)
    push_function_context ();
  else
    /* Still increment function_depth so that we don't GC in the
       middle of an expression.  */
    ++function_depth;

  auto odsd = make_temp_override (parser->omp_declare_simd, NULL);
  auto ord = make_temp_override (parser->oacc_routine, NULL);
  auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false);
  vec<tree> omp_privatization_save;
  save_omp_privatization_clauses (omp_privatization_save);
  /* Clear this in case we're in the middle of a default argument.  */
  parser->local_variables_forbidden_p = 0;
  parser->in_function_body = true;

  {
    local_specialization_stack s (lss_copy);
    tree fco = lambda_function (lambda_expr);
    tree body = start_lambda_function (fco, lambda_expr);

    /* Originally C++11 required us to peek for 'return expr'; and
       process it specially here to deduce the return type.  N3638
       removed the need for that.  */
    cp_parser_function_body (parser, false);

    finish_lambda_function (body);
  }

  restore_omp_privatization_clauses (omp_privatization_save);
  parser->local_variables_forbidden_p = local_variables_forbidden_p;
  parser->in_function_body = in_function_body;
  if (nested)
    pop_function_context();
  else
    --function_depth;
}

/* Statements [gram.stmt.stmt]  */

/* Build and add a DEBUG_BEGIN_STMT statement with location LOC.  */

static void
add_debug_begin_stmt (location_t loc)
{
  if (!MAY_HAVE_DEBUG_MARKER_STMTS)
    return;
  if (DECL_DECLARED_CONCEPT_P (current_function_decl))
    /* A concept is never expanded normally.  */
    return;

  tree stmt = build0 (DEBUG_BEGIN_STMT, void_type_node);
  SET_EXPR_LOCATION (stmt, loc);
  add_stmt (stmt);
}

struct cp_omp_attribute_data
{
  cp_token_cache *tokens;
  const c_omp_directive *dir;
  c_omp_directive_kind kind;
};

/* Handle omp::directive and omp::sequence attributes in ATTRS
   (if any) at the start of a statement or in attribute-declaration.  */

static tree
cp_parser_handle_statement_omp_attributes (cp_parser *parser, tree attrs)
{
  if (!flag_openmp && !flag_openmp_simd)
    return attrs;

  auto_vec<cp_omp_attribute_data, 16> vec;
  int cnt = 0;
  int tokens = 0;
  bool bad = false;
  for (tree *pa = &attrs; *pa; )
    if (get_attribute_namespace (*pa) == omp_identifier
	&& is_attribute_p ("directive", get_attribute_name (*pa)))
      {
	cnt++;
	for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
	  {
	    tree d = TREE_VALUE (a);
	    gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
	    cp_token *first = DEFPARSE_TOKENS (d)->first;
	    cp_token *last = DEFPARSE_TOKENS (d)->last;
	    if (parser->omp_attrs_forbidden_p)
	      {
		error_at (first->location,
			  "mixing OpenMP directives with attribute and pragma "
			  "syntax on the same statement");
		parser->omp_attrs_forbidden_p = false;
		bad = true;
	      }
	    const char *directive[3] = {};
	    for (int i = 0; i < 3; i++)
	      {
		tree id = NULL_TREE;
		if (first + i == last)
		  break;
		if (first[i].type == CPP_NAME)
		  id = first[i].u.value;
		else if (first[i].type == CPP_KEYWORD)
		  id = ridpointers[(int) first[i].keyword];
		else
		  break;
		directive[i] = IDENTIFIER_POINTER (id);
	      }
	    const c_omp_directive *dir = NULL;
	    if (directive[0])
	      dir = c_omp_categorize_directive (directive[0], directive[1],
						directive[2]);
	    if (dir == NULL)
	      {
		error_at (first->location,
			  "unknown OpenMP directive name in %<omp::directive%>"
			  " attribute argument");
		continue;
	      }
	    c_omp_directive_kind kind = dir->kind;
	    if (dir->id == PRAGMA_OMP_ORDERED)
	      {
		/* ordered is C_OMP_DIR_CONSTRUCT only if it doesn't contain
		   depend/doacross clause.  */
		if (directive[1]
		    && (strcmp (directive[1], "depend") == 0
			|| strcmp (directive[1], "doacross") == 0))
		  kind = C_OMP_DIR_STANDALONE;
		else if (first + 2 < last
			 && first[1].type == CPP_COMMA
			 && first[2].type == CPP_NAME
			 && (strcmp (IDENTIFIER_POINTER (first[2].u.value),
				     "depend") == 0
			     || strcmp (IDENTIFIER_POINTER (first[2].u.value),
					"doacross") == 0))
		  kind = C_OMP_DIR_STANDALONE;
	      }
	    else if (dir->id == PRAGMA_OMP_ERROR)
	      {
		/* error with at(execution) clause is C_OMP_DIR_STANDALONE.  */
		int paren_depth = 0;
		for (int i = 1; first + i < last; i++)
		  if (first[i].type == CPP_OPEN_PAREN)
		    paren_depth++;
		  else if (first[i].type == CPP_CLOSE_PAREN)
		    paren_depth--;
		  else if (paren_depth == 0
			   && first + i + 2 < last
			   && first[i].type == CPP_NAME
			   && first[i + 1].type == CPP_OPEN_PAREN
			   && first[i + 2].type == CPP_NAME
			   && !strcmp (IDENTIFIER_POINTER (first[i].u.value),
				       "at")
			   && !strcmp (IDENTIFIER_POINTER (first[i
								 + 2].u.value),
				       "execution"))
		    {
		      kind = C_OMP_DIR_STANDALONE;
		      break;
		    }
	      }
	    cp_omp_attribute_data v = { DEFPARSE_TOKENS (d), dir, kind };
	    vec.safe_push (v);
	    if (flag_openmp || dir->simd)
	      tokens += (last - first) + 1;
	  }
	cp_omp_attribute_data v = {};
	vec.safe_push (v);
	*pa = TREE_CHAIN (*pa);
      }
    else
      pa = &TREE_CHAIN (*pa);

  if (bad)
    return attrs;

  unsigned int i;
  cp_omp_attribute_data *v;
  cp_omp_attribute_data *construct_seen = nullptr;
  cp_omp_attribute_data *standalone_seen = nullptr;
  cp_omp_attribute_data *prev_standalone_seen = nullptr;
  FOR_EACH_VEC_ELT (vec, i, v)
    if (v->tokens)
      {
	if (v->kind == C_OMP_DIR_CONSTRUCT && !construct_seen)
	  construct_seen = v;
	else if (v->kind == C_OMP_DIR_STANDALONE && !standalone_seen)
	  standalone_seen = v;
      }
    else
      {
	if (standalone_seen && !prev_standalone_seen)
	  {
	    prev_standalone_seen = standalone_seen;
	    standalone_seen = nullptr;
	  }
      }

  if (cnt > 1 && construct_seen)
    {
      error_at (construct_seen->tokens->first->location,
		"OpenMP construct among %<omp::directive%> attributes"
		" requires all %<omp::directive%> attributes on the"
		" same statement to be in the same %<omp::sequence%>");
      return attrs;
    }
  if (cnt > 1 && standalone_seen && prev_standalone_seen)
    {
      error_at (standalone_seen->tokens->first->location,
		"multiple OpenMP standalone directives among"
		" %<omp::directive%> attributes must be all within the"
		" same %<omp::sequence%>");
      return attrs;
    }

  if (prev_standalone_seen)
    standalone_seen = prev_standalone_seen;
  if (standalone_seen
      && !cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    {
      error_at (standalone_seen->tokens->first->location,
		"standalone OpenMP directives in %<omp::directive%> attribute"
		" can only appear on an empty statement");
      return attrs;
    }
  if (cnt && cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);
      enum pragma_kind kind = cp_parser_pragma_kind (token);
      if (kind >= PRAGMA_OMP__START_ && kind <= PRAGMA_OMP__LAST_)
	{
	  error_at (token->location,
		    "mixing OpenMP directives with attribute and pragma "
		    "syntax on the same statement");
	  return attrs;
	}
    }

  if (!tokens)
    return attrs;
  tokens++;
  cp_lexer *lexer = cp_lexer_alloc ();
  lexer->debugging_p = parser->lexer->debugging_p;
  vec_safe_reserve (lexer->buffer, tokens, true);
  FOR_EACH_VEC_ELT (vec, i, v)
    {
      if (!v->tokens)
	continue;
      if (!flag_openmp && !v->dir->simd)
	continue;
      cp_token *first = v->tokens->first;
      cp_token *last = v->tokens->last;
      cp_token tok = {};
      tok.type = CPP_PRAGMA;
      tok.keyword = RID_MAX;
      tok.u.value = build_int_cst (NULL, v->dir->id);
      tok.location = first->location;
      lexer->buffer->quick_push (tok);
      while (++first < last)
	lexer->buffer->quick_push (*first);
      tok = {};
      tok.type = CPP_PRAGMA_EOL;
      tok.keyword = RID_MAX;
      tok.location = last->location;
      lexer->buffer->quick_push (tok);
    }
  cp_token tok = {};
  tok.type = CPP_EOF;
  tok.keyword = RID_MAX;
  tok.location = lexer->buffer->last ().location;
  lexer->buffer->quick_push (tok);
  lexer->next = parser->lexer;
  lexer->next_token = lexer->buffer->address ();
  lexer->last_token = lexer->next_token
		      + lexer->buffer->length ()
		      - 1;
  lexer->in_omp_attribute_pragma = true;
  parser->lexer = lexer;
  /* Move the current source position to that of the first token in the
     new lexer.  */
  cp_lexer_set_source_position_from_token (lexer->next_token);
  return attrs;
}

/* True if and only if the name is one of the contract types.  */

static bool
contract_attribute_p (const_tree id)
{
  return is_attribute_p ("assert", id)
    || is_attribute_p ("pre", id)
    || is_attribute_p ("post", id);
}

/* Handle omp::directive and omp::sequence attributes in *PATTRS
   (if any) at the start or after declaration-id of a declaration.  */

static void
cp_parser_handle_directive_omp_attributes (cp_parser *parser, tree *pattrs,
					   cp_omp_declare_simd_data *data,
					   bool start)
{
  if (!flag_openmp && !flag_openmp_simd)
    return;

  int cnt = 0;
  bool bad = false;
  bool variant_p = false;
  location_t loc = UNKNOWN_LOCATION;
  for (tree pa = *pattrs; pa; pa = TREE_CHAIN (pa))
    if (get_attribute_namespace (pa) == omp_identifier
	&& is_attribute_p ("directive", get_attribute_name (pa)))
      {
	for (tree a = TREE_VALUE (pa); a; a = TREE_CHAIN (a))
	  {
	    tree d = TREE_VALUE (a);
	    gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
	    cp_token *first = DEFPARSE_TOKENS (d)->first;
	    cp_token *last = DEFPARSE_TOKENS (d)->last;
	    const char *directive[3] = {};
	    for (int i = 0; i < 3; i++)
	      {
		tree id = NULL_TREE;
		if (first + i == last)
		  break;
		if (first[i].type == CPP_NAME)
		  id = first[i].u.value;
		else if (first[i].type == CPP_KEYWORD)
		  id = ridpointers[(int) first[i].keyword];
		else
		  break;
		directive[i] = IDENTIFIER_POINTER (id);
	      }
	    const c_omp_directive *dir = NULL;
	    if (directive[0])
	      dir = c_omp_categorize_directive (directive[0], directive[1],
						directive[2]);
	    if (dir == NULL)
	      continue;
	    if (dir->id == PRAGMA_OMP_DECLARE
		&& (strcmp (directive[1], "simd") == 0
		    || strcmp (directive[1], "variant") == 0))
	      {
		if (cnt++ == 0)
		  {
		    variant_p = strcmp (directive[1], "variant") == 0;
		    loc = first->location;
		  }
		if (start && parser->omp_declare_simd && !bad)
		  {
		    error_at (first->location,
			      "mixing OpenMP directives with attribute and "
			      "pragma syntax on the same declaration");
		    bad = true;
		  }
	      }
	  }
      }

  if (bad)
    {
      for (tree *pa = pattrs; *pa; )
	if (get_attribute_namespace (*pa) == omp_identifier
	    && is_attribute_p ("directive", get_attribute_name (*pa)))
	  *pa = TREE_CHAIN (*pa);
	else
	  pa = &TREE_CHAIN (*pa);
      return;
    }
  if (cnt == 0)
    return;

  if (parser->omp_declare_simd == NULL)
    {
      data->error_seen = false;
      data->fndecl_seen = false;
      data->variant_p = variant_p;
      data->loc = loc;
      data->tokens = vNULL;
      data->attribs[0] = NULL;
      data->attribs[1] = NULL;
      parser->omp_declare_simd = data;
    }
  parser->omp_declare_simd->attribs[!start] = pattrs;
}

/* Parse a statement.

   statement:
     labeled-statement
     expression-statement
     compound-statement
     selection-statement
     iteration-statement
     jump-statement
     declaration-statement
     try-block

  C++11:

  statement:
    labeled-statement
    attribute-specifier-seq (opt) expression-statement
    attribute-specifier-seq (opt) compound-statement
    attribute-specifier-seq (opt) selection-statement
    attribute-specifier-seq (opt) iteration-statement
    attribute-specifier-seq (opt) jump-statement
    declaration-statement
    attribute-specifier-seq (opt) try-block

  init-statement:
    expression-statement
    simple-declaration
    alias-declaration

  TM Extension:

   statement:
     atomic-statement

  IN_COMPOUND is true when the statement is nested inside a
  cp_parser_compound_statement.

  If IF_P is not NULL, *IF_P is set to indicate whether the statement
  is a (possibly labeled) if statement which is not enclosed in braces
  and has an else clause.  This is used to implement -Wparentheses.

  CHAIN is a vector of if-else-if conditions.

  Note that this version of parsing restricts assertions to be attached to
  empty statements. */

static void
cp_parser_statement (cp_parser* parser, tree in_statement_expr,
		     const bool in_compound, bool *if_p, vec<tree> *chain,
		     location_t *loc_after_labels)
{
  tree statement, std_attrs = NULL_TREE;
  cp_token *token;
  location_t statement_location, attrs_loc;
  bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
  bool has_std_attrs;
  /* A copy of IN_COMPOUND which is set to false after seeing a label.
     This matters for certain pragmas.  */
  bool in_compound_for_pragma = in_compound;

 restart:
  if (if_p != NULL)
    *if_p = false;
  /* There is no statement yet.  */
  statement = NULL_TREE;

  saved_token_sentinel saved_tokens (parser->lexer);
  token = cp_lexer_peek_token (parser->lexer);
  attrs_loc = token->location;
  if (c_dialect_objc ())
    /* In obj-c++, seeing '[[' might be the either the beginning of
       c++11 attributes, or a nested objc-message-expression.  So
       let's parse the c++11 attributes tentatively.  */
    cp_parser_parse_tentatively (parser);
  std_attrs = cp_parser_std_attribute_spec_seq (parser);
  if (std_attrs)
    attrs_loc = make_location (attrs_loc, attrs_loc, parser->lexer);
  if (c_dialect_objc ())
    {
      if (!cp_parser_parse_definitely (parser))
	std_attrs = NULL_TREE;
    }
  has_std_attrs = cp_lexer_peek_token (parser->lexer) != token;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* If we have contracts, check that they're valid in this context.  */
  if (std_attrs != error_mark_node)
    {
      if (tree pre = lookup_attribute ("pre", std_attrs))
	error_at (EXPR_LOCATION (TREE_VALUE (pre)),
		  "preconditions cannot be statements");
      else if (tree post = lookup_attribute ("post", std_attrs))
	error_at (EXPR_LOCATION (TREE_VALUE (post)),
		  "postconditions cannot be statements");

    /* Check that assertions are null statements.  */
    if (cp_contract_assertion_p (std_attrs))
      if (token->type != CPP_SEMICOLON)
	error_at (token->location, "assertions must be followed by %<;%>");
    }

  bool omp_attrs_forbidden_p;
  omp_attrs_forbidden_p = parser->omp_attrs_forbidden_p;

  if (std_attrs && (flag_openmp || flag_openmp_simd))
    {
      bool handle_omp_attribs = false;
      if (token->type == CPP_KEYWORD)
	switch (token->keyword)
	  {
	  case RID_IF:
	  case RID_SWITCH:
	  case RID_WHILE:
	  case RID_DO:
	  case RID_FOR:
	  case RID_BREAK:
	  case RID_CONTINUE:
	  case RID_RETURN:
	  case RID_CO_RETURN:
	  case RID_GOTO:
	  case RID_AT_TRY:
	  case RID_AT_CATCH:
	  case RID_AT_FINALLY:
	  case RID_AT_SYNCHRONIZED:
	  case RID_AT_THROW:
	  case RID_TRY:
	  case RID_TRANSACTION_ATOMIC:
	  case RID_TRANSACTION_RELAXED:
	  case RID_SYNCHRONIZED:
	  case RID_ATOMIC_NOEXCEPT:
	  case RID_ATOMIC_CANCEL:
	  case RID_TRANSACTION_CANCEL:
	    handle_omp_attribs = true;
	    break;
	  default:
	    break;
	  }
      else if (token->type == CPP_SEMICOLON
	       || token->type == CPP_OPEN_BRACE
	       || token->type == CPP_PRAGMA)
	handle_omp_attribs = true;
      if (handle_omp_attribs)
	{
	  std_attrs = cp_parser_handle_statement_omp_attributes (parser,
								 std_attrs);
	  token = cp_lexer_peek_token (parser->lexer);
	}
    }
  parser->omp_attrs_forbidden_p = false;

  /* Remember the location of the first token in the statement.  */
  cp_token *statement_token = token;
  statement_location = token->location;
  add_debug_begin_stmt (statement_location);
  /* If this is a keyword, then that will often determine what kind of
     statement we have.  */
  if (token->type == CPP_KEYWORD)
    {
      enum rid keyword = token->keyword;

      switch (keyword)
	{
	case RID_CASE:
	case RID_DEFAULT:
	  /* Looks like a labeled-statement with a case label.
	     Parse the label, and then use tail recursion to parse
	     the statement.  */
	  cp_parser_label_for_labeled_statement (parser, std_attrs);
	  in_compound_for_pragma = false;
	  in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
	  goto restart;

	case RID_IF:
	case RID_SWITCH:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_selection_statement (parser, if_p, chain);
	  break;

	case RID_WHILE:
	case RID_DO:
	case RID_FOR:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_iteration_statement (parser, if_p, false, 0);
	  break;

	case RID_BREAK:
	case RID_CONTINUE:
	case RID_RETURN:
	case RID_CO_RETURN:
	case RID_GOTO:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_jump_statement (parser);
	  break;

	  /* Objective-C++ exception-handling constructs.  */
	case RID_AT_TRY:
	case RID_AT_CATCH:
	case RID_AT_FINALLY:
	case RID_AT_SYNCHRONIZED:
	case RID_AT_THROW:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_objc_statement (parser);
	  break;

	case RID_TRY:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_try_block (parser);
	  break;

	case RID_NAMESPACE:
	  /* This must be a namespace alias definition.  */
	  if (has_std_attrs)
	    {
	      /* Attributes should be parsed as part of the
		 declaration, so let's un-parse them.  */
	      saved_tokens.rollback();
	      std_attrs = NULL_TREE;
	    }
	  cp_parser_declaration_statement (parser);
	  return;

	case RID_TRANSACTION_ATOMIC:
	case RID_TRANSACTION_RELAXED:
	case RID_SYNCHRONIZED:
	case RID_ATOMIC_NOEXCEPT:
	case RID_ATOMIC_CANCEL:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_transaction (parser, token);
	  break;
	case RID_TRANSACTION_CANCEL:
	  std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
	  statement = cp_parser_transaction_cancel (parser);
	  break;

	default:
	  /* It might be a keyword like `int' that can start a
	     declaration-statement.  */
	  break;
	}
    }
  else if (token->type == CPP_NAME)
    {
      /* If the next token is a `:', then we are looking at a
	 labeled-statement.  */
      token = cp_lexer_peek_nth_token (parser->lexer, 2);
      if (token->type == CPP_COLON)
	{
	  /* Looks like a labeled-statement with an ordinary label.
	     Parse the label, and then use tail recursion to parse
	     the statement.  */

	  cp_parser_label_for_labeled_statement (parser, std_attrs);

	  /* If there's no statement, it's not a labeled-statement, just
	     a label.  That's allowed in C++23, but only if we're at the
	     end of a compound-statement.  */
	  if (in_compound
	      && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
	    {
	      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
	      if (cxx_dialect < cxx23)
		pedwarn (loc, OPT_Wc__23_extensions,
			 "label at end of compound statement only available "
			 "with %<-std=c++2b%> or %<-std=gnu++2b%>");
	      return;
	    }
	  in_compound_for_pragma = false;
	  in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
	  goto restart;
	}
    }
  /* Anything that starts with a `{' must be a compound-statement.  */
  else if (token->type == CPP_OPEN_BRACE)
    {
      std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
      statement = cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
    }
  /* CPP_PRAGMA is a #pragma inside a function body, which constitutes
     a statement all its own.  */
  else if (token->type == CPP_PRAGMA)
    {
     do_pragma:;
      cp_lexer *lexer = parser->lexer;
      bool do_restart = false;
      /* Only certain OpenMP pragmas are attached to statements, and thus
	 are considered statements themselves.  All others are not.  In
	 the context of a compound, accept the pragma as a "statement" and
	 return so that we can check for a close brace.  Otherwise we
	 require a real statement and must go back and read one.  */
      if (in_compound_for_pragma)
	cp_parser_pragma (parser, pragma_compound, if_p);
      else if (!cp_parser_pragma (parser, pragma_stmt, if_p))
	do_restart = true;
      if (parser->lexer != lexer
	  && lexer->in_omp_attribute_pragma
	  && (!in_omp_attribute_pragma || lexer->orphan_p))
	{
	  if (saved_tokens.lexer == lexer)
	    {
	      if (saved_tokens.mode == STS_COMMIT)
		cp_lexer_commit_tokens (lexer);
	      gcc_assert (lexer->saved_tokens.length () == saved_tokens.len);
	      saved_tokens.lexer = parser->lexer;
	      saved_tokens.mode = STS_DONOTHING;
	      saved_tokens.len = parser->lexer->saved_tokens.length ();
	    }
	  cp_lexer_destroy (lexer);
	  lexer = parser->lexer;
	}
      if (do_restart)
	goto restart;
      if (parser->lexer == lexer
	  && lexer->in_omp_attribute_pragma
	  && !in_omp_attribute_pragma)
	parser->lexer->orphan_p = true;
      return;
    }
  else if (token->type == CPP_EOF)
    {
      cp_parser_error (parser, "expected statement");
      return;
    }

  /* Everything else must be a declaration-statement or an
     expression-statement.  Try for the declaration-statement
     first, unless we are looking at a `;', in which case we know that
     we have an expression-statement.  */
  if (!statement)
    {
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	{
	  if (has_std_attrs)
	    /* Attributes should be parsed as part of the declaration,
	       so let's un-parse them.  */
	    saved_tokens.rollback();

	  parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
	  cp_parser_parse_tentatively (parser);
	  /* Try to parse the declaration-statement.  */
	  cp_parser_declaration_statement (parser);
	  parser->omp_attrs_forbidden_p = false;
	  /* If that worked, we're done.  */
	  if (cp_parser_parse_definitely (parser))
	    return;
	  /* It didn't work, restore the post-attribute position.  */
	  if (has_std_attrs)
	    {
	      cp_lexer_set_token_position (parser->lexer, statement_token);
	      if (flag_openmp || flag_openmp_simd)
		{
		  size_t i = 1;
		  bool handle_omp_attribs = true;
		  while (cp_lexer_peek_nth_token (parser->lexer, i)->keyword
			 == RID_EXTENSION)
		    i++;
		  switch (cp_lexer_peek_nth_token (parser->lexer, i)->keyword)
		    {
		    case RID_ASM:
		    case RID_NAMESPACE:
		    case RID_USING:
		    case RID_LABEL:
		    case RID_STATIC_ASSERT:
		      /* Don't handle OpenMP attribs on keywords that
			 always start a declaration statement but don't
			 accept attribute before it and therefore
			 the tentative cp_parser_declaration_statement
			 fails to parse because of that.  */
		      handle_omp_attribs = false;
		      break;
		    default:
		      break;
		    }

		  if (handle_omp_attribs)
		    {
		      parser->omp_attrs_forbidden_p = omp_attrs_forbidden_p;
		      std_attrs
			= cp_parser_handle_statement_omp_attributes
					(parser, std_attrs);
		      parser->omp_attrs_forbidden_p = false;
		      token = cp_lexer_peek_token (parser->lexer);
		      if (token->type == CPP_PRAGMA)
			goto do_pragma;
		    }
		}
	    }
	}
      /* All preceding labels have been parsed at this point.  */
      if (loc_after_labels != NULL)
	*loc_after_labels = statement_location;

      std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);

      /* Look for an expression-statement instead.  */
      statement = cp_parser_expression_statement (parser, in_statement_expr);

      std_attrs = process_stmt_assume_attribute (std_attrs, statement,
						 attrs_loc);

      /* Handle [[fallthrough]];.  */
      if (attribute_fallthrough_p (std_attrs))
	{
	  /* The next token after the fallthrough attribute is ';'.  */
	  if (statement == NULL_TREE)
	    {
	      /* Turn [[fallthrough]]; into FALLTHROUGH ();.  */
	      statement = build_call_expr_internal_loc (statement_location,
							IFN_FALLTHROUGH,
							void_type_node, 0);
	      finish_expr_stmt (statement);
	    }
	  else
	    warning_at (statement_location, OPT_Wattributes,
			"%<fallthrough%> attribute not followed by %<;%>");
	  std_attrs = NULL_TREE;
	}

      /* Handle [[assert: ...]];  */
      if (cp_contract_assertion_p (std_attrs))
	{
	  /* Add the assertion as a statement in the current block.  */
	  gcc_assert (!statement || statement == error_mark_node);
	  emit_assertion (std_attrs);
	  std_attrs = NULL_TREE;
	}
    }

  /* Set the line number for the statement.  */
  if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
    SET_EXPR_LOCATION (statement, statement_location);

  /* Allow "[[fallthrough]];" or "[[assume(cond)]];", but warn otherwise.  */
  if (std_attrs != NULL_TREE)
    warning_at (attrs_loc,
		OPT_Wattributes,
		"attributes at the beginning of statement are ignored");
}

/* Append ATTR to attribute list ATTRS.  */

tree
attr_chainon (tree attrs, tree attr)
{
  if (attrs == error_mark_node)
    return error_mark_node;
  if (attr == error_mark_node)
    return error_mark_node;
  return chainon (attrs, attr);
}

/* Parse the label for a labeled-statement, i.e.

   label:
     attribute-specifier-seq[opt] identifier :
     attribute-specifier-seq[opt] case constant-expression :
     attribute-specifier-seq[opt] default :

   labeled-statement:
     label statement

   GNU Extension:
   case constant-expression ... constant-expression : statement

   When a label is parsed without errors, the label is added to the
   parse tree by the finish_* functions, so this function doesn't
   have to return the label.  */

static void
cp_parser_label_for_labeled_statement (cp_parser* parser, tree attributes)
{
  cp_token *token;
  tree label = NULL_TREE;
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;

  /* The next token should be an identifier.  */
  token = cp_lexer_peek_token (parser->lexer);
  if (token->type != CPP_NAME
      && token->type != CPP_KEYWORD)
    {
      cp_parser_error (parser, "expected labeled-statement");
      return;
    }

  /* Remember whether this case or a user-defined label is allowed to fall
     through to.  */
  bool fallthrough_p = token->flags & PREV_FALLTHROUGH;

  parser->colon_corrects_to_scope_p = false;
  switch (token->keyword)
    {
    case RID_CASE:
      {
	tree expr, expr_hi;
	cp_token *ellipsis;

	/* Consume the `case' token.  */
	cp_lexer_consume_token (parser->lexer);
	/* Parse the constant-expression.  */
	expr = cp_parser_constant_expression (parser);
	if (check_for_bare_parameter_packs (expr))
	  expr = error_mark_node;

	ellipsis = cp_lexer_peek_token (parser->lexer);
	if (ellipsis->type == CPP_ELLIPSIS)
	  {
	    /* Consume the `...' token.  */
	    cp_lexer_consume_token (parser->lexer);
	    expr_hi = cp_parser_constant_expression (parser);
	    if (check_for_bare_parameter_packs (expr_hi))
	      expr_hi = error_mark_node;

	    /* We don't need to emit warnings here, as the common code
	       will do this for us.  */
	  }
	else
	  expr_hi = NULL_TREE;

	if (parser->in_switch_statement_p)
	  {
	    tree l = finish_case_label (token->location, expr, expr_hi);
	    if (l && TREE_CODE (l) == CASE_LABEL_EXPR)
	      {
		label = CASE_LABEL (l);
		FALLTHROUGH_LABEL_P (label) = fallthrough_p;
	      }
	  }
	else
	  error_at (token->location,
		    "case label %qE not within a switch statement",
		    expr);
      }
      break;

    case RID_DEFAULT:
      /* Consume the `default' token.  */
      cp_lexer_consume_token (parser->lexer);

      if (parser->in_switch_statement_p)
	{
	  tree l = finish_case_label (token->location, NULL_TREE, NULL_TREE);
	  if (l && TREE_CODE (l) == CASE_LABEL_EXPR)
	      {
		label = CASE_LABEL (l);
		FALLTHROUGH_LABEL_P (label) = fallthrough_p;
	      }
	}
      else
	error_at (token->location, "case label not within a switch statement");
      break;

    default:
      /* Anything else must be an ordinary label.  */
      label = finish_label_stmt (cp_parser_identifier (parser));
      if (label && TREE_CODE (label) == LABEL_DECL)
	FALLTHROUGH_LABEL_P (label) = fallthrough_p;
      break;
    }

  /* Require the `:' token.  */
  cp_parser_require (parser, CPP_COLON, RT_COLON);

  /* An ordinary label may optionally be followed by attributes.
     However, this is only permitted if the attributes are then
     followed by a semicolon.  This is because, for backward
     compatibility, when parsing
       lab: __attribute__ ((unused)) int i;
     we want the attribute to attach to "i", not "lab".  */
  if (label != NULL_TREE
      && cp_next_tokens_can_be_gnu_attribute_p (parser))
    {
      tree attrs;
      cp_parser_parse_tentatively (parser);
      attrs = cp_parser_gnu_attributes_opt (parser);
      if (attrs == NULL_TREE
	  /* And fallthrough always binds to the expression-statement.  */
	  || attribute_fallthrough_p (attrs)
	  || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	cp_parser_abort_tentative_parse (parser);
      else if (!cp_parser_parse_definitely (parser))
	;
      else
	attributes = attr_chainon (attributes, attrs);
    }

  if (attributes != NULL_TREE)
    cplus_decl_attributes (&label, attributes, 0);

  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
}

/* Parse an expression-statement.

   expression-statement:
     expression [opt] ;

   Returns the new EXPR_STMT -- or NULL_TREE if the expression
   statement consists of nothing more than an `;'. IN_STATEMENT_EXPR_P
   indicates whether this expression-statement is part of an
   expression statement.  */

static tree
cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
{
  tree statement = NULL_TREE;
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  location_t loc = token->location;

  /* There might be attribute fallthrough.  */
  tree attr = cp_parser_gnu_attributes_opt (parser);

  /* If the next token is a ';', then there is no expression
     statement.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    {
      statement = cp_parser_expression (parser);
      if (statement == error_mark_node
	  && !cp_parser_uncommitted_to_tentative_parse_p (parser))
	{
	  cp_parser_skip_to_end_of_block_or_statement (parser);
	  return error_mark_node;
	}
    }

  attr = process_stmt_assume_attribute (attr, statement, loc);

  /* Handle [[fallthrough]];.  */
  if (attribute_fallthrough_p (attr))
    {
      /* The next token after the fallthrough attribute is ';'.  */
      if (statement == NULL_TREE)
	/* Turn [[fallthrough]]; into FALLTHROUGH ();.  */
	statement = build_call_expr_internal_loc (loc, IFN_FALLTHROUGH,
						  void_type_node, 0);
      else
	warning_at (loc, OPT_Wattributes,
		    "%<fallthrough%> attribute not followed by %<;%>");
      attr = NULL_TREE;
    }

  /* Allow "[[fallthrough]];", but warn otherwise.  */
  if (attr != NULL_TREE)
    warning_at (loc, OPT_Wattributes,
		"attributes at the beginning of statement are ignored");

  /* Give a helpful message for "A<T>::type t;" and the like.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
      && !cp_parser_uncommitted_to_tentative_parse_p (parser))
    {
      if (TREE_CODE (statement) == SCOPE_REF)
	error_at (token->location, "need %<typename%> before %qE because "
		  "%qT is a dependent scope",
		  statement, TREE_OPERAND (statement, 0));
      else if (is_overloaded_fn (statement)
	       && DECL_CONSTRUCTOR_P (get_first_fn (statement)))
	{
	  /* A::A a; */
	  tree fn = get_first_fn (statement);
	  error_at (token->location,
		    "%<%T::%D%> names the constructor, not the type",
		    DECL_CONTEXT (fn), DECL_NAME (fn));
	}
    }

  /* Consume the final `;'.  */
  cp_parser_consume_semicolon_at_end_of_statement (parser);

  if (in_statement_expr
      && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
    /* This is the final expression statement of a statement
       expression.  */
    statement = finish_stmt_expr_expr (statement, in_statement_expr);
  else if (statement)
    statement = finish_expr_stmt (statement);

  return statement;
}

/* Parse a compound-statement.

   compound-statement:
     { statement-seq [opt] label-seq [opt] }

   label-seq:
     label
     label-seq label

   GNU extension:

   compound-statement:
     { label-declaration-seq [opt] statement-seq [opt] }

   label-declaration-seq:
     label-declaration
     label-declaration-seq label-declaration

   Returns a tree representing the statement.  */

static tree
cp_parser_compound_statement (cp_parser *parser, tree in_statement_expr,
			      int bcs_flags, bool function_body)
{
  tree compound_stmt;
  matching_braces braces;

  /* Consume the `{'.  */
  if (!braces.require_open (parser))
    return error_mark_node;
  if (DECL_DECLARED_CONSTEXPR_P (current_function_decl)
      && !function_body && cxx_dialect < cxx14)
    pedwarn (input_location, OPT_Wpedantic,
	     "compound-statement in %<constexpr%> function");
  /* Begin the compound-statement.  */
  compound_stmt = begin_compound_stmt (bcs_flags);
  /* If the next keyword is `__label__' we have a label declaration.  */
  while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
    cp_parser_label_declaration (parser);
  /* Parse an (optional) statement-seq.  */
  cp_parser_statement_seq_opt (parser, in_statement_expr);

  /* Consume the `}'.  */
  braces.require_close (parser);

  /* Finish the compound-statement.  */
  finish_compound_stmt (compound_stmt);

  return compound_stmt;
}

/* Parse an (optional) statement-seq.

   statement-seq:
     statement
     statement-seq [opt] statement  */

static void
cp_parser_statement_seq_opt (cp_parser* parser, tree in_statement_expr)
{
  /* Scan statements until there aren't any more.  */
  while (true)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      /* If we are looking at a `}', then we have run out of
	 statements; the same is true if we have reached the end
	 of file, or have stumbled upon a stray '@end'.  */
      if (token->type == CPP_CLOSE_BRACE
	  || token->type == CPP_EOF
	  || token->type == CPP_PRAGMA_EOL
	  || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END))
	break;

      /* If we are in a compound statement and find 'else' then
	 something went wrong.  */
      else if (token->type == CPP_KEYWORD && token->keyword == RID_ELSE)
	{
	  if (parser->in_statement & IN_IF_STMT)
	    break;
	  else
	    {
	      token = cp_lexer_consume_token (parser->lexer);
	      error_at (token->location, "%<else%> without a previous %<if%>");
	    }
	}

      /* Parse the statement.  */
      cp_parser_statement (parser, in_statement_expr, true, NULL);
    }
}

/* Return true if this is the C++20 version of range-based-for with
   init-statement.  */

static bool
cp_parser_range_based_for_with_init_p (cp_parser *parser)
{
  bool r = false;

  /* Save tokens so that we can put them back.  */
  cp_lexer_save_tokens (parser->lexer);

  /* There has to be an unnested ; followed by an unnested :.  */
  if (cp_parser_skip_to_closing_parenthesis_1 (parser,
					       /*recovering=*/false,
					       CPP_SEMICOLON,
					       /*consume_paren=*/false) != -1)
    goto out;

  /* We found the semicolon, eat it now.  */
  cp_lexer_consume_token (parser->lexer);

  /* Now look for ':' that is not nested in () or {}.  */
  r = (cp_parser_skip_to_closing_parenthesis_1 (parser,
						/*recovering=*/false,
						CPP_COLON,
						/*consume_paren=*/false) == -1);

out:
  /* Roll back the tokens we skipped.  */
  cp_lexer_rollback_tokens (parser->lexer);

  return r;
}

/* Return true if we're looking at (init; cond), false otherwise.  */

static bool
cp_parser_init_statement_p (cp_parser *parser)
{
  /* Save tokens so that we can put them back.  */
  cp_lexer_save_tokens (parser->lexer);

  /* Look for ';' that is not nested in () or {}.  */
  int ret = cp_parser_skip_to_closing_parenthesis_1 (parser,
						     /*recovering=*/false,
						     CPP_SEMICOLON,
						     /*consume_paren=*/false);

  /* Roll back the tokens we skipped.  */
  cp_lexer_rollback_tokens (parser->lexer);

  return ret == -1;
}

/* Parse a selection-statement.

   selection-statement:
     if ( init-statement [opt] condition ) statement
     if ( init-statement [opt] condition ) statement else statement
     switch ( init-statement [opt] condition ) statement

   Returns the new IF_STMT or SWITCH_STMT.

   If IF_P is not NULL, *IF_P is set to indicate whether the statement
   is a (possibly labeled) if statement which is not enclosed in
   braces and has an else clause.  This is used to implement
   -Wparentheses.

   CHAIN is a vector of if-else-if conditions.  This is used to implement
   -Wduplicated-cond.  */

static tree
cp_parser_selection_statement (cp_parser* parser, bool *if_p,
			       vec<tree> *chain)
{
  cp_token *token;
  enum rid keyword;
  token_indent_info guard_tinfo;

  if (if_p != NULL)
    *if_p = false;

  /* Peek at the next token.  */
  token = cp_parser_require (parser, CPP_KEYWORD, RT_SELECT);
  guard_tinfo = get_token_indent_info (token);

  /* See what kind of keyword it is.  */
  keyword = token->keyword;
  switch (keyword)
    {
    case RID_IF:
    case RID_SWITCH:
      {
	tree statement;
	tree condition;

	bool cx = false;
	if (keyword == RID_IF
	    && cp_lexer_next_token_is_keyword (parser->lexer,
					       RID_CONSTEXPR))
	  {
	    cx = true;
	    cp_token *tok = cp_lexer_consume_token (parser->lexer);
	    if (cxx_dialect < cxx17)
	      pedwarn (tok->location, OPT_Wc__17_extensions,
		       "%<if constexpr%> only available with "
		       "%<-std=c++17%> or %<-std=gnu++17%>");
	  }
	int ce = 0;
	if (keyword == RID_IF && !cx)
	  {
	    if (cp_lexer_next_token_is_keyword (parser->lexer,
						RID_CONSTEVAL))
	      ce = 1;
	    else if (cp_lexer_next_token_is (parser->lexer, CPP_NOT)
		     && cp_lexer_nth_token_is_keyword (parser->lexer, 2,
						       RID_CONSTEVAL))
	      {
		ce = -1;
		cp_lexer_consume_token (parser->lexer);
	      }
	  }
	if (ce)
	  {
	    cp_token *tok = cp_lexer_consume_token (parser->lexer);
	    if (cxx_dialect < cxx23)
	      pedwarn (tok->location, OPT_Wc__23_extensions,
		       "%<if consteval%> only available with "
		       "%<-std=c++2b%> or %<-std=gnu++2b%>");

	    bool save_in_consteval_if_p = in_consteval_if_p;
	    statement = begin_if_stmt ();
	    IF_STMT_CONSTEVAL_P (statement) = true;
	    condition = finish_if_stmt_cond (boolean_false_node, statement);

	    gcc_rich_location richloc (tok->location);
	    bool non_compound_stmt_p = false;
	    if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
	      {
		non_compound_stmt_p = true;
		richloc.add_fixit_insert_after (tok->location, "{");
	      }

	    in_consteval_if_p |= ce > 0;
	    cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);

	    if (non_compound_stmt_p)
	      {
		location_t before_loc
		  = cp_lexer_peek_token (parser->lexer)->location;
		richloc.add_fixit_insert_before (before_loc, "}");
		error_at (&richloc,
			  "%<if consteval%> requires compound statement");
		non_compound_stmt_p = false;
	      }

	    finish_then_clause (statement);

	    /* If the next token is `else', parse the else-clause.  */
	    if (cp_lexer_next_token_is_keyword (parser->lexer,
						RID_ELSE))
	      {
		cp_token *else_tok = cp_lexer_peek_token (parser->lexer);
		gcc_rich_location else_richloc (else_tok->location);
		guard_tinfo = get_token_indent_info (else_tok);
		/* Consume the `else' keyword.  */
		cp_lexer_consume_token (parser->lexer);

		begin_else_clause (statement);

		if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
		  {
		    non_compound_stmt_p = true;
		    else_richloc.add_fixit_insert_after (else_tok->location,
							 "{");
		  }

		in_consteval_if_p = save_in_consteval_if_p | (ce < 0);
		cp_parser_implicitly_scoped_statement (parser, NULL,
						       guard_tinfo);

		if (non_compound_stmt_p)
		  {
		    location_t before_loc
		      = cp_lexer_peek_token (parser->lexer)->location;
		    else_richloc.add_fixit_insert_before (before_loc, "}");
		    error_at (&else_richloc,
			      "%<if consteval%> requires compound statement");
		  }

		finish_else_clause (statement);
	      }

	    in_consteval_if_p = save_in_consteval_if_p;
	    if (ce < 0)
	      {
		std::swap (THEN_CLAUSE (statement), ELSE_CLAUSE (statement));
		if (THEN_CLAUSE (statement) == NULL_TREE)
		  THEN_CLAUSE (statement) = build_empty_stmt (tok->location);
	      }

	    finish_if_stmt (statement);
	    return statement;
	  }

	/* Look for the `('.  */
	matching_parens parens;
	if (!parens.require_open (parser))
	  {
	    cp_parser_skip_to_end_of_statement (parser);
	    return error_mark_node;
	  }

	/* Begin the selection-statement.  */
	if (keyword == RID_IF)
	  {
	    statement = begin_if_stmt ();
	    IF_STMT_CONSTEXPR_P (statement) = cx;
	  }
	else
	  statement = begin_switch_stmt ();

	/* Parse the optional init-statement.  */
	if (cp_parser_init_statement_p (parser))
	  {
	    tree decl;
	    if (cxx_dialect < cxx17)
	      pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		       OPT_Wc__17_extensions,
		       "init-statement in selection statements only available "
		       "with %<-std=c++17%> or %<-std=gnu++17%>");
	    if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	      /* A non-empty init-statement can have arbitrary side
		 effects.  */
	      vec_free (chain);
	    cp_parser_init_statement (parser, &decl);
	  }

	/* Parse the condition.  */
	condition = cp_parser_condition (parser);
	/* Look for the `)'.  */
	if (!parens.require_close (parser))
	  cp_parser_skip_to_closing_parenthesis (parser, true, false,
						 /*consume_paren=*/true);

	if (keyword == RID_IF)
	  {
	    bool nested_if;
	    unsigned char in_statement;

	    /* Add the condition.  */
	    condition = finish_if_stmt_cond (condition, statement);

	    if (warn_duplicated_cond)
	      warn_duplicated_cond_add_or_warn (token->location, condition,
						&chain);

	    /* Parse the then-clause.  */
	    in_statement = parser->in_statement;
	    parser->in_statement |= IN_IF_STMT;

	    /* Outside a template, the non-selected branch of a constexpr
	       if is a 'discarded statement', i.e. unevaluated.  */
	    bool was_discarded = in_discarded_stmt;
	    bool discard_then = (cx && !processing_template_decl
				 && integer_zerop (condition));
	    if (discard_then)
	      {
		in_discarded_stmt = true;
		++c_inhibit_evaluation_warnings;
	      }

	    cp_parser_implicitly_scoped_statement (parser, &nested_if,
						   guard_tinfo);

	    parser->in_statement = in_statement;

	    finish_then_clause (statement);

	    if (discard_then)
	      {
		THEN_CLAUSE (statement) = NULL_TREE;
		in_discarded_stmt = was_discarded;
		--c_inhibit_evaluation_warnings;
	      }

	    /* If the next token is `else', parse the else-clause.  */
	    if (cp_lexer_next_token_is_keyword (parser->lexer,
						RID_ELSE))
	      {
		bool discard_else = (cx && !processing_template_decl
				     && integer_nonzerop (condition));
		if (discard_else)
		  {
		    in_discarded_stmt = true;
		    ++c_inhibit_evaluation_warnings;
		  }

		guard_tinfo
		  = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
		/* Consume the `else' keyword.  */
		cp_lexer_consume_token (parser->lexer);
		if (warn_duplicated_cond)
		  {
		    if (cp_lexer_next_token_is_keyword (parser->lexer,
							RID_IF)
			&& chain == NULL)
		      {
			/* We've got "if (COND) else if (COND2)".  Start
			   the condition chain and add COND as the first
			   element.  */
			chain = new vec<tree> ();
			if (!CONSTANT_CLASS_P (condition)
			    && !TREE_SIDE_EFFECTS (condition))
			{
			  /* Wrap it in a NOP_EXPR so that we can set the
			     location of the condition.  */
			  tree e = build1 (NOP_EXPR, TREE_TYPE (condition),
					   condition);
			  SET_EXPR_LOCATION (e, token->location);
			  chain->safe_push (e);
			}
		      }
		    else if (!cp_lexer_next_token_is_keyword (parser->lexer,
							      RID_IF))
		      /* This is if-else without subsequent if.  Zap the
			 condition chain; we would have already warned at
			 this point.  */
		      vec_free (chain);
		  }
		begin_else_clause (statement);
		/* Parse the else-clause.  */
		cp_parser_implicitly_scoped_statement (parser, NULL,
						       guard_tinfo, chain);

		finish_else_clause (statement);

		/* If we are currently parsing a then-clause, then
		   IF_P will not be NULL.  We set it to true to
		   indicate that this if statement has an else clause.
		   This may trigger the Wparentheses warning below
		   when we get back up to the parent if statement.  */
		if (if_p != NULL)
		  *if_p = true;

		if (discard_else)
		  {
		    ELSE_CLAUSE (statement) = NULL_TREE;
		    in_discarded_stmt = was_discarded;
		    --c_inhibit_evaluation_warnings;
		  }
	      }
	    else
	      {
		/* This if statement does not have an else clause.  If
		   NESTED_IF is true, then the then-clause has an if
		   statement which does have an else clause.  We warn
		   about the potential ambiguity.  */
		if (nested_if)
		  warning_at (EXPR_LOCATION (statement), OPT_Wdangling_else,
			      "suggest explicit braces to avoid ambiguous"
			      " %<else%>");
		if (warn_duplicated_cond)
		  /* We don't need the condition chain anymore.  */
		  vec_free (chain);
	      }

	    /* Now we're all done with the if-statement.  */
	    finish_if_stmt (statement);
	  }
	else
	  {
	    bool in_switch_statement_p;
	    unsigned char in_statement;

	    /* Add the condition.  */
	    finish_switch_cond (condition, statement);

	    /* Parse the body of the switch-statement.  */
	    in_switch_statement_p = parser->in_switch_statement_p;
	    in_statement = parser->in_statement;
	    parser->in_switch_statement_p = true;
	    parser->in_statement |= IN_SWITCH_STMT;
	    cp_parser_implicitly_scoped_statement (parser, if_p,
						   guard_tinfo);
	    parser->in_switch_statement_p = in_switch_statement_p;
	    parser->in_statement = in_statement;

	    /* Now we're all done with the switch-statement.  */
	    finish_switch_stmt (statement);
	  }

	return statement;
      }
      break;

    default:
      cp_parser_error (parser, "expected selection-statement");
      return error_mark_node;
    }
}

/* Helper function for cp_parser_condition and cp_parser_simple_declaration.
   If we have seen at least one decl-specifier, and the next token is not
   a parenthesis (after "int (" we might be looking at a functional cast)
   neither we are dealing with a concept-check expression then we must be
   looking at a declaration.  */

static void
cp_parser_maybe_commit_to_declaration (cp_parser* parser,
				       cp_decl_specifier_seq *decl_specs)
{
  if (decl_specs->any_specifiers_p
      && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
      && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
      && !cp_parser_error_occurred (parser)
      && !(decl_specs->type
	   && TREE_CODE (decl_specs->type) == TYPE_DECL
	   && is_constrained_auto (TREE_TYPE (decl_specs->type))))
    cp_parser_commit_to_tentative_parse (parser);
}

/* Helper function for cp_parser_condition.  Enforces [stmt.stmt]/2:
   The declarator shall not specify a function or an array.  Returns
   TRUE if the declarator is valid, FALSE otherwise.  */

static bool
cp_parser_check_condition_declarator (cp_parser* parser,
                                     cp_declarator *declarator,
                                     location_t loc)
{
  if (declarator == cp_error_declarator
      || function_declarator_p (declarator)
      || declarator->kind == cdk_array)
    {
      if (declarator == cp_error_declarator)
	/* Already complained.  */;
      else if (declarator->kind == cdk_array)
       error_at (loc, "condition declares an array");
      else
       error_at (loc, "condition declares a function");
      if (parser->fully_implicit_function_template_p)
       abort_fully_implicit_template (parser);
      cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
                                            /*or_comma=*/false,
                                            /*consume_paren=*/false);
      return false;
    }
  else
    return true;
}

/* Parse a condition.

   condition:
     expression
     type-specifier-seq declarator = initializer-clause
     type-specifier-seq declarator braced-init-list

   GNU Extension:

   condition:
     type-specifier-seq declarator asm-specification [opt]
       attributes [opt] = assignment-expression

   Returns the expression that should be tested.  */

static tree
cp_parser_condition (cp_parser* parser)
{
  cp_decl_specifier_seq type_specifiers;
  const char *saved_message;
  int declares_class_or_enum;

  /* Try the declaration first.  */
  cp_parser_parse_tentatively (parser);
  /* New types are not allowed in the type-specifier-seq for a
     condition.  */
  saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in conditions");
  /* Parse the type-specifier-seq.  */
  cp_parser_decl_specifier_seq (parser,
				CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR,
				&type_specifiers,
				&declares_class_or_enum);
  /* Restore the saved message.  */
  parser->type_definition_forbidden_message = saved_message;

  /* Gather the attributes that were provided with the
     decl-specifiers.  */
  tree prefix_attributes = type_specifiers.attributes;

  cp_parser_maybe_commit_to_declaration (parser, &type_specifiers);

  /* If all is well, we might be looking at a declaration.  */
  if (!cp_parser_error_occurred (parser))
    {
      tree decl;
      tree asm_specification;
      tree attributes;
      cp_declarator *declarator;
      tree initializer = NULL_TREE;
      location_t loc = cp_lexer_peek_token (parser->lexer)->location;

      /* Parse the declarator.  */
      declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
					 CP_PARSER_FLAGS_NONE,
					 /*ctor_dtor_or_conv_p=*/NULL,
					 /*parenthesized_p=*/NULL,
					 /*member_p=*/false,
					 /*friend_p=*/false,
					 /*static_p=*/false);
      /* Parse the attributes.  */
      attributes = cp_parser_attributes_opt (parser);
      /* Parse the asm-specification.  */
      asm_specification = cp_parser_asm_specification_opt (parser);
      /* If the next token is not an `=' or '{', then we might still be
	 looking at an expression.  For example:

	   if (A(a).x)

	 looks like a decl-specifier-seq and a declarator -- but then
	 there is no `=', so this is an expression.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
	cp_parser_simulate_error (parser);

      /* If we did see an `=' or '{', then we are looking at a declaration
	 for sure.  */
      if (cp_parser_parse_definitely (parser))
	{
	  tree pushed_scope;
	  bool non_constant_p = false;
	  int flags = LOOKUP_ONLYCONVERTING;

	  if (!cp_parser_check_condition_declarator (parser, declarator, loc))
	    return error_mark_node;

	  /* Create the declaration.  */
	  decl = start_decl (declarator, &type_specifiers,
			     /*initialized_p=*/true,
			     attributes, prefix_attributes,
			     &pushed_scope);

	  declarator->init_loc = cp_lexer_peek_token (parser->lexer)->location;
	  /* Parse the initializer.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	    {
	      initializer = cp_parser_braced_list (parser, &non_constant_p);
	      CONSTRUCTOR_IS_DIRECT_INIT (initializer) = 1;
	      flags = 0;
	    }
	  else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	    {
	      /* Consume the `='.  */
	      cp_lexer_consume_token (parser->lexer);
	      initializer = cp_parser_initializer_clause (parser,
							  &non_constant_p);
	    }
	  else
	    {
	      cp_parser_error (parser, "expected initializer");
	      initializer = error_mark_node;
	    }
	  if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
	    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);

	  /* Process the initializer.  */
	  cp_finish_decl (decl,
			  initializer, !non_constant_p,
			  asm_specification,
			  flags);

	  if (pushed_scope)
	    pop_scope (pushed_scope);

	  return convert_from_reference (decl);
	}
    }
  /* If we didn't even get past the declarator successfully, we are
     definitely not looking at a declaration.  */
  else
    cp_parser_abort_tentative_parse (parser);

  /* Otherwise, we are looking at an expression.  */
  return cp_parser_expression (parser);
}

/* Parses a for-statement or range-for-statement until the closing ')',
   not included. */

static tree
cp_parser_for (cp_parser *parser, bool ivdep, unsigned short unroll)
{
  tree init, scope, decl;
  bool is_range_for;

  /* Begin the for-statement.  */
  scope = begin_for_scope (&init);

  /* Maybe parse the optional init-statement in a range-based for loop.  */
  if (cp_parser_range_based_for_with_init_p (parser)
      /* Checked for diagnostic purposes only.  */
      && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    {
      tree dummy;
      cp_parser_init_statement (parser, &dummy);
      if (cxx_dialect < cxx20)
	{
	  pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		   OPT_Wc__20_extensions,
		   "range-based %<for%> loops with initializer only "
		   "available with %<-std=c++20%> or %<-std=gnu++20%>");
	  decl = error_mark_node;
	}
    }

  /* Parse the initialization.  */
  is_range_for = cp_parser_init_statement (parser, &decl);

  if (is_range_for)
    return cp_parser_range_for (parser, scope, init, decl, ivdep, unroll,
				false);
  else
    return cp_parser_c_for (parser, scope, init, ivdep, unroll);
}

static tree
cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep,
		 unsigned short unroll)
{
  /* Normal for loop */
  tree condition = NULL_TREE;
  tree expression = NULL_TREE;
  tree stmt;

  stmt = begin_for_stmt (scope, init);
  /* The init-statement has already been parsed in
     cp_parser_init_statement, so no work is needed here.  */
  finish_init_stmt (stmt);

  /* If there's a condition, process it.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    condition = cp_parser_condition (parser);
  else if (ivdep)
    {
      cp_parser_error (parser, "missing loop condition in loop with "
		       "%<GCC ivdep%> pragma");
      condition = error_mark_node;
    }
  else if (unroll)
    {
      cp_parser_error (parser, "missing loop condition in loop with "
		       "%<GCC unroll%> pragma");
      condition = error_mark_node;
    }
  finish_for_cond (condition, stmt, ivdep, unroll);
  /* Look for the `;'.  */
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

  /* If there's an expression, process it.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
    expression = cp_parser_expression (parser);
  finish_for_expr (expression, stmt);

  return stmt;
}

/* Tries to parse a range-based for-statement:

  range-based-for:
    decl-specifier-seq declarator : expression

  The decl-specifier-seq declarator and the `:' are already parsed by
  cp_parser_init_statement.  If processing_template_decl it returns a
  newly created RANGE_FOR_STMT; if not, it is converted to a
  regular FOR_STMT.  */

static tree
cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
		     bool ivdep, unsigned short unroll, bool is_omp)
{
  tree stmt, range_expr;
  auto_vec <cxx_binding *, 16> bindings;
  auto_vec <tree, 16> names;
  tree decomp_first_name = NULL_TREE;
  unsigned int decomp_cnt = 0;

  /* Get the range declaration momentarily out of the way so that
     the range expression doesn't clash with it. */
  if (range_decl != error_mark_node)
    {
      if (DECL_HAS_VALUE_EXPR_P (range_decl))
	{
	  tree v = DECL_VALUE_EXPR (range_decl);
	  /* For decomposition declaration get all of the corresponding
	     declarations out of the way.  */
	  if (TREE_CODE (v) == ARRAY_REF
	      && VAR_P (TREE_OPERAND (v, 0))
	      && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
	    {
	      tree d = range_decl;
	      range_decl = TREE_OPERAND (v, 0);
	      decomp_cnt = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
	      decomp_first_name = d;
	      for (unsigned int i = 0; i < decomp_cnt; i++, d = DECL_CHAIN (d))
		{
		  tree name = DECL_NAME (d);
		  names.safe_push (name);
		  bindings.safe_push (IDENTIFIER_BINDING (name));
		  IDENTIFIER_BINDING (name)
		    = IDENTIFIER_BINDING (name)->previous;
		}
	    }
	}
      if (names.is_empty ())
	{
	  tree name = DECL_NAME (range_decl);
	  names.safe_push (name);
	  bindings.safe_push (IDENTIFIER_BINDING (name));
	  IDENTIFIER_BINDING (name) = IDENTIFIER_BINDING (name)->previous;
	}
    }

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      bool expr_non_constant_p;
      range_expr = cp_parser_braced_list (parser, &expr_non_constant_p);
    }
  else
    range_expr = cp_parser_expression (parser);

  /* Put the range declaration(s) back into scope. */
  for (unsigned int i = 0; i < names.length (); i++)
    {
      cxx_binding *binding = bindings[i];
      binding->previous = IDENTIFIER_BINDING (names[i]);
      IDENTIFIER_BINDING (names[i]) = binding;
    }

  /* finish_omp_for has its own code for the following, so just
     return the range_expr instead.  */
  if (is_omp)
    return range_expr;

  /* If in template, STMT is converted to a normal for-statement
     at instantiation. If not, it is done just ahead. */
  if (processing_template_decl)
    {
      if (check_for_bare_parameter_packs (range_expr))
	range_expr = error_mark_node;
      stmt = begin_range_for_stmt (scope, init);
      if (ivdep)
	RANGE_FOR_IVDEP (stmt) = 1;
      if (unroll)
	RANGE_FOR_UNROLL (stmt) = build_int_cst (integer_type_node, unroll);
      finish_range_for_decl (stmt, range_decl, range_expr);
      if (!type_dependent_expression_p (range_expr)
	  /* do_auto_deduction doesn't mess with template init-lists.  */
	  && !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
	do_range_for_auto_deduction (range_decl, range_expr, decomp_first_name,
				     decomp_cnt);
    }
  else
    {
      stmt = begin_for_stmt (scope, init);
      stmt = cp_convert_range_for (stmt, range_decl, range_expr,
				   decomp_first_name, decomp_cnt, ivdep,
				   unroll);
    }
  return stmt;
}

/* Subroutine of cp_convert_range_for: given the initializer expression,
   builds up the range temporary.  */

static tree
build_range_temp (tree range_expr)
{
  /* Find out the type deduced by the declaration
     `auto &&__range = range_expr'.  */
  tree auto_node = make_auto ();
  tree range_type = cp_build_reference_type (auto_node, true);
  range_type = do_auto_deduction (range_type, range_expr, auto_node);

  /* Create the __range variable.  */
  tree range_temp = build_decl (input_location, VAR_DECL,
				for_range__identifier, range_type);
  TREE_USED (range_temp) = 1;
  DECL_ARTIFICIAL (range_temp) = 1;

  return range_temp;
}

/* Used by cp_parser_range_for in template context: we aren't going to
   do a full conversion yet, but we still need to resolve auto in the
   type of the for-range-declaration if present.  This is basically
   a shortcut version of cp_convert_range_for.  */

static void
do_range_for_auto_deduction (tree decl, tree range_expr,
			     tree decomp_first_name, unsigned int decomp_cnt)
{
  tree auto_node = type_uses_auto (TREE_TYPE (decl));
  if (auto_node)
    {
      tree begin_dummy, end_dummy, range_temp, iter_type, iter_decl;
      range_temp = convert_from_reference (build_range_temp (range_expr));
      iter_type = (cp_parser_perform_range_for_lookup
		   (range_temp, &begin_dummy, &end_dummy));
      if (iter_type)
	{
	  iter_decl = build_decl (input_location, VAR_DECL, NULL_TREE,
				  iter_type);
	  iter_decl = build_x_indirect_ref (input_location, iter_decl,
					    RO_UNARY_STAR, NULL_TREE,
					    tf_warning_or_error);
	  TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
						iter_decl, auto_node,
						tf_warning_or_error,
						adc_variable_type);
	  if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
	    cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
	}
    }
}

/* Warns when the loop variable should be changed to a reference type to
   avoid unnecessary copying.  I.e., from

     for (const auto x : range)

   where range returns a reference, to

     for (const auto &x : range)

   if this version doesn't make a copy.

  This function also warns when the loop variable is initialized with
  a value of a different type resulting in a copy:

     int arr[10];
     for (const double &x : arr)

   DECL is the RANGE_DECL; EXPR is the *__for_begin expression.
   This function is never called when processing_template_decl is on.  */

static void
warn_for_range_copy (tree decl, tree expr)
{
  if (!warn_range_loop_construct
      || decl == error_mark_node)
    return;

  location_t loc = DECL_SOURCE_LOCATION (decl);
  tree type = TREE_TYPE (decl);

  if (from_macro_expansion_at (loc))
    return;

  if (TYPE_REF_P (type))
    {
      if (glvalue_p (expr)
	  && ref_conv_binds_to_temporary (type, expr).is_true ())
	{
	  auto_diagnostic_group d;
	  if (warning_at (loc, OPT_Wrange_loop_construct,
			  "loop variable %qD of type %qT binds to a temporary "
			  "constructed from type %qT", decl, type,
			  TREE_TYPE (expr)))
	    {
	      tree ref = cp_build_qualified_type (TREE_TYPE (expr),
						  TYPE_QUAL_CONST);
	      ref = cp_build_reference_type (ref, /*rval*/false);
	      inform (loc, "use non-reference type %qT to make the copy "
		      "explicit or %qT to prevent copying",
		      non_reference (type), ref);
	    }
	}
      return;
    }
  else if (!CP_TYPE_CONST_P (type))
    return;

  /* Since small trivially copyable types are cheap to copy, we suppress the
     warning for them.  64B is a common size of a cache line.  */
  if (TREE_CODE (TYPE_SIZE_UNIT (type)) != INTEGER_CST
      || (tree_to_uhwi (TYPE_SIZE_UNIT (type)) <= 64
	  && trivially_copyable_p (type)))
    return;

  /* If we can initialize a reference directly, suggest that to avoid the
     copy.  */
  tree rtype = cp_build_reference_type (type, /*rval*/false);
  if (ref_conv_binds_to_temporary (rtype, expr).is_false ())
    {
      auto_diagnostic_group d;
      if (warning_at (loc, OPT_Wrange_loop_construct,
		      "loop variable %qD creates a copy from type %qT",
		      decl, type))
	{
	  gcc_rich_location richloc (loc);
	  richloc.add_fixit_insert_before ("&");
	  inform (&richloc, "use reference type to prevent copying");
	}
    }
}

/* Converts a range-based for-statement into a normal
   for-statement, as per the definition.

      for (RANGE_DECL : RANGE_EXPR)
	BLOCK

   should be equivalent to:

      {
	auto &&__range = RANGE_EXPR;
	for (auto __begin = BEGIN_EXPR, __end = END_EXPR;
	      __begin != __end;
	      ++__begin)
	  {
	      RANGE_DECL = *__begin;
	      BLOCK
	  }
      }

   If RANGE_EXPR is an array:
	BEGIN_EXPR = __range
	END_EXPR = __range + ARRAY_SIZE(__range)
   Else if RANGE_EXPR has a member 'begin' or 'end':
	BEGIN_EXPR = __range.begin()
	END_EXPR = __range.end()
   Else:
	BEGIN_EXPR = begin(__range)
	END_EXPR = end(__range);

   If __range has a member 'begin' but not 'end', or vice versa, we must
   still use the second alternative (it will surely fail, however).
   When calling begin()/end() in the third alternative we must use
   argument dependent lookup, but always considering 'std' as an associated
   namespace.  */

tree
cp_convert_range_for (tree statement, tree range_decl, tree range_expr,
		      tree decomp_first_name, unsigned int decomp_cnt,
		      bool ivdep, unsigned short unroll)
{
  tree begin, end;
  tree iter_type, begin_expr, end_expr;
  tree condition, expression;

  range_expr = mark_lvalue_use (range_expr);

  if (range_decl == error_mark_node || range_expr == error_mark_node)
    /* If an error happened previously do nothing or else a lot of
       unhelpful errors would be issued.  */
    begin_expr = end_expr = iter_type = error_mark_node;
  else
    {
      tree range_temp;

      if (VAR_P (range_expr)
	  && array_of_runtime_bound_p (TREE_TYPE (range_expr)))
	/* Can't bind a reference to an array of runtime bound.  */
	range_temp = range_expr;
      else
	{
	  range_temp = build_range_temp (range_expr);
	  pushdecl (range_temp);
	  cp_finish_decl (range_temp, range_expr,
			  /*is_constant_init*/false, NULL_TREE,
			  LOOKUP_ONLYCONVERTING);
	  range_temp = convert_from_reference (range_temp);
	}
      iter_type = cp_parser_perform_range_for_lookup (range_temp,
						      &begin_expr, &end_expr);
    }

  /* The new for initialization statement.  */
  begin = build_decl (input_location, VAR_DECL, for_begin__identifier,
		      iter_type);
  TREE_USED (begin) = 1;
  DECL_ARTIFICIAL (begin) = 1;
  pushdecl (begin);
  cp_finish_decl (begin, begin_expr,
		  /*is_constant_init*/false, NULL_TREE,
		  LOOKUP_ONLYCONVERTING);

  if (cxx_dialect >= cxx17)
    iter_type = cv_unqualified (TREE_TYPE (end_expr));
  end = build_decl (input_location, VAR_DECL, for_end__identifier, iter_type);
  TREE_USED (end) = 1;
  DECL_ARTIFICIAL (end) = 1;
  pushdecl (end);
  cp_finish_decl (end, end_expr,
		  /*is_constant_init*/false, NULL_TREE,
		  LOOKUP_ONLYCONVERTING);

  finish_init_stmt (statement);

  /* The new for condition.  */
  condition = build_x_binary_op (input_location, NE_EXPR,
				 begin, ERROR_MARK,
				 end, ERROR_MARK,
				 NULL_TREE, NULL, tf_warning_or_error);
  finish_for_cond (condition, statement, ivdep, unroll);

  /* The new increment expression.  */
  expression = finish_unary_op_expr (input_location,
				     PREINCREMENT_EXPR, begin,
				     tf_warning_or_error);
  finish_for_expr (expression, statement);

  if (VAR_P (range_decl) && DECL_DECOMPOSITION_P (range_decl))
    cp_maybe_mangle_decomp (range_decl, decomp_first_name, decomp_cnt);

  /* The declaration is initialized with *__begin inside the loop body.  */
  tree deref_begin = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
					   NULL_TREE, tf_warning_or_error);
  cp_finish_decl (range_decl, deref_begin,
		  /*is_constant_init*/false, NULL_TREE,
		  LOOKUP_ONLYCONVERTING);
  if (VAR_P (range_decl) && DECL_DECOMPOSITION_P (range_decl))
    cp_finish_decomp (range_decl, decomp_first_name, decomp_cnt);

  warn_for_range_copy (range_decl, deref_begin);

  return statement;
}

/* Solves BEGIN_EXPR and END_EXPR as described in cp_convert_range_for.
   We need to solve both at the same time because the method used
   depends on the existence of members begin or end.
   Returns the type deduced for the iterator expression.  */

static tree
cp_parser_perform_range_for_lookup (tree range, tree *begin, tree *end)
{
  if (error_operand_p (range))
    {
      *begin = *end = error_mark_node;
      return error_mark_node;
    }

  if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (range))))
    {
      error ("range-based %<for%> expression of type %qT "
	     "has incomplete type", TREE_TYPE (range));
      *begin = *end = error_mark_node;
      return error_mark_node;
    }
  if (TREE_CODE (TREE_TYPE (range)) == ARRAY_TYPE)
    {
      /* If RANGE is an array, we will use pointer arithmetic.  */
      *begin = decay_conversion (range, tf_warning_or_error);
      *end = build_binary_op (input_location, PLUS_EXPR,
			      range,
			      array_type_nelts_top (TREE_TYPE (range)),
			      false);
      return TREE_TYPE (*begin);
    }
  else
    {
      /* If it is not an array, we must do a bit of magic.  */
      tree id_begin, id_end;
      tree member_begin, member_end;

      *begin = *end = error_mark_node;

      id_begin = get_identifier ("begin");
      id_end = get_identifier ("end");
      member_begin = lookup_member (TREE_TYPE (range), id_begin,
				    /*protect=*/2, /*want_type=*/false,
				    tf_warning_or_error);
      member_end = lookup_member (TREE_TYPE (range), id_end,
				  /*protect=*/2, /*want_type=*/false,
				  tf_warning_or_error);

      if (member_begin != NULL_TREE && member_end != NULL_TREE)
	{
	  /* Use the member functions.  */
	  *begin = cp_parser_range_for_member_function (range, id_begin);
	  *end = cp_parser_range_for_member_function (range, id_end);
	}
      else
	{
	  /* Use global functions with ADL.  */
	  releasing_vec vec;

	  vec_safe_push (vec, range);

	  member_begin = perform_koenig_lookup (id_begin, vec,
						tf_warning_or_error);
	  *begin = finish_call_expr (member_begin, &vec, false, true,
				     tf_warning_or_error);
	  member_end = perform_koenig_lookup (id_end, vec,
					      tf_warning_or_error);
	  *end = finish_call_expr (member_end, &vec, false, true,
				   tf_warning_or_error);
	}

      /* Last common checks.  */
      if (*begin == error_mark_node || *end == error_mark_node)
	{
	  /* If one of the expressions is an error do no more checks.  */
	  *begin = *end = error_mark_node;
	  return error_mark_node;
	}
      else if (type_dependent_expression_p (*begin)
	       || type_dependent_expression_p (*end))
	/* Can happen, when, eg, in a template context, Koenig lookup
	   can't resolve begin/end (c++/58503).  */
	return NULL_TREE;
      else
	{
	  tree iter_type = cv_unqualified (TREE_TYPE (*begin));
	  /* The unqualified type of the __begin and __end temporaries should
	     be the same, as required by the multiple auto declaration.  */
	  if (!same_type_p (iter_type, cv_unqualified (TREE_TYPE (*end))))
	    {
	      if (cxx_dialect >= cxx17
		  && (build_x_binary_op (input_location, NE_EXPR,
					 *begin, ERROR_MARK,
					 *end, ERROR_MARK,
					 NULL_TREE, NULL, tf_none)
		      != error_mark_node))
		/* P0184R0 allows __begin and __end to have different types,
		   but make sure they are comparable so we can give a better
		   diagnostic.  */;
	      else
		error ("inconsistent begin/end types in range-based %<for%> "
		       "statement: %qT and %qT",
		       TREE_TYPE (*begin), TREE_TYPE (*end));
	    }
	  return iter_type;
	}
    }
}

/* Helper function for cp_parser_perform_range_for_lookup.
   Builds a tree for RANGE.IDENTIFIER().  */

static tree
cp_parser_range_for_member_function (tree range, tree identifier)
{
  tree member, res;

  member = finish_class_member_access_expr (range, identifier,
					    false, tf_warning_or_error);
  if (member == error_mark_node)
    return error_mark_node;

  releasing_vec vec;
  res = finish_call_expr (member, &vec,
			  /*disallow_virtual=*/false,
			  /*koenig_p=*/false,
			  tf_warning_or_error);
  return res;
}

/* Parse an iteration-statement.

   iteration-statement:
     while ( condition ) statement
     do statement while ( expression ) ;
     for ( init-statement condition [opt] ; expression [opt] )
       statement

   Returns the new WHILE_STMT, DO_STMT, FOR_STMT or RANGE_FOR_STMT.  */

static tree
cp_parser_iteration_statement (cp_parser* parser, bool *if_p, bool ivdep,
			       unsigned short unroll)
{
  cp_token *token;
  enum rid keyword;
  tree statement;
  unsigned char in_statement;
  token_indent_info guard_tinfo;

  /* Peek at the next token.  */
  token = cp_parser_require (parser, CPP_KEYWORD, RT_ITERATION);
  if (!token)
    return error_mark_node;

  guard_tinfo = get_token_indent_info (token);

  /* Remember whether or not we are already within an iteration
     statement.  */
  in_statement = parser->in_statement;

  /* See what kind of keyword it is.  */
  keyword = token->keyword;
  switch (keyword)
    {
    case RID_WHILE:
      {
	tree condition;

	/* Begin the while-statement.  */
	statement = begin_while_stmt ();
	/* Look for the `('.  */
	matching_parens parens;
	parens.require_open (parser);
	/* Parse the condition.  */
	condition = cp_parser_condition (parser);
	finish_while_stmt_cond (condition, statement, ivdep, unroll);
	/* Look for the `)'.  */
	parens.require_close (parser);
	/* Parse the dependent statement.  */
	parser->in_statement = IN_ITERATION_STMT;
	bool prev = note_iteration_stmt_body_start ();
	cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
	note_iteration_stmt_body_end (prev);
	parser->in_statement = in_statement;
	/* We're done with the while-statement.  */
	finish_while_stmt (statement);
      }
      break;

    case RID_DO:
      {
	tree expression;

	/* Begin the do-statement.  */
	statement = begin_do_stmt ();
	/* Parse the body of the do-statement.  */
	parser->in_statement = IN_ITERATION_STMT;
	bool prev = note_iteration_stmt_body_start ();
	cp_parser_implicitly_scoped_statement (parser, NULL, guard_tinfo);
	note_iteration_stmt_body_end (prev);
	parser->in_statement = in_statement;
	finish_do_body (statement);
	/* Look for the `while' keyword.  */
	cp_parser_require_keyword (parser, RID_WHILE, RT_WHILE);
	/* Look for the `('.  */
	matching_parens parens;
	parens.require_open (parser);
	/* Parse the expression.  */
	expression = cp_parser_expression (parser);
	/* We're done with the do-statement.  */
	finish_do_stmt (expression, statement, ivdep, unroll);
	/* Look for the `)'.  */
	parens.require_close (parser);
	/* Look for the `;'.  */
	cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      }
      break;

    case RID_FOR:
      {
	/* Look for the `('.  */
	matching_parens parens;
	parens.require_open (parser);

	statement = cp_parser_for (parser, ivdep, unroll);

	/* Look for the `)'.  */
	parens.require_close (parser);

	/* Parse the body of the for-statement.  */
	parser->in_statement = IN_ITERATION_STMT;
	bool prev = note_iteration_stmt_body_start ();
	cp_parser_already_scoped_statement (parser, if_p, guard_tinfo);
	note_iteration_stmt_body_end (prev);
	parser->in_statement = in_statement;

	/* We're done with the for-statement.  */
	finish_for_stmt (statement);
      }
      break;

    default:
      cp_parser_error (parser, "expected iteration-statement");
      statement = error_mark_node;
      break;
    }

  return statement;
}

/* Parse an init-statement or the declarator of a range-based-for.
   Returns true if a range-based-for declaration is seen.

   init-statement:
     expression-statement
     simple-declaration
     alias-declaration  */

static bool
cp_parser_init_statement (cp_parser *parser, tree *decl)
{
  /* If the next token is a `;', then we have an empty
     expression-statement.  Grammatically, this is also a
     simple-declaration, but an invalid one, because it does not
     declare anything.  Therefore, if we did not handle this case
     specially, we would issue an error message about an invalid
     declaration.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    {
      bool is_range_for = false;
      bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;

      /* A colon is used in range-based for.  */
      parser->colon_corrects_to_scope_p = false;

      /* We're going to speculatively look for a declaration, falling back
	 to an expression, if necessary.  */
      cp_parser_parse_tentatively (parser);
      bool expect_semicolon_p = true;
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
	{
	  cp_parser_alias_declaration (parser);
	  expect_semicolon_p = false;
	  if (cxx_dialect < cxx23
	      && !cp_parser_uncommitted_to_tentative_parse_p (parser))
	    pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		     OPT_Wc__23_extensions,
		     "alias-declaration in init-statement only "
		     "available with %<-std=c++23%> or %<-std=gnu++23%>");
	}
      else
	/* Parse the declaration.  */
	cp_parser_simple_declaration (parser,
				      /*function_definition_allowed_p=*/false,
				      decl);
      parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
      if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
	{
	  /* It is a range-for, consume the ':'.  */
	  cp_lexer_consume_token (parser->lexer);
	  is_range_for = true;
	  if (cxx_dialect < cxx11)
	    pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		     OPT_Wc__11_extensions,
		     "range-based %<for%> loops only available with "
		     "%<-std=c++11%> or %<-std=gnu++11%>");
	}
      else if (expect_semicolon_p)
	/* The ';' is not consumed yet because we told
	   cp_parser_simple_declaration not to.  */
	cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

      if (cp_parser_parse_definitely (parser))
	return is_range_for;
      /* If the tentative parse failed, then we shall need to look for an
	 expression-statement.  */
    }
  /* If we are here, it is an expression-statement.  */
  cp_parser_expression_statement (parser, NULL_TREE);
  return false;
}

/* Parse a jump-statement.

   jump-statement:
     break ;
     continue ;
     return expression [opt] ;
     return braced-init-list ;
     coroutine-return-statement;
     goto identifier ;

   GNU extension:

   jump-statement:
     goto * expression ;

   Returns the new BREAK_STMT, CONTINUE_STMT, RETURN_EXPR, or GOTO_EXPR.  */

static tree
cp_parser_jump_statement (cp_parser* parser)
{
  tree statement = error_mark_node;
  cp_token *token;
  enum rid keyword;
  unsigned char in_statement;

  /* Peek at the next token.  */
  token = cp_parser_require (parser, CPP_KEYWORD, RT_JUMP);
  if (!token)
    return error_mark_node;

  /* See what kind of keyword it is.  */
  keyword = token->keyword;
  switch (keyword)
    {
    case RID_BREAK:
      in_statement = parser->in_statement & ~IN_IF_STMT;
      switch (in_statement)
	{
	case 0:
	  error_at (token->location, "break statement not within loop or switch");
	  break;
	default:
	  gcc_assert ((in_statement & IN_SWITCH_STMT)
		      || in_statement == IN_ITERATION_STMT);
	  statement = finish_break_stmt ();
	  if (in_statement == IN_ITERATION_STMT)
	    break_maybe_infinite_loop ();
	  break;
	case IN_OMP_BLOCK:
	  error_at (token->location, "invalid exit from OpenMP structured block");
	  break;
	case IN_OMP_FOR:
	  error_at (token->location, "break statement used with OpenMP for loop");
	  break;
	}
      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      break;

    case RID_CONTINUE:
      switch (parser->in_statement & ~(IN_SWITCH_STMT | IN_IF_STMT))
	{
	case 0:
	  error_at (token->location, "continue statement not within a loop");
	  break;
	  /* Fall through.  */
	case IN_ITERATION_STMT:
	case IN_OMP_FOR:
	  statement = finish_continue_stmt ();
	  break;
	case IN_OMP_BLOCK:
	  error_at (token->location, "invalid exit from OpenMP structured block");
	  break;
	default:
	  gcc_unreachable ();
	}
      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      break;

    case RID_CO_RETURN:
    case RID_RETURN:
      {
	tree expr;
	bool expr_non_constant_p;

	if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	  {
	    cp_lexer_set_source_position (parser->lexer);
	    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
	    expr = cp_parser_braced_list (parser, &expr_non_constant_p);
	  }
	else if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	  expr = cp_parser_expression (parser);
	else
	  /* If the next token is a `;', then there is no
	     expression.  */
	  expr = NULL_TREE;
	/* Build the return-statement, check co-return first, since type
	   deduction is not valid there.  */
	if (keyword == RID_CO_RETURN)
	  statement = finish_co_return_stmt (token->location, expr);
	else if (FNDECL_USED_AUTO (current_function_decl) && in_discarded_stmt)
	  /* Don't deduce from a discarded return statement.  */;
	else
	  statement = finish_return_stmt (expr);
	/* Look for the final `;'.  */
	cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      }
      break;

    case RID_GOTO:
      if (parser->in_function_body
	  && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
	  && cxx_dialect < cxx23)
	{
	  error ("%<goto%> in %<constexpr%> function only available with "
		 "%<-std=c++2b%> or %<-std=gnu++2b%>");
	  cp_function_chain->invalid_constexpr = true;
	}

      /* Create the goto-statement.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_MULT))
	{
	  /* Issue a warning about this use of a GNU extension.  */
	  pedwarn (token->location, OPT_Wpedantic, "ISO C++ forbids computed gotos");
	  /* Consume the '*' token.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Parse the dependent expression.  */
	  finish_goto_stmt (cp_parser_expression (parser));
	}
      else
	finish_goto_stmt (cp_parser_identifier (parser));
      /* Look for the final `;'.  */
      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      break;

    default:
      cp_parser_error (parser, "expected jump-statement");
      break;
    }

  return statement;
}

/* Parse a declaration-statement.

   declaration-statement:
     block-declaration  */

static void
cp_parser_declaration_statement (cp_parser* parser)
{
  void *p;

  /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
  p = obstack_alloc (&declarator_obstack, 0);

 /* Parse the block-declaration.  */
  cp_parser_block_declaration (parser, /*statement_p=*/true);

  /* Free any declarators allocated.  */
  obstack_free (&declarator_obstack, p);
}

/* Some dependent statements (like `if (cond) statement'), are
   implicitly in their own scope.  In other words, if the statement is
   a single statement (as opposed to a compound-statement), it is
   none-the-less treated as if it were enclosed in braces.  Any
   declarations appearing in the dependent statement are out of scope
   after control passes that point.  This function parses a statement,
   but ensures that is in its own scope, even if it is not a
   compound-statement.

   If IF_P is not NULL, *IF_P is set to indicate whether the statement
   is a (possibly labeled) if statement which is not enclosed in
   braces and has an else clause.  This is used to implement
   -Wparentheses.

   CHAIN is a vector of if-else-if conditions.  This is used to implement
   -Wduplicated-cond.

   Returns the new statement.  */

static tree
cp_parser_implicitly_scoped_statement (cp_parser* parser, bool *if_p,
				       const token_indent_info &guard_tinfo,
				       vec<tree> *chain)
{
  tree statement;
  location_t body_loc = cp_lexer_peek_token (parser->lexer)->location;
  location_t body_loc_after_labels = UNKNOWN_LOCATION;
  token_indent_info body_tinfo
    = get_token_indent_info (cp_lexer_peek_token (parser->lexer));

  if (if_p != NULL)
    *if_p = false;

  /* Mark if () ; with a special NOP_EXPR.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    {
      cp_lexer_consume_token (parser->lexer);
      statement = add_stmt (build_empty_stmt (body_loc));

      if (guard_tinfo.keyword == RID_IF
	  && !cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
	warning_at (body_loc, OPT_Wempty_body,
		    "suggest braces around empty body in an %<if%> statement");
      else if (guard_tinfo.keyword == RID_ELSE)
	warning_at (body_loc, OPT_Wempty_body,
		    "suggest braces around empty body in an %<else%> statement");
    }
  /* if a compound is opened, we simply parse the statement directly.  */
  else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    statement = cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
  /* If the token is not a `{', then we must take special action.  */
  else
    {
      /* Create a compound-statement.  */
      statement = begin_compound_stmt (0);
      /* Parse the dependent-statement.  */
      cp_parser_statement (parser, NULL_TREE, false, if_p, chain,
			   &body_loc_after_labels);
      /* Finish the dummy compound-statement.  */
      finish_compound_stmt (statement);
    }

  token_indent_info next_tinfo
    = get_token_indent_info (cp_lexer_peek_token (parser->lexer));
  warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);

  if (body_loc_after_labels != UNKNOWN_LOCATION
      && next_tinfo.type != CPP_SEMICOLON)
    warn_for_multistatement_macros (body_loc_after_labels, next_tinfo.location,
				    guard_tinfo.location, guard_tinfo.keyword);

  /* Return the statement.  */
  return statement;
}

/* For some dependent statements (like `while (cond) statement'), we
   have already created a scope.  Therefore, even if the dependent
   statement is a compound-statement, we do not want to create another
   scope.  */

static void
cp_parser_already_scoped_statement (cp_parser* parser, bool *if_p,
				    const token_indent_info &guard_tinfo)
{
  /* If the token is a `{', then we must take special action.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
    {
      token_indent_info body_tinfo
	= get_token_indent_info (cp_lexer_peek_token (parser->lexer));
      location_t loc_after_labels = UNKNOWN_LOCATION;

      cp_parser_statement (parser, NULL_TREE, false, if_p, NULL,
			   &loc_after_labels);
      token_indent_info next_tinfo
	= get_token_indent_info (cp_lexer_peek_token (parser->lexer));
      warn_for_misleading_indentation (guard_tinfo, body_tinfo, next_tinfo);

      if (loc_after_labels != UNKNOWN_LOCATION
	  && next_tinfo.type != CPP_SEMICOLON)
	warn_for_multistatement_macros (loc_after_labels, next_tinfo.location,
					guard_tinfo.location,
					guard_tinfo.keyword);
    }
  else
    {
      /* Avoid calling cp_parser_compound_statement, so that we
	 don't create a new scope.  Do everything else by hand.  */
      matching_braces braces;
      braces.require_open (parser);
      /* If the next keyword is `__label__' we have a label declaration.  */
      while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
	cp_parser_label_declaration (parser);
      /* Parse an (optional) statement-seq.  */
      cp_parser_statement_seq_opt (parser, NULL_TREE);
      braces.require_close (parser);
    }
}

/* Modules */

/* Parse a module-name,
   identifier
   module-name . identifier
   header-name

   Returns a pointer to module object, NULL.   */

static module_state *
cp_parser_module_name (cp_parser *parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_HEADER_NAME)
    {
      cp_lexer_consume_token (parser->lexer);

      return get_module (token->u.value);
    }

  module_state *parent = NULL;
  bool partitioned = false;
  if (token->type == CPP_COLON && named_module_p ())
    {
      partitioned = true;
      cp_lexer_consume_token (parser->lexer);
    }

  for (;;)
    {
      if (cp_lexer_peek_token (parser->lexer)->type != CPP_NAME)
	{
	  cp_parser_error (parser, "expected module-name");
	  break;
	}

      tree name = cp_lexer_consume_token (parser->lexer)->u.value;
      parent = get_module (name, parent, partitioned);
      token = cp_lexer_peek_token (parser->lexer);
      if (!partitioned && token->type == CPP_COLON)
	partitioned = true;
      else if (token->type != CPP_DOT)
	break;

      cp_lexer_consume_token (parser->lexer);
   }

  return parent;
}

/* Named module-declaration
     __module ; PRAGMA_EOL
     __module private ; PRAGMA_EOL (unimplemented)
     [__export] __module module-name attr-spec-seq-opt ; PRAGMA_EOL
*/

static module_parse
cp_parser_module_declaration (cp_parser *parser, module_parse mp_state,
			      bool exporting)
{
  /* We're a pseudo pragma.  */
  parser->lexer->in_pragma = true;
  cp_token *token = cp_lexer_consume_token (parser->lexer);

  if (flag_header_unit)
    {
      error_at (token->location,
		"module-declaration not permitted in header-unit");
      goto skip_eol;
    }
  else if (mp_state == MP_FIRST && !exporting
      && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    {
      /* Start global module fragment.  */
      cp_lexer_consume_token (parser->lexer);
      module_kind = MK_NAMED;
      mp_state = MP_GLOBAL;
      cp_parser_require_pragma_eol (parser, token);
    }
  else if (!exporting
	   && cp_lexer_next_token_is (parser->lexer, CPP_COLON)
	   && cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_PRIVATE)
	   && cp_lexer_nth_token_is (parser->lexer, 3, CPP_SEMICOLON))
    {
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
      cp_parser_require_pragma_eol (parser, token);

      if ((mp_state == MP_PURVIEW || mp_state == MP_PURVIEW_IMPORTS)
	  && module_has_cmi_p ())
	{
	  mp_state = MP_PRIVATE_IMPORTS;
	  sorry_at (token->location, "private module fragment");
	}
      else
	error_at (token->location,
		  "private module fragment only permitted in purview"
		  " of module interface or partition");
    }
  else if (!(mp_state == MP_FIRST || mp_state == MP_GLOBAL))
    {
      /* Neither the first declaration, nor in a GMF.  */
      error_at (token->location, "module-declaration only permitted as first"
		" declaration, or ending a global module fragment");
    skip_eol:
      cp_parser_skip_to_pragma_eol (parser, token);
    }
  else
    {
      module_state *mod = cp_parser_module_name (parser);
      tree attrs = cp_parser_attributes_opt (parser);

      mp_state = MP_PURVIEW_IMPORTS;
      if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
	goto skip_eol;

      declare_module (mod, token->location, exporting, attrs, parse_in);
      cp_parser_require_pragma_eol (parser, token);
    }

  return mp_state;
}

/* Import-declaration
   [__export] __import module-name attr-spec-seq-opt ; PRAGMA_EOL */

static void
cp_parser_import_declaration (cp_parser *parser, module_parse mp_state,
			      bool exporting)
{
  /* We're a pseudo pragma.  */
  parser->lexer->in_pragma = true;
  cp_token *token = cp_lexer_consume_token (parser->lexer);

  if (mp_state == MP_PURVIEW || mp_state == MP_PRIVATE)
    {
      error_at (token->location, "post-module-declaration"
		" imports must be contiguous");
    note_lexer:
      inform (token->location, "perhaps insert a line break, or other"
	      " disambiguation, to prevent this being considered a"
	      " module control-line");
    skip_eol:
      cp_parser_skip_to_pragma_eol (parser, token);
    }
  else if (current_scope () != global_namespace)
    {
      error_at (token->location, "import-declaration must be at global scope");
      goto note_lexer;
    }
  else
    {
      module_state *mod = cp_parser_module_name (parser);
      tree attrs = cp_parser_attributes_opt (parser);

      if (!mod || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
	goto skip_eol;
      cp_parser_require_pragma_eol (parser, token);

      if (parser->in_unbraced_linkage_specification_p)
	error_at (token->location, "import cannot appear directly in"
		  " a linkage-specification");

      if (mp_state == MP_PURVIEW_IMPORTS || mp_state == MP_PRIVATE_IMPORTS)
	{
	  /* Module-purview imports must not be from source inclusion
	     [cpp.import]/7  */
	  if (attrs
	      && private_lookup_attribute ("__translated",
					   strlen ("__translated"), attrs))
	    error_at (token->location, "post-module-declaration imports"
		      " must not be include-translated");
	  else if (!token->main_source_p)
	    error_at (token->location, "post-module-declaration imports"
		      " must not be from header inclusion");
	}

      import_module (mod, token->location, exporting, attrs, parse_in);
    }
}

/*  export-declaration.

    export declaration
    export { declaration-seq-opt }  */

static void
cp_parser_module_export (cp_parser *parser)
{
  gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT));
  cp_token *token = cp_lexer_consume_token (parser->lexer);

  if (!module_interface_p ())
    error_at (token->location,
	      "%qE may only occur after a module interface declaration",
	      token->u.value);

  bool braced = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE);

  unsigned mk = module_kind;
  if (module_exporting_p ())
    error_at (token->location,
	      "%qE may only occur once in an export declaration",
	      token->u.value);
  module_kind |= MK_EXPORTING;

  if (braced)
    {
      cp_ensure_no_omp_declare_simd (parser);
      cp_ensure_no_oacc_routine (parser);

      cp_lexer_consume_token (parser->lexer);
      cp_parser_declaration_seq_opt (parser);
      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
    }
  else
    {
      /* Explicitly check if the next tokens might be a
         module-directive line, so we can give a clearer error message
         about why the directive will be rejected.  */
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID__MODULE)
	  || cp_lexer_next_token_is_keyword (parser->lexer, RID__IMPORT)
	  || cp_lexer_next_token_is_keyword (parser->lexer, RID__EXPORT))
	error_at (token->location, "%<export%> not part of following"
		  " module-directive");
      cp_parser_declaration (parser, NULL_TREE);
    }

  module_kind = mk;
}

/* Declarations [gram.dcl.dcl] */

/* Parse an optional declaration-sequence.  TOP_LEVEL is true, if this
   is the top-level declaration sequence.  That affects whether we
   deal with module-preamble.

   declaration-seq:
     declaration
     declaration-seq declaration  */

static void
cp_parser_declaration_seq_opt (cp_parser* parser)
{
  while (true)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      if (token->type == CPP_CLOSE_BRACE
	  || token->type == CPP_EOF)
	break;
      else
	cp_parser_toplevel_declaration (parser);
    }
}

/* Parse a declaration.

   declaration:
     block-declaration
     function-definition
     template-declaration
     explicit-instantiation
     explicit-specialization
     linkage-specification
     namespace-definition

   C++17:
     deduction-guide

   modules:
     (all these are only allowed at the outermost level, check
   	that semantically, for better diagnostics)
     module-declaration
     module-export-declaration
     module-import-declaration
     export-declaration

   GNU extension:

   declaration:
      __extension__ declaration */

static void
cp_parser_declaration (cp_parser* parser, tree prefix_attrs)
{
  int saved_pedantic;

  /* Check for the `__extension__' keyword.  */
  if (cp_parser_extension_opt (parser, &saved_pedantic))
    {
      /* Parse the qualified declaration.  */
      cp_parser_declaration (parser, prefix_attrs);
      /* Restore the PEDANTIC flag.  */
      pedantic = saved_pedantic;

      return;
    }

  /* Try to figure out what kind of declaration is present.  */
  cp_token *token1 = cp_lexer_peek_token (parser->lexer);
  cp_token *token2 = (token1->type == CPP_EOF
		      ? token1 : cp_lexer_peek_nth_token (parser->lexer, 2));

  if (token1->type == CPP_SEMICOLON)
    {
      cp_lexer_consume_token (parser->lexer);
      /* A declaration consisting of a single semicolon is invalid
       * before C++11.  Allow it unless we're being pedantic.  */
      if (cxx_dialect < cxx11)
	pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
      return;
    }
  else if (cp_lexer_nth_token_is (parser->lexer,
				  cp_parser_skip_std_attribute_spec_seq (parser,
									 1),
				  CPP_SEMICOLON))
    {
      location_t attrs_loc = token1->location;
      tree std_attrs = cp_parser_std_attribute_spec_seq (parser);

      if (std_attrs && (flag_openmp || flag_openmp_simd))
	{
	  gcc_assert (!parser->lexer->in_omp_attribute_pragma);
	  std_attrs = cp_parser_handle_statement_omp_attributes (parser,
								 std_attrs);
	  if (parser->lexer->in_omp_attribute_pragma)
	    {
	      cp_lexer *lexer = parser->lexer;
	      while (parser->lexer->in_omp_attribute_pragma)
		{
		  gcc_assert (cp_lexer_next_token_is (parser->lexer,
						      CPP_PRAGMA));
		  cp_parser_pragma (parser, pragma_external, NULL);
		}
	      cp_lexer_destroy (lexer);
	    }
	}

      if (std_attrs != NULL_TREE && !attribute_ignored_p (std_attrs))
	warning_at (make_location (attrs_loc, attrs_loc, parser->lexer),
		    OPT_Wattributes, "attribute ignored");
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	cp_lexer_consume_token (parser->lexer);
      return;
    }

  /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
  void *p = obstack_alloc (&declarator_obstack, 0);

  tree attributes = NULL_TREE;

  /* Conditionally, allow attributes to precede a linkage specification.  */
  if (token1->keyword == RID_ATTRIBUTE)
    {
      cp_lexer_save_tokens (parser->lexer);
      attributes = cp_parser_attributes_opt (parser);
      cp_token *t1 = cp_lexer_peek_token (parser->lexer);
      cp_token *t2 = (t1->type == CPP_EOF
		      ? t1 : cp_lexer_peek_nth_token (parser->lexer, 2));
      if (t1->keyword == RID_EXTERN
	  && cp_parser_is_pure_string_literal (t2))
	{
	  cp_lexer_commit_tokens (parser->lexer);
	  /* We might have already been here.  */
	  if (!c_dialect_objc ())
	    {
	      location_t where = get_finish (t2->location);
	      warning_at (token1->location, OPT_Wattributes, "attributes are"
			  " not permitted in this position");
	      where = linemap_position_for_loc_and_offset (line_table,
							   where, 1);
	      inform (where, "attributes may be inserted here");
	      attributes = NULL_TREE;
	    }
	  token1 = t1;
	  token2 = t2;
	}
      else
	{
	  cp_lexer_rollback_tokens (parser->lexer);
	  attributes = NULL_TREE;
	}
    }
  /* If we already had some attributes, and we've added more, then prepend.
     Otherwise attributes just contains any that we just read.  */
  if (prefix_attrs)
    {
      if (attributes)
	TREE_CHAIN (prefix_attrs) = attributes;
      attributes = prefix_attrs;
    }

  /* If the next token is `extern' and the following token is a string
     literal, then we have a linkage specification.  */
  if (token1->keyword == RID_EXTERN
      && cp_parser_is_pure_string_literal (token2))
    cp_parser_linkage_specification (parser, attributes);
  /* If the next token is `template', then we have either a template
     declaration, an explicit instantiation, or an explicit
     specialization.  */
  else if (token1->keyword == RID_TEMPLATE)
    {
      /* `template <>' indicates a template specialization.  */
      if (token2->type == CPP_LESS
	  && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
	cp_parser_explicit_specialization (parser);
      /* `template <' indicates a template declaration.  */
      else if (token2->type == CPP_LESS)
	cp_parser_template_declaration (parser, /*member_p=*/false);
      /* Anything else must be an explicit instantiation.  */
      else
	cp_parser_explicit_instantiation (parser);
    }
  /* If the next token is `export', it's new-style modules or
     old-style template.  */
  else if (token1->keyword == RID_EXPORT)
    {
      if (!modules_p ())
	cp_parser_template_declaration (parser, /*member_p=*/false);
      else
	cp_parser_module_export (parser);
    }
  else if (cp_token_is_module_directive (token1))
    {
      bool exporting = token1->keyword == RID__EXPORT;
      cp_token *next = exporting ? token2 : token1;
      if (exporting)
	cp_lexer_consume_token (parser->lexer);
      // In module purview this will be ill-formed.
      auto state = (!named_module_p () ? MP_NOT_MODULE
		    : module_purview_p () ? MP_PURVIEW
		    : MP_GLOBAL);
      if (next->keyword == RID__MODULE)
	cp_parser_module_declaration (parser, state, exporting);
      else
	cp_parser_import_declaration (parser, state, exporting);
    }
  /* If the next token is `extern', 'static' or 'inline' and the one
     after that is `template', we have a GNU extended explicit
     instantiation directive.  */
  else if (cp_parser_allow_gnu_extensions_p (parser)
	   && token2->keyword == RID_TEMPLATE
	   && (token1->keyword == RID_EXTERN
	       || token1->keyword == RID_STATIC
	       || token1->keyword == RID_INLINE))
    cp_parser_explicit_instantiation (parser);
  /* If the next token is `namespace', check for a named or unnamed
     namespace definition.  */
  else if (token1->keyword == RID_NAMESPACE
	   && (/* A named namespace definition.  */
	       (token2->type == CPP_NAME
		&& (cp_lexer_peek_nth_token (parser->lexer, 3)->type
		    != CPP_EQ))
               || (token2->type == CPP_OPEN_SQUARE
                   && cp_lexer_peek_nth_token (parser->lexer, 3)->type
                   == CPP_OPEN_SQUARE)
	       /* An unnamed namespace definition.  */
	       || token2->type == CPP_OPEN_BRACE
	       || token2->keyword == RID_ATTRIBUTE))
    cp_parser_namespace_definition (parser);
  /* An inline (associated) namespace definition.  */
  else if (token2->keyword == RID_NAMESPACE
	   && token1->keyword == RID_INLINE)
    cp_parser_namespace_definition (parser);
  /* Objective-C++ declaration/definition.  */
  else if (c_dialect_objc () && OBJC_IS_AT_KEYWORD (token1->keyword))
    cp_parser_objc_declaration (parser, attributes);
  else if (c_dialect_objc ()
	   && token1->keyword == RID_ATTRIBUTE
	   && cp_parser_objc_valid_prefix_attributes (parser, &attributes))
    cp_parser_objc_declaration (parser, attributes);
  /* At this point we may have a template declared by a concept
     introduction.  */
  else if (flag_concepts
	   && cp_parser_template_declaration_after_export (parser,
							   /*member_p=*/false))
    /* We did.  */;
  else
    /* Try to parse a block-declaration, or a function-definition.  */
    cp_parser_block_declaration (parser, /*statement_p=*/false);

  /* Free any declarators allocated.  */
  obstack_free (&declarator_obstack, p);
}

/* Parse a namespace-scope declaration.  */

static void
cp_parser_toplevel_declaration (cp_parser* parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  if (token->type == CPP_PRAGMA)
    /* A top-level declaration can consist solely of a #pragma.  A
       nested declaration cannot, so this is done here and not in
       cp_parser_declaration.  (A #pragma at block scope is
       handled in cp_parser_statement.)  */
    cp_parser_pragma (parser, pragma_external, NULL);
  else
    /* Parse the declaration itself.  */
    cp_parser_declaration (parser, NULL_TREE);
}

/* Parse a block-declaration.

   block-declaration:
     simple-declaration
     asm-definition
     namespace-alias-definition
     using-declaration
     using-directive

   GNU Extension:

   block-declaration:
     __extension__ block-declaration

   C++0x Extension:

   block-declaration:
     static_assert-declaration

   If STATEMENT_P is TRUE, then this block-declaration is occurring as
   part of a declaration-statement.  */

static void
cp_parser_block_declaration (cp_parser *parser,
			     bool      statement_p)
{
  int saved_pedantic;

  /* Check for the `__extension__' keyword.  */
  if (cp_parser_extension_opt (parser, &saved_pedantic))
    {
      /* Parse the qualified declaration.  */
      cp_parser_block_declaration (parser, statement_p);
      /* Restore the PEDANTIC flag.  */
      pedantic = saved_pedantic;

      return;
    }

  /* Peek at the next token to figure out which kind of declaration is
     present.  */
  cp_token *token1 = cp_lexer_peek_token (parser->lexer);
  size_t attr_idx;

  /* If the next keyword is `asm', we have an asm-definition.  */
  if (token1->keyword == RID_ASM)
    {
      if (statement_p)
	cp_parser_commit_to_tentative_parse (parser);
      cp_parser_asm_definition (parser);
    }
  /* If the next keyword is `namespace', we have a
     namespace-alias-definition.  */
  else if (token1->keyword == RID_NAMESPACE)
    cp_parser_namespace_alias_definition (parser);
  /* If the next keyword is `using', we have a
     using-declaration, a using-directive, or an alias-declaration.  */
  else if (token1->keyword == RID_USING)
    {
      cp_token *token2;

      if (statement_p)
	cp_parser_commit_to_tentative_parse (parser);
      /* If the token after `using' is `namespace', then we have a
	 using-directive.  */
      token2 = cp_lexer_peek_nth_token (parser->lexer, 2);
      if (token2->keyword == RID_NAMESPACE)
	cp_parser_using_directive (parser);
      else if (token2->keyword == RID_ENUM)
	cp_parser_using_enum (parser);
      /* If the second token after 'using' is '=', then we have an
	 alias-declaration.  */
      else if (cxx_dialect >= cxx11
	       && token2->type == CPP_NAME
	       && ((cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ)
		   || (cp_nth_tokens_can_be_attribute_p (parser, 3))))
	cp_parser_alias_declaration (parser);
      /* Otherwise, it's a using-declaration.  */
      else
	cp_parser_using_declaration (parser,
				     /*access_declaration_p=*/false);
    }
  /* If the next keyword is `__label__' we have a misplaced label
     declaration.  */
  else if (token1->keyword == RID_LABEL)
    {
      cp_lexer_consume_token (parser->lexer);
      error_at (token1->location, "%<__label__%> not at the beginning of a block");
      cp_parser_skip_to_end_of_statement (parser);
      /* If the next token is now a `;', consume it.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	cp_lexer_consume_token (parser->lexer);
    }
  /* If the next token is `static_assert' we have a static assertion.  */
  else if (token1->keyword == RID_STATIC_ASSERT)
    cp_parser_static_assert (parser, /*member_p=*/false);
  /* If the next tokens after attributes is `using namespace', then we have
     a using-directive.  */
  else if ((attr_idx = cp_parser_skip_std_attribute_spec_seq (parser, 1)) != 1
	   && cp_lexer_nth_token_is_keyword (parser->lexer, attr_idx,
					     RID_USING)
	   && cp_lexer_nth_token_is_keyword (parser->lexer, attr_idx + 1,
					     RID_NAMESPACE))
    {
      if (statement_p)
	cp_parser_commit_to_tentative_parse (parser);
      cp_parser_using_directive (parser);
    }
  /* Anything else must be a simple-declaration.  */
  else
    cp_parser_simple_declaration (parser, !statement_p,
				  /*maybe_range_for_decl*/NULL);
}

/* Parse a simple-declaration.

   simple-declaration:
     decl-specifier-seq [opt] init-declarator-list [opt] ;
     decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
       brace-or-equal-initializer ;

   init-declarator-list:
     init-declarator
     init-declarator-list , init-declarator

   If FUNCTION_DEFINITION_ALLOWED_P is TRUE, then we also recognize a
   function-definition as a simple-declaration.

   If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
   parsed declaration if it is an uninitialized single declarator not followed
   by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
   if present, will not be consumed.  */

static void
cp_parser_simple_declaration (cp_parser* parser,
			      bool function_definition_allowed_p,
			      tree *maybe_range_for_decl)
{
  cp_decl_specifier_seq decl_specifiers;
  int declares_class_or_enum;
  bool saw_declarator;
  location_t comma_loc = UNKNOWN_LOCATION;
  location_t init_loc = UNKNOWN_LOCATION;

  if (maybe_range_for_decl)
    *maybe_range_for_decl = NULL_TREE;

  /* Defer access checks until we know what is being declared; the
     checks for names appearing in the decl-specifier-seq should be
     done as if we were in the scope of the thing being declared.  */
  push_deferring_access_checks (dk_deferred);

  /* Parse the decl-specifier-seq.  We have to keep track of whether
     or not the decl-specifier-seq declares a named class or
     enumeration type, since that is the only case in which the
     init-declarator-list is allowed to be empty.

     [dcl.dcl]

     In a simple-declaration, the optional init-declarator-list can be
     omitted only when declaring a class or enumeration, that is when
     the decl-specifier-seq contains either a class-specifier, an
     elaborated-type-specifier, or an enum-specifier.  */
  cp_parser_decl_specifier_seq (parser,
				CP_PARSER_FLAGS_OPTIONAL,
				&decl_specifiers,
				&declares_class_or_enum);
  /* We no longer need to defer access checks.  */
  stop_deferring_access_checks ();

  cp_omp_declare_simd_data odsd;
  if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
    cp_parser_handle_directive_omp_attributes (parser,
					       &decl_specifiers.attributes,
					       &odsd, true);

  /* In a block scope, a valid declaration must always have a
     decl-specifier-seq.  By not trying to parse declarators, we can
     resolve the declaration/expression ambiguity more quickly.  */
  if (!function_definition_allowed_p
      && !decl_specifiers.any_specifiers_p)
    {
      cp_parser_error (parser, "expected declaration");
      goto done;
    }

  /* If the next two tokens are both identifiers, the code is
     erroneous. The usual cause of this situation is code like:

       T t;

     where "T" should name a type -- but does not.  */
  if (!decl_specifiers.any_type_specifiers_p
      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
    {
      /* If parsing tentatively, we should commit; we really are
	 looking at a declaration.  */
      cp_parser_commit_to_tentative_parse (parser);
      /* Give up.  */
      goto done;
    }

  cp_parser_maybe_commit_to_declaration (parser, &decl_specifiers);

  /* Look for C++17 decomposition declaration.  */
  for (size_t n = 1; ; n++)
    if (cp_lexer_nth_token_is (parser->lexer, n, CPP_AND)
	|| cp_lexer_nth_token_is (parser->lexer, n, CPP_AND_AND))
      continue;
    else if (cp_lexer_nth_token_is (parser->lexer, n, CPP_OPEN_SQUARE)
	     && !cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_SQUARE)
	     && decl_specifiers.any_specifiers_p)
      {
	tree decl
	  = cp_parser_decomposition_declaration (parser, &decl_specifiers,
						 maybe_range_for_decl,
						 &init_loc);

	/* The next token should be either a `,' or a `;'.  */
	cp_token *token = cp_lexer_peek_token (parser->lexer);
	/* If it's a `;', we are done.  */
	if (token->type == CPP_SEMICOLON)
	  goto finish;
	else if (maybe_range_for_decl)
	  {
	    if (*maybe_range_for_decl == NULL_TREE)
	      *maybe_range_for_decl = error_mark_node;
	    goto finish;
	  }
	/* Anything else is an error.  */
	else
	  {
	    /* If we have already issued an error message we don't need
	       to issue another one.  */
	    if ((decl != error_mark_node
		 && DECL_INITIAL (decl) != error_mark_node)
		|| cp_parser_uncommitted_to_tentative_parse_p (parser))
	      cp_parser_error (parser, "expected %<;%>");
	    /* Skip tokens until we reach the end of the statement.  */
	    cp_parser_skip_to_end_of_statement (parser);
	    /* If the next token is now a `;', consume it.  */
	    if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	      cp_lexer_consume_token (parser->lexer);
	    goto done;
	  }
      }
    else
      break;

  tree last_type;
  bool auto_specifier_p;
  /* NULL_TREE if both variable and function declaration are allowed,
     error_mark_node if function declaration are not allowed and
     a FUNCTION_DECL that should be diagnosed if it is followed by
     variable declarations.  */
  tree auto_function_declaration;

  last_type = NULL_TREE;
  auto_specifier_p
    = decl_specifiers.type && type_uses_auto (decl_specifiers.type);
  auto_function_declaration = NULL_TREE;

  /* Keep going until we hit the `;' at the end of the simple
     declaration.  */
  saw_declarator = false;
  while (cp_lexer_next_token_is_not (parser->lexer,
				     CPP_SEMICOLON))
    {
      cp_token *token;
      bool function_definition_p;
      tree decl;
      tree auto_result = NULL_TREE;

      if (saw_declarator)
	{
	  /* If we are processing next declarator, comma is expected */
	  token = cp_lexer_peek_token (parser->lexer);
	  gcc_assert (token->type == CPP_COMMA);
	  cp_lexer_consume_token (parser->lexer);
	  if (maybe_range_for_decl)
	    {
	      *maybe_range_for_decl = error_mark_node;
	      if (comma_loc == UNKNOWN_LOCATION)
		comma_loc = token->location;
	    }
	}
      else
	saw_declarator = true;

      /* Parse the init-declarator.  */
      decl = cp_parser_init_declarator (parser,
					CP_PARSER_FLAGS_NONE,
					&decl_specifiers,
					/*checks=*/NULL,
					function_definition_allowed_p,
					/*member_p=*/false,
					declares_class_or_enum,
					&function_definition_p,
					maybe_range_for_decl,
					&init_loc,
					&auto_result);
      /* If an error occurred while parsing tentatively, exit quickly.
	 (That usually happens when in the body of a function; each
	 statement is treated as a declaration-statement until proven
	 otherwise.)  */
      if (cp_parser_error_occurred (parser))
	goto done;

      if (auto_specifier_p && cxx_dialect >= cxx14)
	{
	  /* If the init-declarator-list contains more than one
	     init-declarator, they shall all form declarations of
	     variables.  */
	  if (auto_function_declaration == NULL_TREE)
	    auto_function_declaration
	      = TREE_CODE (decl) == FUNCTION_DECL ? decl : error_mark_node;
	  else if (TREE_CODE (decl) == FUNCTION_DECL
		   || auto_function_declaration != error_mark_node)
	    {
	      error_at (decl_specifiers.locations[ds_type_spec],
			"non-variable %qD in declaration with more than one "
			"declarator with placeholder type",
			TREE_CODE (decl) == FUNCTION_DECL
			? decl : auto_function_declaration);
	      auto_function_declaration = error_mark_node;
	    }
	}

      if (auto_result
	  && (!processing_template_decl || !type_uses_auto (auto_result)))
	{
	  if (last_type
	      && last_type != error_mark_node
	      && !same_type_p (auto_result, last_type))
	    {
	      /* If the list of declarators contains more than one declarator,
		 the type of each declared variable is determined as described
		 above. If the type deduced for the template parameter U is not
		 the same in each deduction, the program is ill-formed.  */
	      error_at (decl_specifiers.locations[ds_type_spec],
			"inconsistent deduction for %qT: %qT and then %qT",
			decl_specifiers.type, last_type, auto_result);
	      last_type = error_mark_node;
	    }
	  else
	    last_type = auto_result;
	}

      /* Handle function definitions specially.  */
      if (function_definition_p)
	{
	  /* If the next token is a `,', then we are probably
	     processing something like:

	       void f() {}, *p;

	     which is erroneous.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	    {
	      cp_token *token = cp_lexer_peek_token (parser->lexer);
	      error_at (token->location,
			"mixing"
			" declarations and function-definitions is forbidden");
	    }
	  /* Otherwise, we're done with the list of declarators.  */
	  else
	    {
	      pop_deferring_access_checks ();
	      cp_finalize_omp_declare_simd (parser, &odsd);
	      return;
	    }
	}
      if (maybe_range_for_decl && *maybe_range_for_decl == NULL_TREE)
	*maybe_range_for_decl = decl;
      /* The next token should be either a `,' or a `;'.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* If it's a `,', there are more declarators to come.  */
      if (token->type == CPP_COMMA)
	/* will be consumed next time around */;
      /* If it's a `;', we are done.  */
      else if (token->type == CPP_SEMICOLON)
	break;
      else if (maybe_range_for_decl)
	{
	  if ((declares_class_or_enum & 2) && token->type == CPP_COLON)
	    permerror (decl_specifiers.locations[ds_type_spec],
		       "types may not be defined in a for-range-declaration");
	  break;
	}
      /* Anything else is an error.  */
      else
	{
	  /* If we have already issued an error message we don't need
	     to issue another one.  */
	  if ((decl != error_mark_node
	       && DECL_INITIAL (decl) != error_mark_node)
	      || cp_parser_uncommitted_to_tentative_parse_p (parser))
	    cp_parser_error (parser, "expected %<,%> or %<;%>");
	  /* Skip tokens until we reach the end of the statement.  */
	  cp_parser_skip_to_end_of_statement (parser);
	  /* If the next token is now a `;', consume it.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	    cp_lexer_consume_token (parser->lexer);
	  goto done;
	}
      /* After the first time around, a function-definition is not
	 allowed -- even if it was OK at first.  For example:

	   int i, f() {}

	 is not valid.  */
      function_definition_allowed_p = false;
    }

  /* Issue an error message if no declarators are present, and the
     decl-specifier-seq does not itself declare a class or
     enumeration: [dcl.dcl]/3.  */
  if (!saw_declarator)
    {
      if (cp_parser_declares_only_class_p (parser))
	{
	  if (!declares_class_or_enum
	      && decl_specifiers.type
	      && OVERLOAD_TYPE_P (decl_specifiers.type))
	    /* Ensure an error is issued anyway when finish_decltype_type,
	       called via cp_parser_decl_specifier_seq, returns a class or
	       an enumeration (c++/51786).  */
	    decl_specifiers.type = NULL_TREE;
	  shadow_tag (&decl_specifiers);
	}
      /* Perform any deferred access checks.  */
      perform_deferred_access_checks (tf_warning_or_error);
    }

  /* Consume the `;'.  */
 finish:
  if (!maybe_range_for_decl)
    cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
  else if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      if (init_loc != UNKNOWN_LOCATION)
	error_at (init_loc, "initializer in range-based %<for%> loop");
      if (comma_loc != UNKNOWN_LOCATION)
	error_at (comma_loc,
		  "multiple declarations in range-based %<for%> loop");
    }

 done:
  pop_deferring_access_checks ();
  cp_finalize_omp_declare_simd (parser, &odsd);
}

/* Helper of cp_parser_simple_declaration, parse a decomposition declaration.
     decl-specifier-seq ref-qualifier [opt] [ identifier-list ]
       initializer ;  */

static tree
cp_parser_decomposition_declaration (cp_parser *parser,
				     cp_decl_specifier_seq *decl_specifiers,
				     tree *maybe_range_for_decl,
				     location_t *init_loc)
{
  cp_ref_qualifier ref_qual = cp_parser_ref_qualifier_opt (parser);
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
  cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE);

  /* Parse the identifier-list.  */
  auto_vec<cp_expr, 10> v;
  if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
    while (true)
      {
	cp_expr e = cp_parser_identifier (parser);
	if (e.get_value () == error_mark_node)
	  break;
	v.safe_push (e);
	if (!cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	  break;
	cp_lexer_consume_token (parser->lexer);
      }

  location_t end_loc = cp_lexer_peek_token (parser->lexer)->location;
  if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
    {
      end_loc = UNKNOWN_LOCATION;
      cp_parser_skip_to_closing_parenthesis_1 (parser, true, CPP_CLOSE_SQUARE,
					       false);
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
	cp_lexer_consume_token (parser->lexer);
      else
	{
	  cp_parser_skip_to_end_of_statement (parser);
	  return error_mark_node;
	}
    }

  if (cxx_dialect < cxx17)
    pedwarn (loc, OPT_Wc__17_extensions,
	     "structured bindings only available with "
	     "%<-std=c++17%> or %<-std=gnu++17%>");

  tree pushed_scope;
  cp_declarator *declarator = make_declarator (cdk_decomp);
  loc = end_loc == UNKNOWN_LOCATION ? loc : make_location (loc, loc, end_loc);
  declarator->id_loc = loc;
  if (ref_qual != REF_QUAL_NONE)
    declarator = make_reference_declarator (TYPE_UNQUALIFIED, declarator,
					    ref_qual == REF_QUAL_RVALUE,
					    NULL_TREE);
  tree decl = start_decl (declarator, decl_specifiers, SD_INITIALIZED,
			  NULL_TREE, decl_specifiers->attributes,
			  &pushed_scope);
  tree orig_decl = decl;

  unsigned int i;
  cp_expr e;
  cp_decl_specifier_seq decl_specs;
  clear_decl_specs (&decl_specs);
  decl_specs.type = make_auto ();
  tree prev = decl;
  FOR_EACH_VEC_ELT (v, i, e)
    {
      if (i == 0)
	declarator = make_id_declarator (NULL_TREE, e.get_value (),
					 sfk_none, e.get_location ());
      else
	{
	  declarator->u.id.unqualified_name = e.get_value ();
	  declarator->id_loc = e.get_location ();
	}
      tree elt_pushed_scope;
      tree decl2 = start_decl (declarator, &decl_specs, SD_DECOMPOSITION,
			       NULL_TREE, NULL_TREE, &elt_pushed_scope);
      if (decl2 == error_mark_node)
	decl = error_mark_node;
      else if (decl != error_mark_node && DECL_CHAIN (decl2) != prev)
	{
	  /* Ensure we've diagnosed redeclaration if we aren't creating
	     a new VAR_DECL.  */
	  gcc_assert (errorcount);
	  decl = error_mark_node;
	}
      else
	prev = decl2;
      if (elt_pushed_scope)
	pop_scope (elt_pushed_scope);
    }

  if (v.is_empty ())
    {
      error_at (loc, "empty structured binding declaration");
      decl = error_mark_node;
    }

  if (maybe_range_for_decl == NULL
      || cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
    {
      bool non_constant_p = false, is_direct_init = false;
      *init_loc = cp_lexer_peek_token (parser->lexer)->location;
      tree initializer = cp_parser_initializer (parser, &is_direct_init,
						&non_constant_p);
      if (initializer == NULL_TREE
	  || (TREE_CODE (initializer) == TREE_LIST
	      && TREE_CHAIN (initializer))
	  || (is_direct_init
	      && BRACE_ENCLOSED_INITIALIZER_P (initializer)
	      && CONSTRUCTOR_NELTS (initializer) != 1))
	{
	  error_at (loc, "invalid initializer for structured binding "
		    "declaration");
	  initializer = error_mark_node;
	}

      if (decl != error_mark_node)
	{
	  cp_maybe_mangle_decomp (decl, prev, v.length ());
	  cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE,
			  (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
	  cp_finish_decomp (decl, prev, v.length ());
	}
    }
  else if (decl != error_mark_node)
    {
      *maybe_range_for_decl = prev;
      /* Ensure DECL_VALUE_EXPR is created for all the decls but
	 the underlying DECL.  */
      cp_finish_decomp (decl, prev, v.length ());
    }

  if (pushed_scope)
    pop_scope (pushed_scope);

  if (decl == error_mark_node && DECL_P (orig_decl))
    {
      if (DECL_NAMESPACE_SCOPE_P (orig_decl))
	SET_DECL_ASSEMBLER_NAME (orig_decl, get_identifier ("<decomp>"));
    }

  return decl;
}

/* Names of storage classes.  */

static const char *const
cp_storage_class_name[] = {
  "", "auto", "register", "static", "extern", "mutable"
};

/* Parse a decl-specifier-seq.

   decl-specifier-seq:
     decl-specifier-seq [opt] decl-specifier
     decl-specifier attribute-specifier-seq [opt] (C++11)

   decl-specifier:
     storage-class-specifier
     type-specifier
     function-specifier
     friend
     typedef

   GNU Extension:

   decl-specifier:
     attributes

   Concepts Extension:

   decl-specifier:
     concept

   Set *DECL_SPECS to a representation of the decl-specifier-seq.

   The parser flags FLAGS is used to control type-specifier parsing.

   *DECLARES_CLASS_OR_ENUM is set to the bitwise or of the following
   flags:

     1: one of the decl-specifiers is an elaborated-type-specifier
	(i.e., a type declaration)
     2: one of the decl-specifiers is an enum-specifier or a
	class-specifier (i.e., a type definition)

   */

static void
cp_parser_decl_specifier_seq (cp_parser* parser,
			      cp_parser_flags flags,
			      cp_decl_specifier_seq *decl_specs,
			      int* declares_class_or_enum)
{
  bool constructor_possible_p = !parser->in_declarator_p;
  bool found_decl_spec = false;
  cp_token *start_token = NULL;
  cp_decl_spec ds;

  /* Clear DECL_SPECS.  */
  clear_decl_specs (decl_specs);

  /* Assume no class or enumeration type is declared.  */
  *declares_class_or_enum = 0;

  /* Keep reading specifiers until there are no more to read.  */
  while (true)
    {
      bool constructor_p;
      cp_token *token;
      ds = ds_last;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);

      /* Save the first token of the decl spec list for error
         reporting.  */
      if (!start_token)
	start_token = token;
      /* Handle attributes.  */
      if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) == 0
	  && cp_next_tokens_can_be_attribute_p (parser))
	{
	  /* Parse the attributes.  */
	  tree attrs = cp_parser_attributes_opt (parser);

	  /* In a sequence of declaration specifiers, c++11 attributes
	     appertain to the type that precede them. In that case
	     [dcl.spec]/1 says:

	         The attribute-specifier-seq affects the type only for
		 the declaration it appears in, not other declarations
		 involving the same type.

             But for now let's force the user to position the
             attribute either at the beginning of the declaration or
             after the declarator-id, which would clearly mean that it
             applies to the declarator.  */
	  if (cxx11_attribute_p (attrs))
	    {
	      if (!found_decl_spec)
		/* The c++11 attribute is at the beginning of the
		   declaration.  It appertains to the entity being
		   declared.  */;
	      else
		{
		  if (find_contract (attrs))
		    {
		      diagnose_misapplied_contracts (attrs);
		      attrs = NULL_TREE;
		    }
		  else if (decl_specs->type && CLASS_TYPE_P (decl_specs->type))
		    {
		      /*  This is an attribute following a
			  class-specifier.  */
		      if (decl_specs->type_definition_p)
			warn_misplaced_attr_for_class_type (token->location,
							    decl_specs->type);
		      attrs = NULL_TREE;
		    }
		  else
		    {
		      decl_specs->std_attributes
			= attr_chainon (decl_specs->std_attributes, attrs);
		      if (decl_specs->locations[ds_std_attribute] == 0)
			decl_specs->locations[ds_std_attribute] = token->location;
		    }
		  continue;
		}
	    }

	  decl_specs->attributes
	    = attr_chainon (decl_specs->attributes, attrs);
	  if (decl_specs->locations[ds_attribute] == 0)
	    decl_specs->locations[ds_attribute] = token->location;
	  continue;
	}
      /* Assume we will find a decl-specifier keyword.  */
      found_decl_spec = true;
      /* If the next token is an appropriate keyword, we can simply
	 add it to the list.  */
      switch (token->keyword)
	{
	  /* decl-specifier:
	       friend
	       constexpr
	       constinit */
	case RID_FRIEND:
	  if (!at_class_scope_p ())
	    {
	      gcc_rich_location richloc (token->location);
	      richloc.add_fixit_remove ();
	      error_at (&richloc, "%<friend%> used outside of class");
	      cp_lexer_purge_token (parser->lexer);
	    }
	  else
	    {
	      ds = ds_friend;
	      /* Consume the token.  */
	      cp_lexer_consume_token (parser->lexer);
	    }
	  break;

        case RID_CONSTEXPR:
	  ds = ds_constexpr;
          cp_lexer_consume_token (parser->lexer);
          break;

	case RID_CONSTINIT:
	  ds = ds_constinit;
	  cp_lexer_consume_token (parser->lexer);
	  break;

	case RID_CONSTEVAL:
	  ds = ds_consteval;
	  cp_lexer_consume_token (parser->lexer);
	  break;

        case RID_CONCEPT:
          ds = ds_concept;
          cp_lexer_consume_token (parser->lexer);

	  if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
	    break;

          /* Warn for concept as a decl-specifier. We'll rewrite these as
             concept declarations later.  */
          if (!flag_concepts_ts)
            {
	      cp_token *next = cp_lexer_peek_token (parser->lexer);
	      if (next->keyword == RID_BOOL)
		permerror (next->location, "the %<bool%> keyword is not "
			   "allowed in a C++20 concept definition");
	      else
		error_at (token->location, "C++20 concept definition syntax "
			  "is %<concept <name> = <expr>%>");
            }

	  /* In C++20 a concept definition is just 'concept name = expr;'
	     Support that syntax as a TS extension by pretending we've seen
	     the 'bool' specifier.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_EQ)
	      && !decl_specs->any_type_specifiers_p)
	    {
	      cp_parser_set_decl_spec_type (decl_specs, boolean_type_node,
					    token, /*type_definition*/false);
	      decl_specs->any_type_specifiers_p = true;
	    }
          break;

	  /* function-specifier:
	       inline
	       virtual
	       explicit  */
	case RID_INLINE:
	case RID_VIRTUAL:
	case RID_EXPLICIT:
	  cp_parser_function_specifier_opt (parser, decl_specs);
	  break;

	  /* decl-specifier:
	       typedef  */
	case RID_TYPEDEF:
	  ds = ds_typedef;
	  /* Consume the token.  */
	  cp_lexer_consume_token (parser->lexer);

	  if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
	    break;

	  /* A constructor declarator cannot appear in a typedef.  */
	  constructor_possible_p = false;
	  /* The "typedef" keyword can only occur in a declaration; we
	     may as well commit at this point.  */
	  cp_parser_commit_to_tentative_parse (parser);

	  if (decl_specs->storage_class != sc_none)
	    {
	      if (decl_specs->conflicting_specifiers_p)
		break;
	      gcc_rich_location richloc (token->location);
	      location_t oloc = decl_specs->locations[ds_storage_class];
	      richloc.add_location_if_nearby (oloc);
	      error_at (&richloc,
			"%<typedef%> specifier conflicts with %qs",
			cp_storage_class_name[decl_specs->storage_class]);
	      decl_specs->conflicting_specifiers_p = true;
	    }
	  break;

	  /* storage-class-specifier:
	       auto
	       register
	       static
	       extern
	       mutable

	     GNU Extension:
	       thread  */
	case RID_AUTO:
          if (cxx_dialect == cxx98)
            {
	      /* Consume the token.  */
	      cp_lexer_consume_token (parser->lexer);

	      /* Complain about `auto' as a storage specifier, if
		 we're complaining about C++0x compatibility.  */
	      gcc_rich_location richloc (token->location);
	      richloc.add_fixit_remove ();
	      warning_at (&richloc, OPT_Wc__11_compat,
			  "%<auto%> changes meaning in C++11; "
			  "please remove it");

              /* Set the storage class anyway.  */
              cp_parser_set_storage_class (parser, decl_specs, RID_AUTO,
					   token);
            }
          else
	    /* C++0x auto type-specifier.  */
	    found_decl_spec = false;
          break;

	case RID_REGISTER:
	case RID_STATIC:
	case RID_EXTERN:
	case RID_MUTABLE:
	  /* Consume the token.  */
	  cp_lexer_consume_token (parser->lexer);
          cp_parser_set_storage_class (parser, decl_specs, token->keyword,
				       token);
	  break;
	case RID_THREAD:
	  /* Consume the token.  */
	  ds = ds_thread;
	  cp_lexer_consume_token (parser->lexer);
	  break;

	default:
	  /* We did not yet find a decl-specifier yet.  */
	  found_decl_spec = false;
	  break;
	}

      if (found_decl_spec
	  && (flags & CP_PARSER_FLAGS_ONLY_TYPE_OR_CONSTEXPR)
	  && token->keyword != RID_CONSTEXPR)
	error ("%qD invalid in condition", ridpointers[token->keyword]);

      if (found_decl_spec
	  && (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
	  && token->keyword != RID_MUTABLE
	  && token->keyword != RID_CONSTEXPR
	  && token->keyword != RID_CONSTEVAL)
	{
	  if (token->keyword != RID_STATIC)
	    error_at (token->location, "%qD invalid in lambda",
		      ridpointers[token->keyword]);
	  else if (cxx_dialect < cxx23)
	    pedwarn (token->location, OPT_Wc__23_extensions,
		     "%qD only valid in lambda with %<-std=c++23%> or "
		     "%<-std=gnu++23%>", ridpointers[token->keyword]);
	}

      if (ds != ds_last)
	set_and_check_decl_spec_loc (decl_specs, ds, token);

      /* Constructors are a special case.  The `S' in `S()' is not a
	 decl-specifier; it is the beginning of the declarator.  */
      constructor_p
	= (!found_decl_spec
	   && constructor_possible_p
	   && (cp_parser_constructor_declarator_p
	       (parser, flags, decl_spec_seq_has_spec_p (decl_specs,
							 ds_friend))));

      /* If we don't have a DECL_SPEC yet, then we must be looking at
	 a type-specifier.  */
      if (!found_decl_spec && !constructor_p)
	{
	  int decl_spec_declares_class_or_enum;
	  bool is_cv_qualifier;
	  tree type_spec;

	  if (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
	    flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;

	  type_spec
	    = cp_parser_type_specifier (parser, flags,
					decl_specs,
					/*is_declaration=*/true,
					&decl_spec_declares_class_or_enum,
					&is_cv_qualifier);
	  *declares_class_or_enum |= decl_spec_declares_class_or_enum;

	  /* If this type-specifier referenced a user-defined type
	     (a typedef, class-name, etc.), then we can't allow any
	     more such type-specifiers henceforth.

	     [dcl.spec]

	     The longest sequence of decl-specifiers that could
	     possibly be a type name is taken as the
	     decl-specifier-seq of a declaration.  The sequence shall
	     be self-consistent as described below.

	     [dcl.type]

	     As a general rule, at most one type-specifier is allowed
	     in the complete decl-specifier-seq of a declaration.  The
	     only exceptions are the following:

	     -- const or volatile can be combined with any other
		type-specifier.

	     -- signed or unsigned can be combined with char, long,
		short, or int.

	     -- ..

	     Example:

	       typedef char* Pc;
	       void g (const int Pc);

	     Here, Pc is *not* part of the decl-specifier seq; it's
	     the declarator.  Therefore, once we see a type-specifier
	     (other than a cv-qualifier), we forbid any additional
	     user-defined types.  We *do* still allow things like `int
	     int' to be considered a decl-specifier-seq, and issue the
	     error message later.  */
	  if (type_spec && !is_cv_qualifier)
	    flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
	  /* A constructor declarator cannot follow a type-specifier.  */
	  if (type_spec)
	    {
	      constructor_possible_p = false;
	      found_decl_spec = true;
	      if (!is_cv_qualifier)
		decl_specs->any_type_specifiers_p = true;

	      if ((flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR) != 0)
		error_at (token->location, "type-specifier invalid in lambda");
	    }
	}

      /* If we still do not have a DECL_SPEC, then there are no more
	 decl-specifiers.  */
      if (!found_decl_spec)
	break;

      if (decl_specs->std_attributes)
	{
	  error_at (decl_specs->locations[ds_std_attribute],
		    "standard attributes in middle of decl-specifiers");
	  inform (decl_specs->locations[ds_std_attribute],
		  "standard attributes must precede the decl-specifiers to "
		  "apply to the declaration, or follow them to apply to "
		  "the type");
	}

      decl_specs->any_specifiers_p = true;
      /* After we see one decl-specifier, further decl-specifiers are
	 always optional.  */
      flags |= CP_PARSER_FLAGS_OPTIONAL;
    }

  /* Don't allow a friend specifier with a class definition.  */
  if (decl_spec_seq_has_spec_p (decl_specs, ds_friend)
      && (*declares_class_or_enum & 2))
    error_at (decl_specs->locations[ds_friend],
	      "class definition may not be declared a friend");
}

/* Parse an (optional) storage-class-specifier.

   storage-class-specifier:
     auto
     register
     static
     extern
     mutable

   GNU Extension:

   storage-class-specifier:
     thread

   Returns an IDENTIFIER_NODE corresponding to the keyword used.  */

static tree
cp_parser_storage_class_specifier_opt (cp_parser* parser)
{
  switch (cp_lexer_peek_token (parser->lexer)->keyword)
    {
    case RID_AUTO:
      if (cxx_dialect != cxx98)
        return NULL_TREE;
      /* Fall through for C++98.  */
      gcc_fallthrough ();

    case RID_REGISTER:
    case RID_STATIC:
    case RID_EXTERN:
    case RID_MUTABLE:
    case RID_THREAD:
      /* Consume the token.  */
      return cp_lexer_consume_token (parser->lexer)->u.value;

    default:
      return NULL_TREE;
    }
}

/* Parse an (optional) function-specifier.

   function-specifier:
     inline
     virtual
     explicit

   C++20 Extension:
     explicit(constant-expression)

   Returns an IDENTIFIER_NODE corresponding to the keyword used.
   Updates DECL_SPECS, if it is non-NULL.  */

static tree
cp_parser_function_specifier_opt (cp_parser* parser,
				  cp_decl_specifier_seq *decl_specs)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  switch (token->keyword)
    {
    case RID_INLINE:
      set_and_check_decl_spec_loc (decl_specs, ds_inline, token);
      break;

    case RID_VIRTUAL:
      /* 14.5.2.3 [temp.mem]

	 A member function template shall not be virtual.  */
      if (PROCESSING_REAL_TEMPLATE_DECL_P ()
	  && current_class_type)
	error_at (token->location, "templates may not be %<virtual%>");
      else
	set_and_check_decl_spec_loc (decl_specs, ds_virtual, token);
      break;

    case RID_EXPLICIT:
      {
	tree id = cp_lexer_consume_token (parser->lexer)->u.value;
	/* If we see '(', it's C++20 explicit(bool).  */
	tree expr;
	if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
	  {
	    matching_parens parens;
	    parens.consume_open (parser);

	    /* New types are not allowed in an explicit-specifier.  */
	    const char *saved_message
	      = parser->type_definition_forbidden_message;
	    parser->type_definition_forbidden_message
	      = G_("types may not be defined in explicit-specifier");

	    if (cxx_dialect < cxx20)
	      pedwarn (token->location, OPT_Wc__20_extensions,
		       "%<explicit(bool)%> only available with %<-std=c++20%> "
		       "or %<-std=gnu++20%>");

	    /* Parse the constant-expression.  */
	    expr = cp_parser_constant_expression (parser);

	    /* Restore the saved message.  */
	    parser->type_definition_forbidden_message = saved_message;
	    parens.require_close (parser);
	  }
	else
	  /* The explicit-specifier explicit without a constant-expression is
	     equivalent to the explicit-specifier explicit(true).  */
	  expr = boolean_true_node;

	/* [dcl.fct.spec]
	   "the constant-expression, if supplied, shall be a contextually
	   converted constant expression of type bool."  */
	expr = build_explicit_specifier (expr, tf_warning_or_error);
	/* We could evaluate it -- mark the decl as appropriate.  */
	if (expr == boolean_true_node)
	  set_and_check_decl_spec_loc (decl_specs, ds_explicit, token);
	else if (expr == boolean_false_node)
	  /* Don't mark the decl as explicit.  */;
	else if (decl_specs)
	  /* The expression was value-dependent.  Remember it so that we can
	     substitute it later.  */
	  decl_specs->explicit_specifier = expr;
	return id;
      }

    default:
      return NULL_TREE;
    }

  /* Consume the token.  */
  return cp_lexer_consume_token (parser->lexer)->u.value;
}

/* Parse a linkage-specification.

   linkage-specification:
     extern string-literal { declaration-seq [opt] }
     extern string-literal declaration  */

static void
cp_parser_linkage_specification (cp_parser* parser, tree prefix_attr)
{
  /* Look for the `extern' keyword.  */
  cp_token *extern_token
    = cp_parser_require_keyword (parser, RID_EXTERN, RT_EXTERN);

  /* Look for the string-literal.  */
  cp_token *string_token = cp_lexer_peek_token (parser->lexer);
  tree linkage = cp_parser_string_literal (parser, /*translate=*/false,
					   /*wide_ok=*/false);

  /* Transform the literal into an identifier.  If the literal is a
     wide-character string, or contains embedded NULs, then we can't
     handle it as the user wants.  */
  if (linkage == error_mark_node
      || strlen (TREE_STRING_POINTER (linkage))
	 != (size_t) (TREE_STRING_LENGTH (linkage) - 1))
    {
      cp_parser_error (parser, "invalid linkage-specification");
      /* Assume C++ linkage.  */
      linkage = lang_name_cplusplus;
    }
  else
    linkage = get_identifier (TREE_STRING_POINTER (linkage));

  /* We're now using the new linkage.  */
  unsigned saved_module = module_kind;
  module_kind &= ~MK_ATTACH;
  push_lang_context (linkage);

  /* Preserve the location of the innermost linkage specification,
     tracking the locations of nested specifications via a local.  */
  location_t saved_location
    = parser->innermost_linkage_specification_location;
  /* Construct a location ranging from the start of the "extern" to
     the end of the string-literal, with the caret at the start, e.g.:
       extern "C" {
       ^~~~~~~~~~
  */
  parser->innermost_linkage_specification_location
    = make_location (extern_token->location,
		     extern_token->location,
		     get_finish (string_token->location));

  /* If the next token is a `{', then we're using the first
     production.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      cp_ensure_no_omp_declare_simd (parser);
      cp_ensure_no_oacc_routine (parser);

      /* Consume the `{' token.  */
      matching_braces braces;
      braces.consume_open (parser);
      /* Parse the declarations.  */
      cp_parser_declaration_seq_opt (parser);
      /* Look for the closing `}'.  */
      braces.require_close (parser);
    }
  /* Otherwise, there's just one declaration.  */
  else
    {
      bool saved_in_unbraced_linkage_specification_p;

      saved_in_unbraced_linkage_specification_p
	= parser->in_unbraced_linkage_specification_p;
      parser->in_unbraced_linkage_specification_p = true;
      cp_parser_declaration (parser, prefix_attr);
      parser->in_unbraced_linkage_specification_p
	= saved_in_unbraced_linkage_specification_p;
    }

  /* We're done with the linkage-specification.  */
  pop_lang_context ();
  module_kind = saved_module;

  /* Restore location of parent linkage specification, if any.  */
  parser->innermost_linkage_specification_location = saved_location;
}

/* Parse a static_assert-declaration.

   static_assert-declaration:
     static_assert ( constant-expression , string-literal ) ;
     static_assert ( constant-expression ) ; (C++17)

   If MEMBER_P, this static_assert is a class member.  */

static void
cp_parser_static_assert(cp_parser *parser, bool member_p)
{
  cp_expr condition;
  location_t token_loc;
  tree message;
  bool dummy;

  /* Peek at the `static_assert' token so we can keep track of exactly
     where the static assertion started.  */
  token_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Look for the `static_assert' keyword.  */
  if (!cp_parser_require_keyword (parser, RID_STATIC_ASSERT,
                                  RT_STATIC_ASSERT))
    return;

  /*  We know we are in a static assertion; commit to any tentative
      parse.  */
  if (cp_parser_parsing_tentatively (parser))
    cp_parser_commit_to_tentative_parse (parser);

  /* Parse the `(' starting the static assertion condition.  */
  matching_parens parens;
  parens.require_open (parser);

  /* Parse the constant-expression.  Allow a non-constant expression
     here in order to give better diagnostics in finish_static_assert.  */
  condition =
    cp_parser_constant_expression (parser,
                                   /*allow_non_constant_p=*/true,
                                   /*non_constant_p=*/&dummy);

  if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
    {
      if (pedantic && cxx_dialect < cxx17)
	pedwarn (input_location, OPT_Wc__17_extensions,
		 "%<static_assert%> without a message "
		 "only available with %<-std=c++17%> or %<-std=gnu++17%>");
      /* Eat the ')'  */
      cp_lexer_consume_token (parser->lexer);
      message = build_string (1, "");
      TREE_TYPE (message) = char_array_type_node;
      fix_string_type (message);
    }
  else
    {
      /* Parse the separating `,'.  */
      cp_parser_require (parser, CPP_COMMA, RT_COMMA);

      /* Parse the string-literal message.  */
      message = cp_parser_string_literal (parser, /*translate=*/false,
					  /*wide_ok=*/true);

      /* A `)' completes the static assertion.  */
      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser,
                                               /*recovering=*/true,
                                               /*or_comma=*/false,
					       /*consume_paren=*/true);
    }

  /* A semicolon terminates the declaration.  */
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

  /* Get the location for the static assertion.  Use that of the
     condition if available, otherwise, use that of the "static_assert"
     token.  */
  location_t assert_loc = condition.get_location ();
  if (assert_loc == UNKNOWN_LOCATION)
    assert_loc = token_loc;

  /* Complete the static assertion, which may mean either processing
     the static assert now or saving it for template instantiation.  */
  finish_static_assert (condition, message, assert_loc, member_p,
			/*show_expr_p=*/false);
}

/* Parse the expression in decltype ( expression ).  */

static tree
cp_parser_decltype_expr (cp_parser *parser,
			 bool &id_expression_or_member_access_p)
{
  cp_token *id_expr_start_token;
  tree expr;

  /* First, try parsing an id-expression.  */
  id_expr_start_token = cp_lexer_peek_token (parser->lexer);
  cp_parser_parse_tentatively (parser);
  expr = cp_parser_id_expression (parser,
                                  /*template_keyword_p=*/false,
                                  /*check_dependency_p=*/true,
                                  /*template_p=*/NULL,
                                  /*declarator_p=*/false,
                                  /*optional_p=*/false);

  if (!cp_parser_error_occurred (parser) && expr != error_mark_node)
    {
      bool non_integral_constant_expression_p = false;
      tree id_expression = expr;
      cp_id_kind idk;
      const char *error_msg;

      if (identifier_p (expr))
	/* Lookup the name we got back from the id-expression.  */
	expr = cp_parser_lookup_name_simple (parser, expr,
					     id_expr_start_token->location);

      if (expr && TREE_CODE (expr) == TEMPLATE_DECL)
	/* A template without args is not a complete id-expression.  */
	expr = error_mark_node;

      if (expr
          && expr != error_mark_node
          && TREE_CODE (expr) != TYPE_DECL
	  && (TREE_CODE (expr) != BIT_NOT_EXPR
	      || !TYPE_P (TREE_OPERAND (expr, 0)))
          && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
        {
          /* Complete lookup of the id-expression.  */
          expr = (finish_id_expression
                  (id_expression, expr, parser->scope, &idk,
                   /*integral_constant_expression_p=*/false,
                   /*allow_non_integral_constant_expression_p=*/true,
                   &non_integral_constant_expression_p,
                   /*template_p=*/false,
                   /*done=*/true,
                   /*address_p=*/false,
                   /*template_arg_p=*/false,
                   &error_msg,
		   id_expr_start_token->location));

          if (expr == error_mark_node)
            /* We found an id-expression, but it was something that we
               should not have found. This is an error, not something
               we can recover from, so note that we found an
               id-expression and we'll recover as gracefully as
               possible.  */
            id_expression_or_member_access_p = true;
        }

      if (expr
          && expr != error_mark_node
          && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
        /* We have an id-expression.  */
        id_expression_or_member_access_p = true;
    }

  if (!id_expression_or_member_access_p)
    {
      /* Abort the id-expression parse.  */
      cp_parser_abort_tentative_parse (parser);

      /* Parsing tentatively, again.  */
      cp_parser_parse_tentatively (parser);

      /* Parse a class member access.  */
      expr = cp_parser_postfix_expression (parser, /*address_p=*/false,
                                           /*cast_p=*/false, /*decltype*/true,
                                           /*member_access_only_p=*/true, NULL);

      if (expr
          && expr != error_mark_node
          && cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
        /* We have an id-expression.  */
        id_expression_or_member_access_p = true;
    }

  if (id_expression_or_member_access_p)
    /* We have parsed the complete id-expression or member access.  */
    cp_parser_parse_definitely (parser);
  else
    {
      /* Abort our attempt to parse an id-expression or member access
         expression.  */
      cp_parser_abort_tentative_parse (parser);

      /* Parse a full expression.  */
      expr = cp_parser_expression (parser, /*pidk=*/NULL, /*cast_p=*/false,
				   /*decltype_p=*/true);
    }

  return expr;
}

/* Parse a `decltype' type.  Returns the type.

   decltype-specifier:
     decltype ( expression )
   C++14:
     decltype ( auto )  */

static tree
cp_parser_decltype (cp_parser *parser)
{
  bool id_expression_or_member_access_p = false;
  cp_token *start_token = cp_lexer_peek_token (parser->lexer);

  if (start_token->type == CPP_DECLTYPE)
    {
      /* Already parsed.  */
      cp_lexer_consume_token (parser->lexer);
      return saved_checks_value (start_token->u.tree_check_value);
    }

  /* Look for the `decltype' token.  */
  if (!cp_parser_require_keyword (parser, RID_DECLTYPE, RT_DECLTYPE))
    return error_mark_node;

  /* Parse the opening `('.  */
  matching_parens parens;
  if (!parens.require_open (parser))
    return error_mark_node;

  /* Since we're going to preserve any side-effects from this parse, set up a
     firewall to protect our callers from cp_parser_commit_to_tentative_parse
     in the expression.  */
  tentative_firewall firewall (parser);

  /* If in_declarator_p, a reparse as an expression might succeed (60361).
     Otherwise, commit now for better diagnostics.  */
  if (cp_parser_uncommitted_to_tentative_parse_p (parser)
      && !parser->in_declarator_p)
    cp_parser_commit_to_topmost_tentative_parse (parser);

  push_deferring_access_checks (dk_deferred);

  tree expr = NULL_TREE;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
    {
      /* decltype (auto) */
      cp_lexer_consume_token (parser->lexer);
      if (cxx_dialect < cxx14)
	{
	  error_at (start_token->location,
		    "%<decltype(auto)%> type specifier only available with "
		    "%<-std=c++14%> or %<-std=gnu++14%>");
	  expr = error_mark_node;
	}
    }
  else
    {
      /* decltype (expression)  */

      /* Types cannot be defined in a `decltype' expression.  Save away the
	 old message and set the new one.  */
      const char *saved_message = parser->type_definition_forbidden_message;
      parser->type_definition_forbidden_message
	= G_("types may not be defined in %<decltype%> expressions");

      /* The restrictions on constant-expressions do not apply inside
	 decltype expressions.  */
      bool saved_integral_constant_expression_p
	= parser->integral_constant_expression_p;
      bool saved_non_integral_constant_expression_p
	= parser->non_integral_constant_expression_p;
      parser->integral_constant_expression_p = false;

      /* Within a parenthesized expression, a `>' token is always
	 the greater-than operator.  */
      bool saved_greater_than_is_operator_p
	= parser->greater_than_is_operator_p;
      parser->greater_than_is_operator_p = true;

      /* Don't synthesize an implicit template type parameter here.  This
	 could happen with C++23 code like

	   void f(decltype(new auto{0}));

	 where we want to deduce the auto right away so that the parameter
	 is of type 'int *'.  */
      auto cleanup = make_temp_override
	(parser->auto_is_implicit_function_template_parm_p, false);

      /* Do not actually evaluate the expression.  */
      ++cp_unevaluated_operand;

      /* Do not warn about problems with the expression.  */
      ++c_inhibit_evaluation_warnings;

      expr = cp_parser_decltype_expr (parser, id_expression_or_member_access_p);
      STRIP_ANY_LOCATION_WRAPPER (expr);

      /* Go back to evaluating expressions.  */
      --cp_unevaluated_operand;
      --c_inhibit_evaluation_warnings;

      /* The `>' token might be the end of a template-id or
	 template-parameter-list now.  */
      parser->greater_than_is_operator_p
	= saved_greater_than_is_operator_p;

      /* Restore the old message and the integral constant expression
	 flags.  */
      parser->type_definition_forbidden_message = saved_message;
      parser->integral_constant_expression_p
	= saved_integral_constant_expression_p;
      parser->non_integral_constant_expression_p
	= saved_non_integral_constant_expression_p;
    }

  /* Parse to the closing `)'.  */
  if (expr == error_mark_node || !parens.require_close (parser))
    {
      cp_parser_skip_to_closing_parenthesis (parser, true, false,
					     /*consume_paren=*/true);
      expr = error_mark_node;
    }

  /* If we got a parse error while tentative, bail out now.  */
  if (cp_parser_error_occurred (parser))
    {
      pop_deferring_access_checks ();
      return error_mark_node;
    }

  if (!expr)
    /* Build auto.  */
    expr = make_decltype_auto ();
  else
    expr = finish_decltype_type (expr, id_expression_or_member_access_p,
				 tf_warning_or_error);

  /* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
     it again.  */
  start_token->type = CPP_DECLTYPE;
  start_token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
  start_token->tree_check_p = true;
  start_token->u.tree_check_value->value = expr;
  start_token->u.tree_check_value->checks = get_deferred_access_checks ();
  start_token->keyword = RID_MAX;

  location_t loc = start_token->location;
  loc = make_location (loc, loc, parser->lexer);
  start_token->location = loc;

  cp_lexer_purge_tokens_after (parser->lexer, start_token);

  pop_to_parent_deferring_access_checks ();

  return expr;
}

/* Special member functions [gram.special] */

/* Parse a conversion-function-id.

   conversion-function-id:
     operator conversion-type-id

   Returns an IDENTIFIER_NODE representing the operator.  */

static tree
cp_parser_conversion_function_id (cp_parser* parser)
{
  tree type;
  tree saved_scope;
  tree saved_qualifying_scope;
  tree saved_object_scope;
  tree pushed_scope = NULL_TREE;

  /* Look for the `operator' token.  */
  if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
    return error_mark_node;
  /* When we parse the conversion-type-id, the current scope will be
     reset.  However, we need that information in able to look up the
     conversion function later, so we save it here.  */
  saved_scope = parser->scope;
  saved_qualifying_scope = parser->qualifying_scope;
  saved_object_scope = parser->object_scope;
  /* We must enter the scope of the class so that the names of
     entities declared within the class are available in the
     conversion-type-id.  For example, consider:

       struct S {
	 typedef int I;
	 operator I();
       };

       S::operator I() { ... }

     In order to see that `I' is a type-name in the definition, we
     must be in the scope of `S'.  */
  if (saved_scope)
    pushed_scope = push_scope (saved_scope);
  /* Parse the conversion-type-id.  */
  type = cp_parser_conversion_type_id (parser);
  /* Leave the scope of the class, if any.  */
  if (pushed_scope)
    pop_scope (pushed_scope);
  /* Restore the saved scope.  */
  parser->scope = saved_scope;
  parser->qualifying_scope = saved_qualifying_scope;
  parser->object_scope = saved_object_scope;
  /* If the TYPE is invalid, indicate failure.  */
  if (type == error_mark_node)
    return error_mark_node;
  return make_conv_op_name (type);
}

/* Parse a conversion-type-id:

   conversion-type-id:
     type-specifier-seq conversion-declarator [opt]

   Returns the TYPE specified.  */

static tree
cp_parser_conversion_type_id (cp_parser* parser)
{
  tree attributes;
  cp_decl_specifier_seq type_specifiers;
  cp_declarator *declarator;
  tree type_specified;
  const char *saved_message;

  /* Parse the attributes.  */
  attributes = cp_parser_attributes_opt (parser);

  saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in a conversion-type-id");

  /* Parse the type-specifiers.  DR 2413 clarifies that `typename' is
     optional in conversion-type-id.  */
  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
				/*is_declaration=*/false,
				/*is_trailing_return=*/false,
				&type_specifiers);

  parser->type_definition_forbidden_message = saved_message;

  /* If that didn't work, stop.  */
  if (type_specifiers.type == error_mark_node)
    return error_mark_node;
  /* Parse the conversion-declarator.  */
  declarator = cp_parser_conversion_declarator_opt (parser);

  type_specified =  grokdeclarator (declarator, &type_specifiers, TYPENAME,
				    /*initialized=*/0, &attributes);
  if (attributes)
    cplus_decl_attributes (&type_specified, attributes, /*flags=*/0);

  /* Don't give this error when parsing tentatively.  This happens to
     work because we always parse this definitively once.  */
  if (! cp_parser_uncommitted_to_tentative_parse_p (parser)
      && type_uses_auto (type_specified))
    {
      if (cxx_dialect < cxx14)
	{
	  error ("invalid use of %<auto%> in conversion operator");
	  return error_mark_node;
	}
      else if (template_parm_scope_p ())
	warning (0, "use of %<auto%> in member template "
		 "conversion operator can never be deduced");
    }

  return type_specified;
}

/* Parse an (optional) conversion-declarator.

   conversion-declarator:
     ptr-operator conversion-declarator [opt]

   */

static cp_declarator *
cp_parser_conversion_declarator_opt (cp_parser* parser)
{
  enum tree_code code;
  tree class_type, std_attributes = NULL_TREE;
  cp_cv_quals cv_quals;

  /* We don't know if there's a ptr-operator next, or not.  */
  cp_parser_parse_tentatively (parser);
  /* Try the ptr-operator.  */
  code = cp_parser_ptr_operator (parser, &class_type, &cv_quals,
				 &std_attributes);
  /* If it worked, look for more conversion-declarators.  */
  if (cp_parser_parse_definitely (parser))
    {
      cp_declarator *declarator;

      /* Parse another optional declarator.  */
      declarator = cp_parser_conversion_declarator_opt (parser);

      declarator = cp_parser_make_indirect_declarator
	(code, class_type, cv_quals, declarator, std_attributes);

      return declarator;
   }

  return NULL;
}

/* Parse an (optional) ctor-initializer.

   ctor-initializer:
     : mem-initializer-list  */

static void
cp_parser_ctor_initializer_opt (cp_parser* parser)
{
  /* If the next token is not a `:', then there is no
     ctor-initializer.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
    {
      /* Do default initialization of any bases and members.  */
      if (DECL_CONSTRUCTOR_P (current_function_decl))
	finish_mem_initializers (NULL_TREE);
      return;
    }

  /* Consume the `:' token.  */
  cp_lexer_consume_token (parser->lexer);
  /* And the mem-initializer-list.  */
  cp_parser_mem_initializer_list (parser);
}

/* Parse a mem-initializer-list.

   mem-initializer-list:
     mem-initializer ... [opt]
     mem-initializer ... [opt] , mem-initializer-list  */

static void
cp_parser_mem_initializer_list (cp_parser* parser)
{
  tree mem_initializer_list = NULL_TREE;
  tree target_ctor = error_mark_node;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Let the semantic analysis code know that we are starting the
     mem-initializer-list.  */
  if (!DECL_CONSTRUCTOR_P (current_function_decl))
    error_at (token->location,
	      "only constructors take member initializers");

  /* Loop through the list.  */
  while (true)
    {
      tree mem_initializer;

      token = cp_lexer_peek_token (parser->lexer);
      /* Parse the mem-initializer.  */
      mem_initializer = cp_parser_mem_initializer (parser);
      /* If the next token is a `...', we're expanding member initializers. */
      bool ellipsis = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
      if (ellipsis
	  || (mem_initializer != error_mark_node
	      && check_for_bare_parameter_packs (TREE_PURPOSE
						 (mem_initializer))))
        {
          /* Consume the `...'. */
	  if (ellipsis)
	    cp_lexer_consume_token (parser->lexer);

          /* The TREE_PURPOSE must be a _TYPE, because base-specifiers
             can be expanded but members cannot. */
          if (mem_initializer != error_mark_node
              && !TYPE_P (TREE_PURPOSE (mem_initializer)))
            {
              error_at (token->location,
			"cannot expand initializer for member %qD",
			TREE_PURPOSE (mem_initializer));
              mem_initializer = error_mark_node;
            }

          /* Construct the pack expansion type. */
          if (mem_initializer != error_mark_node)
            mem_initializer = make_pack_expansion (mem_initializer);
        }
      if (target_ctor != error_mark_node
	  && mem_initializer != error_mark_node)
	{
	  error ("mem-initializer for %qD follows constructor delegation",
		 TREE_PURPOSE (mem_initializer));
	  mem_initializer = error_mark_node;
	}
      /* Look for a target constructor. */
      if (mem_initializer != error_mark_node
	  && CLASS_TYPE_P (TREE_PURPOSE (mem_initializer))
	  && same_type_p (TREE_PURPOSE (mem_initializer), current_class_type))
	{
	  maybe_warn_cpp0x (CPP0X_DELEGATING_CTORS);
	  if (mem_initializer_list)
	    {
	      error ("constructor delegation follows mem-initializer for %qD",
		     TREE_PURPOSE (mem_initializer_list));
	      mem_initializer = error_mark_node;
	    }
	  target_ctor = mem_initializer;
	}
      /* Add it to the list, unless it was erroneous.  */
      if (mem_initializer != error_mark_node)
	{
	  TREE_CHAIN (mem_initializer) = mem_initializer_list;
	  mem_initializer_list = mem_initializer;
	}
      /* If the next token is not a `,', we're done.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Consume the `,' token.  */
      cp_lexer_consume_token (parser->lexer);
    }

  /* Perform semantic analysis.  */
  if (DECL_CONSTRUCTOR_P (current_function_decl))
    finish_mem_initializers (mem_initializer_list);
}

/* Parse a mem-initializer.

   mem-initializer:
     mem-initializer-id ( expression-list [opt] )
     mem-initializer-id braced-init-list

   GNU extension:

   mem-initializer:
     ( expression-list [opt] )

   Returns a TREE_LIST.  The TREE_PURPOSE is the TYPE (for a base
   class) or FIELD_DECL (for a non-static data member) to initialize;
   the TREE_VALUE is the expression-list.  An empty initialization
   list is represented by void_list_node.  */

static tree
cp_parser_mem_initializer (cp_parser* parser)
{
  tree mem_initializer_id;
  tree expression_list;
  tree member;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Find out what is being initialized.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      permerror (token->location,
		 "anachronistic old-style base class initializer");
      mem_initializer_id = NULL_TREE;
    }
  else
    {
      mem_initializer_id = cp_parser_mem_initializer_id (parser);
      if (mem_initializer_id == error_mark_node)
	return mem_initializer_id;
    }
  member = expand_member_init (mem_initializer_id);
  if (member && !DECL_P (member))
    in_base_initializer = 1;

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      bool expr_non_constant_p;
      cp_lexer_set_source_position (parser->lexer);
      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
      expression_list = cp_parser_braced_list (parser, &expr_non_constant_p);
      CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
      expression_list = build_tree_list (NULL_TREE, expression_list);
    }
  else
    {
      vec<tree, va_gc> *vec;
      vec = cp_parser_parenthesized_expression_list (parser, non_attr,
						     /*cast_p=*/false,
						     /*allow_expansion_p=*/true,
						     /*non_constant_p=*/NULL,
						     /*close_paren_loc=*/NULL,
						     /*wrap_locations_p=*/true);
      if (vec == NULL)
	return error_mark_node;
      expression_list = build_tree_list_vec (vec);
      release_tree_vector (vec);
    }

  if (expression_list == error_mark_node)
    return error_mark_node;
  if (!expression_list)
    expression_list = void_type_node;

  in_base_initializer = 0;

  if (!member)
    return error_mark_node;
  tree node = build_tree_list (member, expression_list);

  /* We can't attach the source location of this initializer directly to
     the list node, so we instead attach it to a dummy EMPTY_CLASS_EXPR
     within the TREE_TYPE of the list node.  */
  location_t loc
    = make_location (token->location, token->location, parser->lexer);
  tree dummy = build0 (EMPTY_CLASS_EXPR, NULL_TREE);
  SET_EXPR_LOCATION (dummy, loc);
  TREE_TYPE (node) = dummy;

  return node;
}

/* Parse a mem-initializer-id.

   mem-initializer-id:
     :: [opt] nested-name-specifier [opt] class-name
     decltype-specifier (C++11)
     identifier

   Returns a TYPE indicating the class to be initialized for the first
   production (and the second in C++11).  Returns an IDENTIFIER_NODE
   indicating the data member to be initialized for the last production.  */

static tree
cp_parser_mem_initializer_id (cp_parser* parser)
{
  bool global_scope_p;
  bool nested_name_specifier_p;
  bool template_p = false;
  tree id;

  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* `typename' is not allowed in this context ([temp.res]).  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
    {
      error_at (token->location,
		"keyword %<typename%> not allowed in this context (a qualified "
		"member initializer is implicitly a type)");
      cp_lexer_consume_token (parser->lexer);
    }
  /* Look for the optional `::' operator.  */
  global_scope_p
    = (cp_parser_global_scope_opt (parser,
				   /*current_scope_valid_p=*/false)
       != NULL_TREE);
  /* Look for the optional nested-name-specifier.  The simplest way to
     implement:

       [temp.res]

       The keyword `typename' is not permitted in a base-specifier or
       mem-initializer; in these contexts a qualified name that
       depends on a template-parameter is implicitly assumed to be a
       type name.

     is to assume that we have seen the `typename' keyword at this
     point.  */
  nested_name_specifier_p
    = (cp_parser_nested_name_specifier_opt (parser,
					    /*typename_keyword_p=*/true,
					    /*check_dependency_p=*/true,
					    /*type_p=*/true,
					    /*is_declaration=*/true)
       != NULL_TREE);
  if (nested_name_specifier_p)
    template_p = cp_parser_optional_template_keyword (parser);
  /* If there is a `::' operator or a nested-name-specifier, then we
     are definitely looking for a class-name.  */
  if (global_scope_p || nested_name_specifier_p)
    return cp_parser_class_name (parser,
				 /*typename_keyword_p=*/true,
				 /*template_keyword_p=*/template_p,
				 typename_type,
				 /*check_dependency_p=*/true,
				 /*class_head_p=*/false,
				 /*is_declaration=*/true);
  /* Otherwise, we could also be looking for an ordinary identifier.  */
  cp_parser_parse_tentatively (parser);
  if (cp_lexer_next_token_is_decltype (parser->lexer))
    /* Try a decltype-specifier.  */
    id = cp_parser_decltype (parser);
  else
    /* Otherwise, try a class-name.  */
    id = cp_parser_class_name (parser,
			       /*typename_keyword_p=*/true,
			       /*template_keyword_p=*/false,
			       none_type,
			       /*check_dependency_p=*/true,
			       /*class_head_p=*/false,
			       /*is_declaration=*/true);
  /* If we found one, we're done.  */
  if (cp_parser_parse_definitely (parser))
    return id;
  /* Otherwise, look for an ordinary identifier.  */
  return cp_parser_identifier (parser);
}

/* Overloading [gram.over] */

/* Parse an operator-function-id.

   operator-function-id:
     operator operator

   Returns an IDENTIFIER_NODE for the operator which is a
   human-readable spelling of the identifier, e.g., `operator +'.  */

static cp_expr
cp_parser_operator_function_id (cp_parser* parser)
{
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
  /* Look for the `operator' keyword.  */
  if (!cp_parser_require_keyword (parser, RID_OPERATOR, RT_OPERATOR))
    return error_mark_node;
  /* And then the name of the operator itself.  */
  return cp_parser_operator (parser, start_loc);
}

/* Return an identifier node for a user-defined literal operator.
   The suffix identifier is chained to the operator name identifier.  */

tree
cp_literal_operator_id (const char* name)
{
  tree identifier;
  char *buffer = XNEWVEC (char, strlen (UDLIT_OP_ANSI_PREFIX)
			      + strlen (name) + 10);
  sprintf (buffer, UDLIT_OP_ANSI_FORMAT, name);
  identifier = get_identifier (buffer);
  XDELETEVEC (buffer);

  return identifier;
}

/* Parse an operator.

   operator:
     new delete new[] delete[] + - * / % ^ & | ~ ! = < >
     += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= &&
     || ++ -- , ->* -> () []

   GNU Extensions:

   operator:
     <? >? <?= >?=

   Returns an IDENTIFIER_NODE for the operator which is a
   human-readable spelling of the identifier, e.g., `operator +'.  */

static cp_expr
cp_parser_operator (cp_parser* parser, location_t start_loc)
{
  tree id = NULL_TREE;
  cp_token *token;
  bool utf8 = false;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  location_t end_loc = token->location;

  /* Figure out which operator we have.  */
  enum tree_code op = ERROR_MARK;
  bool assop = false;
  bool consumed = false;
  switch (token->type)
    {
    case CPP_KEYWORD:
      {
	/* The keyword should be either `new', `delete' or `co_await'.  */
	if (token->keyword == RID_NEW)
	  op = NEW_EXPR;
	else if (token->keyword == RID_DELETE)
	  op = DELETE_EXPR;
	else if (token->keyword == RID_CO_AWAIT)
	  op = CO_AWAIT_EXPR;
	else
	  break;

	/* Consume the `new', `delete' or co_await token.  */
	end_loc = cp_lexer_consume_token (parser->lexer)->location;

	/* Peek at the next token.  */
	token = cp_lexer_peek_token (parser->lexer);
	/* If it's a `[' token then this is the array variant of the
	   operator.  */
	if (token->type == CPP_OPEN_SQUARE
	    && op != CO_AWAIT_EXPR)
	  {
	    /* Consume the `[' token.  */
	    cp_lexer_consume_token (parser->lexer);
	    /* Look for the `]' token.  */
	    if (cp_token *close_token
		= cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
	      end_loc = close_token->location;
	    op = op == NEW_EXPR ? VEC_NEW_EXPR : VEC_DELETE_EXPR;
	  }
	consumed = true;
	break;
      }

    case CPP_PLUS:
      op = PLUS_EXPR;
      break;

    case CPP_MINUS:
      op = MINUS_EXPR;
      break;

    case CPP_MULT:
      op = MULT_EXPR;
      break;

    case CPP_DIV:
      op = TRUNC_DIV_EXPR;
      break;

    case CPP_MOD:
      op = TRUNC_MOD_EXPR;
      break;

    case CPP_XOR:
      op = BIT_XOR_EXPR;
      break;

    case CPP_AND:
      op = BIT_AND_EXPR;
      break;

    case CPP_OR:
      op = BIT_IOR_EXPR;
      break;

    case CPP_COMPL:
      op = BIT_NOT_EXPR;
      break;

    case CPP_NOT:
      op = TRUTH_NOT_EXPR;
      break;

    case CPP_EQ:
      assop = true;
      op = NOP_EXPR;
      break;

    case CPP_LESS:
      op = LT_EXPR;
      break;

    case CPP_GREATER:
      op = GT_EXPR;
      break;

    case CPP_PLUS_EQ:
      assop = true;
      op = PLUS_EXPR;
      break;

    case CPP_MINUS_EQ:
      assop = true;
      op = MINUS_EXPR;
      break;

    case CPP_MULT_EQ:
      assop = true;
      op = MULT_EXPR;
      break;

    case CPP_DIV_EQ:
      assop = true;
      op = TRUNC_DIV_EXPR;
      break;

    case CPP_MOD_EQ:
      assop = true;
      op = TRUNC_MOD_EXPR;
      break;

    case CPP_XOR_EQ:
      assop = true;
      op = BIT_XOR_EXPR;
      break;

    case CPP_AND_EQ:
      assop = true;
      op = BIT_AND_EXPR;
      break;

    case CPP_OR_EQ:
      assop = true;
      op = BIT_IOR_EXPR;
      break;

    case CPP_LSHIFT:
      op = LSHIFT_EXPR;
      break;

    case CPP_RSHIFT:
      op = RSHIFT_EXPR;
      break;

    case CPP_LSHIFT_EQ:
      assop = true;
      op = LSHIFT_EXPR;
      break;

    case CPP_RSHIFT_EQ:
      assop = true;
      op = RSHIFT_EXPR;
      break;

    case CPP_EQ_EQ:
      op = EQ_EXPR;
      break;

    case CPP_NOT_EQ:
      op = NE_EXPR;
      break;

    case CPP_LESS_EQ:
      op = LE_EXPR;
      break;

    case CPP_GREATER_EQ:
      op = GE_EXPR;
      break;

    case CPP_SPACESHIP:
      op = SPACESHIP_EXPR;
      break;

    case CPP_AND_AND:
      op = TRUTH_ANDIF_EXPR;
      break;

    case CPP_OR_OR:
      op = TRUTH_ORIF_EXPR;
      break;

    case CPP_PLUS_PLUS:
      op = POSTINCREMENT_EXPR;
      break;

    case CPP_MINUS_MINUS:
      op = PREDECREMENT_EXPR;
      break;

    case CPP_COMMA:
      op = COMPOUND_EXPR;
      break;

    case CPP_DEREF_STAR:
      op = MEMBER_REF;
      break;

    case CPP_DEREF:
      op = COMPONENT_REF;
      break;

    case CPP_QUERY:
      op = COND_EXPR;
      /* Consume the `?'.  */
      cp_lexer_consume_token (parser->lexer);
      /* Look for the matching `:'.  */
      cp_parser_require (parser, CPP_COLON, RT_COLON);
      consumed = true;
      break;

    case CPP_OPEN_PAREN:
      {
        /* Consume the `('.  */
        matching_parens parens;
        parens.consume_open (parser);
        /* Look for the matching `)'.  */
        token = parens.require_close (parser);
        if (token)
	  end_loc = token->location;
	op = CALL_EXPR;
	consumed = true;
	break;
      }

    case CPP_OPEN_SQUARE:
      /* Consume the `['.  */
      cp_lexer_consume_token (parser->lexer);
      /* Look for the matching `]'.  */
      token = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
      if (token)
	end_loc = token->location;
      op = ARRAY_REF;
      consumed = true;
      break;

    case CPP_UTF8STRING:
    case CPP_UTF8STRING_USERDEF:
      utf8 = true;
      /* FALLTHRU */
    case CPP_STRING:
    case CPP_WSTRING:
    case CPP_STRING16:
    case CPP_STRING32:
    case CPP_STRING_USERDEF:
    case CPP_WSTRING_USERDEF:
    case CPP_STRING16_USERDEF:
    case CPP_STRING32_USERDEF:
      {
	tree string_tree;
	int sz, len;

	if (cxx_dialect == cxx98)
	  maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);

	/* Consume the string.  */
	cp_expr str = cp_parser_userdef_string_literal (parser,
							/*lookup_udlit=*/false);
	if (str == error_mark_node)
	  return error_mark_node;
	else if (TREE_CODE (str) == USERDEF_LITERAL)
	  {
	    string_tree = USERDEF_LITERAL_VALUE (str.get_value ());
	    id = USERDEF_LITERAL_SUFFIX_ID (str.get_value ());
	    end_loc = str.get_location ();
	  }
	else
	  {
	    string_tree = str;
	    /* Look for the suffix identifier.  */
	    token = cp_lexer_peek_token (parser->lexer);
	    if (token->type == CPP_NAME)
	      {
		id = cp_parser_identifier (parser);
		end_loc = token->location;
	      }
	    else if (token->type == CPP_KEYWORD)
	      {
		error ("unexpected keyword;"
		       " remove space between quotes and suffix identifier");
		return error_mark_node;
	      }
	    else
	      {
		error ("expected suffix identifier");
		return error_mark_node;
	      }
	  }
	sz = TREE_INT_CST_LOW (TYPE_SIZE_UNIT
			       (TREE_TYPE (TREE_TYPE (string_tree))));
	len = TREE_STRING_LENGTH (string_tree) / sz - 1;
	if (len != 0)
	  {
	    error ("expected empty string after %<operator%> keyword");
	    return error_mark_node;
	  }
	if (utf8 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string_tree)))
	    != char_type_node)
	  {
	    error ("invalid encoding prefix in literal operator");
	    return error_mark_node;
	  }
	if (id != error_mark_node)
	  {
	    const char *name = IDENTIFIER_POINTER (id);
	    id = cp_literal_operator_id (name);
	  }
	/* Generate a location of the form:
	     "" _suffix_identifier
	     ^~~~~~~~~~~~~~~~~~~~~
	   with caret == start at the start token, finish at the end of the
	   suffix identifier.  */
	location_t combined_loc
	  = make_location (start_loc, start_loc, parser->lexer);
	return cp_expr (id, combined_loc);
      }

    default:
      /* Anything else is an error.  */
      break;
    }

  /* If we have selected an identifier, we need to consume the
     operator token.  */
  if (op != ERROR_MARK)
    {
      id = ovl_op_identifier (assop, op);
      if (!consumed)
	cp_lexer_consume_token (parser->lexer);
    }
  /* Otherwise, no valid operator name was present.  */
  else
    {
      cp_parser_error (parser, "expected operator");
      id = error_mark_node;
    }

  start_loc = make_location (start_loc, start_loc, get_finish (end_loc));
  return cp_expr (id, start_loc);
}

/* Parse a template-declaration.

   template-declaration:
     export [opt] template < template-parameter-list > declaration

   If MEMBER_P is TRUE, this template-declaration occurs within a
   class-specifier.

   The grammar rule given by the standard isn't correct.  What
   is really meant is:

   template-declaration:
     export [opt] template-parameter-list-seq
       decl-specifier-seq [opt] init-declarator [opt] ;
     export [opt] template-parameter-list-seq
       function-definition

   template-parameter-list-seq:
     template-parameter-list-seq [opt]
     template < template-parameter-list >

   Concept Extensions:

   template-parameter-list-seq:
     template < template-parameter-list > requires-clause [opt]

   requires-clause:
     requires logical-or-expression  */

static void
cp_parser_template_declaration (cp_parser* parser, bool member_p)
{
  /* Check for `export'.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXPORT))
    {
      /* Consume the `export' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Warn that this use of export is deprecated.  */
      if (cxx_dialect < cxx11)
	warning (0, "keyword %<export%> not implemented, and will be ignored");
      else if (cxx_dialect < cxx20)
	warning (0, "keyword %<export%> is deprecated, and is ignored");
      else
	warning (0, "keyword %<export%> is enabled with %<-fmodules-ts%>");
    }

  cp_parser_template_declaration_after_export (parser, member_p);
}

/* Parse a template-parameter-list.

   template-parameter-list:
     template-parameter
     template-parameter-list , template-parameter

   Returns a TREE_LIST.  Each node represents a template parameter.
   The nodes are connected via their TREE_CHAINs.  */

static tree
cp_parser_template_parameter_list (cp_parser* parser)
{
  tree parameter_list = NULL_TREE;

  /* Don't create wrapper nodes within a template-parameter-list,
     since we don't want to have different types based on the
     spelling location of constants and decls within them.  */
  auto_suppress_location_wrappers sentinel;

  begin_template_parm_list ();

  /* The loop below parses the template parms.  We first need to know
     the total number of template parms to be able to compute proper
     canonical types of each dependent type. So after the loop, when
     we know the total number of template parms,
     end_template_parm_list computes the proper canonical types and
     fixes up the dependent types accordingly.  */
  while (true)
    {
      tree parameter;
      bool is_non_type;
      bool is_parameter_pack;
      location_t parm_loc;

      /* Parse the template-parameter.  */
      parm_loc = cp_lexer_peek_token (parser->lexer)->location;
      parameter = cp_parser_template_parameter (parser,
                                                &is_non_type,
                                                &is_parameter_pack);
      /* Add it to the list.  */
      if (parameter != error_mark_node)
	parameter_list = process_template_parm (parameter_list,
						parm_loc,
						parameter,
						is_non_type,
						is_parameter_pack);
      else
       {
         tree err_parm = build_tree_list (parameter, parameter);
         parameter_list = chainon (parameter_list, err_parm);
       }

      /* If the next token is not a `,', we're done.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Otherwise, consume the `,' token.  */
      cp_lexer_consume_token (parser->lexer);
    }

  return end_template_parm_list (parameter_list);
}

/* Parse a introduction-list.

   introduction-list:
     introduced-parameter
     introduction-list , introduced-parameter

   introduced-parameter:
     ...[opt] identifier

   Returns a TREE_VEC of WILDCARD_DECLs.  If the parameter is a pack
   then the introduced parm will have WILDCARD_PACK_P set.  In addition, the
   WILDCARD_DECL will also have DECL_NAME set and token location in
   DECL_SOURCE_LOCATION.  */

static tree
cp_parser_introduction_list (cp_parser *parser)
{
  vec<tree, va_gc> *introduction_vec = make_tree_vector ();

  while (true)
    {
      bool is_pack = cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS);
      if (is_pack)
	cp_lexer_consume_token (parser->lexer);

      tree identifier = cp_parser_identifier (parser);
      if (identifier == error_mark_node)
	break;

      /* Build placeholder. */
      tree parm = build_nt (WILDCARD_DECL);
      DECL_SOURCE_LOCATION (parm)
	= cp_lexer_peek_token (parser->lexer)->location;
      DECL_NAME (parm) = identifier;
      WILDCARD_PACK_P (parm) = is_pack;
      vec_safe_push (introduction_vec, parm);

      /* If the next token is not a `,', we're done.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Otherwise, consume the `,' token.  */
      cp_lexer_consume_token (parser->lexer);
    }

  /* Convert the vec into a TREE_VEC.  */
  tree introduction_list = make_tree_vec (introduction_vec->length ());
  unsigned int n;
  tree parm;
  FOR_EACH_VEC_ELT (*introduction_vec, n, parm)
    TREE_VEC_ELT (introduction_list, n) = parm;

  release_tree_vector (introduction_vec);
  return introduction_list;
}

/* Given a declarator, get the declarator-id part, or NULL_TREE if this
   is an abstract declarator. */

static inline cp_declarator*
get_id_declarator (cp_declarator *declarator)
{
  cp_declarator *d = declarator;
  while (d && d->kind != cdk_id)
    d = d->declarator;
  return d;
}

/* Get the unqualified-id from the DECLARATOR or NULL_TREE if this
   is an abstract declarator. */

static inline tree
get_unqualified_id (cp_declarator *declarator)
{
  declarator = get_id_declarator (declarator);
  if (declarator)
    return declarator->u.id.unqualified_name;
  else
    return NULL_TREE;
}

/* Returns true if TYPE would declare a constrained constrained-parameter.  */

static inline bool
is_constrained_parameter (tree type)
{
  return (type
          && TREE_CODE (type) == TYPE_DECL
          && CONSTRAINED_PARM_CONCEPT (type)
          && DECL_P (CONSTRAINED_PARM_CONCEPT (type)));
}

/* Returns true if PARM declares a constrained-parameter. */

static inline bool
is_constrained_parameter (cp_parameter_declarator *parm)
{
  return is_constrained_parameter (parm->decl_specifiers.type);
}

/* Check that the type parameter is only a declarator-id, and that its
   type is not cv-qualified. */

bool
cp_parser_check_constrained_type_parm (cp_parser *parser,
				       cp_parameter_declarator *parm)
{
  if (!parm->declarator)
    return true;

  if (parm->declarator->kind != cdk_id)
    {
      cp_parser_error (parser, "invalid constrained type parameter");
      return false;
    }

  /* Don't allow cv-qualified type parameters.  */
  if (decl_spec_seq_has_spec_p (&parm->decl_specifiers, ds_const)
      || decl_spec_seq_has_spec_p (&parm->decl_specifiers, ds_volatile))
    {
      cp_parser_error (parser, "cv-qualified type parameter");
      return false;
    }

  return true;
}

/* Finish parsing/processing a template type parameter and checking
   various restrictions. */

static inline tree
cp_parser_constrained_type_template_parm (cp_parser *parser,
                                          tree id,
                                          cp_parameter_declarator* parmdecl)
{
  if (cp_parser_check_constrained_type_parm (parser, parmdecl))
    return finish_template_type_parm (class_type_node, id);
  else
    return error_mark_node;
}

static tree
finish_constrained_template_template_parm (tree proto, tree id)
{
  /* FIXME: This should probably be copied, and we may need to adjust
     the template parameter depths.  */
  tree saved_parms = current_template_parms;
  begin_template_parm_list ();
  current_template_parms = DECL_TEMPLATE_PARMS (proto);
  end_template_parm_list ();

  tree parm = finish_template_template_parm (class_type_node, id);
  current_template_parms = saved_parms;

  return parm;
}

/* Finish parsing/processing a template template parameter by borrowing
   the template parameter list from the prototype parameter.  */

static tree
cp_parser_constrained_template_template_parm (cp_parser *parser,
                                              tree proto,
                                              tree id,
                                              cp_parameter_declarator *parmdecl)
{
  if (!cp_parser_check_constrained_type_parm (parser, parmdecl))
    return error_mark_node;
  return finish_constrained_template_template_parm (proto, id);
}

/* Create a new non-type template parameter from the given PARM
   declarator.  */

static tree
cp_parser_constrained_non_type_template_parm (bool *is_non_type,
					      cp_parameter_declarator *parm)
{
  *is_non_type = true;
  cp_declarator *decl = parm->declarator;
  cp_decl_specifier_seq *specs = &parm->decl_specifiers;
  specs->type = TREE_TYPE (DECL_INITIAL (specs->type));
  return grokdeclarator (decl, specs, TPARM, 0, NULL);
}

/* Build a constrained template parameter based on the PARMDECL
   declarator. The type of PARMDECL is the constrained type, which
   refers to the prototype template parameter that ultimately
   specifies the type of the declared parameter. */

static tree
finish_constrained_parameter (cp_parser *parser,
                              cp_parameter_declarator *parmdecl,
                              bool *is_non_type)
{
  tree decl = parmdecl->decl_specifiers.type;
  tree id = get_unqualified_id (parmdecl->declarator);
  tree def = parmdecl->default_argument;
  tree proto = DECL_INITIAL (decl);

  /* Build the parameter. Return an error if the declarator was invalid. */
  tree parm;
  if (TREE_CODE (proto) == TYPE_DECL)
    parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl);
  else if (TREE_CODE (proto) == TEMPLATE_DECL)
    parm = cp_parser_constrained_template_template_parm (parser, proto, id,
							 parmdecl);
  else
    parm = cp_parser_constrained_non_type_template_parm (is_non_type, parmdecl);
  if (parm == error_mark_node)
    return error_mark_node;

  /* Finish the parameter decl and create a node attaching the
     default argument and constraint.  */
  parm = build_tree_list (def, parm);
  TEMPLATE_PARM_CONSTRAINTS (parm) = decl;

  return parm;
}

/* Returns true if the parsed type actually represents the declaration
   of a type template-parameter.  */

static bool
declares_constrained_type_template_parameter (tree type)
{
  return (is_constrained_parameter (type)
	  && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TYPE_PARM);
}

/* Returns true if the parsed type actually represents the declaration of
   a template template-parameter.  */

static bool
declares_constrained_template_template_parameter (tree type)
{
  return (is_constrained_parameter (type)
	  && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TEMPLATE_PARM);
}

/* Parse a default argument for a type template-parameter.
   Note that diagnostics are handled in cp_parser_template_parameter.  */

static tree
cp_parser_default_type_template_argument (cp_parser *parser)
{
  gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_EQ));

  /* Consume the `=' token.  */
  cp_lexer_consume_token (parser->lexer);

  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Tell cp_parser_lambda_expression this is a default argument.  */
  auto lvf = make_temp_override (parser->local_variables_forbidden_p);
  parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;

  /* Parse the default-argument.  */
  push_deferring_access_checks (dk_no_deferred);
  tree default_argument = cp_parser_type_id (parser,
					     CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
					     NULL);
  pop_deferring_access_checks ();

  if (flag_concepts && type_uses_auto (default_argument))
    {
      error_at (token->location,
		"invalid use of %<auto%> in default template argument");
      return error_mark_node;
    }

  return default_argument;
}

/* Parse a default argument for a template template-parameter.  */

static tree
cp_parser_default_template_template_argument (cp_parser *parser)
{
  gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_EQ));

  bool is_template;

  /* Consume the `='.  */
  cp_lexer_consume_token (parser->lexer);
  /* Parse the id-expression.  */
  push_deferring_access_checks (dk_no_deferred);
  /* save token before parsing the id-expression, for error
     reporting */
  const cp_token* token = cp_lexer_peek_token (parser->lexer);
  tree default_argument
    = cp_parser_id_expression (parser,
                               /*template_keyword_p=*/false,
                               /*check_dependency_p=*/true,
                               /*template_p=*/&is_template,
                               /*declarator_p=*/false,
                               /*optional_p=*/false);
  if (TREE_CODE (default_argument) == TYPE_DECL)
    /* If the id-expression was a template-id that refers to
       a template-class, we already have the declaration here,
       so no further lookup is needed.  */
    ;
  else
    /* Look up the name.  */
    default_argument
      = cp_parser_lookup_name (parser, default_argument,
                               none_type,
                               /*is_template=*/is_template,
                               /*is_namespace=*/false,
                               /*check_dependency=*/true,
                               /*ambiguous_decls=*/NULL,
                               token->location);
  /* See if the default argument is valid.  */
  default_argument = check_template_template_default_arg (default_argument);
  pop_deferring_access_checks ();
  return default_argument;
}

/* Parse a template-parameter.

   template-parameter:
     type-parameter
     parameter-declaration

   If all goes well, returns a TREE_LIST.  The TREE_VALUE represents
   the parameter.  The TREE_PURPOSE is the default value, if any.
   Returns ERROR_MARK_NODE on failure.  *IS_NON_TYPE is set to true
   iff this parameter is a non-type parameter.  *IS_PARAMETER_PACK is
   set to true iff this parameter is a parameter pack. */

static tree
cp_parser_template_parameter (cp_parser* parser, bool *is_non_type,
                              bool *is_parameter_pack)
{
  cp_token *token;
  cp_parameter_declarator *parameter_declarator;
  tree parm;

  /* Assume it is a type parameter or a template parameter.  */
  *is_non_type = false;
  /* Assume it not a parameter pack. */
  *is_parameter_pack = false;
  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* If it is `template', we have a type-parameter.  */
  if (token->keyword == RID_TEMPLATE)
    return cp_parser_type_parameter (parser, is_parameter_pack);
  /* If it is `class' or `typename' we do not know yet whether it is a
     type parameter or a non-type parameter.  Consider:

       template <typename T, typename T::X X> ...

     or:

       template <class C, class D*> ...

     Here, the first parameter is a type parameter, and the second is
     a non-type parameter.  We can tell by looking at the token after
     the identifier -- if it is a `,', `=', or `>' then we have a type
     parameter.  */
  if (token->keyword == RID_TYPENAME || token->keyword == RID_CLASS)
    {
      /* Peek at the token after `class' or `typename'.  */
      token = cp_lexer_peek_nth_token (parser->lexer, 2);
      /* If it's an ellipsis, we have a template type parameter
         pack. */
      if (token->type == CPP_ELLIPSIS)
        return cp_parser_type_parameter (parser, is_parameter_pack);
      /* If it's an identifier, skip it.  */
      if (token->type == CPP_NAME)
	token = cp_lexer_peek_nth_token (parser->lexer, 3);
      /* Now, see if the token looks like the end of a template
	 parameter.  */
      if (token->type == CPP_COMMA
	  || token->type == CPP_EQ
	  || token->type == CPP_GREATER)
	return cp_parser_type_parameter (parser, is_parameter_pack);
    }

  /* Otherwise, it is a non-type parameter or a constrained parameter.

     [temp.param]

     When parsing a default template-argument for a non-type
     template-parameter, the first non-nested `>' is taken as the end
     of the template parameter-list rather than a greater-than
     operator.  */
  parameter_declarator
     = cp_parser_parameter_declaration (parser,
					CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
					/*template_parm_p=*/true,
					/*parenthesized_p=*/NULL);

  if (!parameter_declarator)
    return error_mark_node;

  /* If the parameter declaration is marked as a parameter pack, set
   *IS_PARAMETER_PACK to notify the caller.  */
  if (parameter_declarator->template_parameter_pack_p)
    *is_parameter_pack = true;

  if (parameter_declarator->default_argument)
    {
      /* Can happen in some cases of erroneous input (c++/34892).  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	/* Consume the `...' for better error recovery.  */
	cp_lexer_consume_token (parser->lexer);
    }

  /* The parameter may have been constrained type parameter.  */
  if (is_constrained_parameter (parameter_declarator))
    return finish_constrained_parameter (parser,
                                         parameter_declarator,
                                         is_non_type);

  // Now we're sure that the parameter is a non-type parameter.
  *is_non_type = true;

  parm = grokdeclarator (parameter_declarator->declarator,
			 &parameter_declarator->decl_specifiers,
			 TPARM, /*initialized=*/0,
			 /*attrlist=*/NULL);
  if (parm == error_mark_node)
    return error_mark_node;

  return build_tree_list (parameter_declarator->default_argument, parm);
}

/* Parse a type-parameter.

   type-parameter:
     class identifier [opt]
     class identifier [opt] = type-id
     typename identifier [opt]
     typename identifier [opt] = type-id
     template < template-parameter-list > class identifier [opt]
     template < template-parameter-list > class identifier [opt]
       = id-expression

   GNU Extension (variadic templates):

   type-parameter:
     class ... identifier [opt]
     typename ... identifier [opt]

   Returns a TREE_LIST.  The TREE_VALUE is itself a TREE_LIST.  The
   TREE_PURPOSE is the default-argument, if any.  The TREE_VALUE is
   the declaration of the parameter.

   Sets *IS_PARAMETER_PACK if this is a template parameter pack. */

static tree
cp_parser_type_parameter (cp_parser* parser, bool *is_parameter_pack)
{
  cp_token *token;
  tree parameter;

  /* Look for a keyword to tell us what kind of parameter this is.  */
  token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_TYPENAME_TEMPLATE);
  if (!token)
    return error_mark_node;

  switch (token->keyword)
    {
    case RID_CLASS:
    case RID_TYPENAME:
      {
	tree identifier;
	tree default_argument;

        /* If the next token is an ellipsis, we have a template
           argument pack. */
        if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
          {
            /* Consume the `...' token. */
            cp_lexer_consume_token (parser->lexer);
            maybe_warn_variadic_templates ();

            *is_parameter_pack = true;
          }

	/* If the next token is an identifier, then it names the
	   parameter.  */
	if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	  identifier = cp_parser_identifier (parser);
	else
	  identifier = NULL_TREE;

	/* Create the parameter.  */
	parameter = finish_template_type_parm (class_type_node, identifier);

	/* If the next token is an `=', we have a default argument.  */
	if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	  {
	    default_argument
	      = cp_parser_default_type_template_argument (parser);

            /* Template parameter packs cannot have default
               arguments. */
            if (*is_parameter_pack)
              {
                if (identifier)
                  error_at (token->location,
			    "template parameter pack %qD cannot have a "
			    "default argument", identifier);
                else
                  error_at (token->location,
			    "template parameter packs cannot have "
			    "default arguments");
                default_argument = NULL_TREE;
              }
	    else if (check_for_bare_parameter_packs (default_argument))
	      default_argument = error_mark_node;
	  }
	else
	  default_argument = NULL_TREE;

	/* Create the combined representation of the parameter and the
	   default argument.  */
	parameter = build_tree_list (default_argument, parameter);
      }
      break;

    case RID_TEMPLATE:
      {
	tree identifier;
	tree default_argument;

	/* Look for the `<'.  */
	cp_parser_require (parser, CPP_LESS, RT_LESS);
	/* Parse the template-parameter-list.  */
	cp_parser_template_parameter_list (parser);
	/* Look for the `>'.  */
	cp_parser_require (parser, CPP_GREATER, RT_GREATER);

	/* If template requirements are present, parse them.  */
	if (flag_concepts)
          {
	    tree reqs = get_shorthand_constraints (current_template_parms);
	    if (tree dreqs = cp_parser_requires_clause_opt (parser, false))
              reqs = combine_constraint_expressions (reqs, dreqs);
	    TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
          }

	/* Look for the `class' or 'typename' keywords.  */
	cp_parser_type_parameter_key (parser);
        /* If the next token is an ellipsis, we have a template
           argument pack. */
        if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
          {
            /* Consume the `...' token. */
            cp_lexer_consume_token (parser->lexer);
            maybe_warn_variadic_templates ();

            *is_parameter_pack = true;
          }
	/* If the next token is an `=', then there is a
	   default-argument.  If the next token is a `>', we are at
	   the end of the parameter-list.  If the next token is a `,',
	   then we are at the end of this parameter.  */
	if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
	    && cp_lexer_next_token_is_not (parser->lexer, CPP_GREATER)
	    && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	  {
	    identifier = cp_parser_identifier (parser);
	    /* Treat invalid names as if the parameter were nameless.  */
	    if (identifier == error_mark_node)
	      identifier = NULL_TREE;
	  }
	else
	  identifier = NULL_TREE;

	/* Create the template parameter.  */
	parameter = finish_template_template_parm (class_type_node,
						   identifier);

	/* If the next token is an `=', then there is a
	   default-argument.  */
	if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	  {
	    default_argument
	      = cp_parser_default_template_template_argument (parser);

            /* Template parameter packs cannot have default
               arguments. */
            if (*is_parameter_pack)
              {
                if (identifier)
                  error_at (token->location,
			    "template parameter pack %qD cannot "
			    "have a default argument",
			    identifier);
                else
                  error_at (token->location, "template parameter packs cannot "
			    "have default arguments");
                default_argument = NULL_TREE;
              }
	  }
	else
	  default_argument = NULL_TREE;

	/* Create the combined representation of the parameter and the
	   default argument.  */
	parameter = build_tree_list (default_argument, parameter);
      }
      break;

    default:
      gcc_unreachable ();
      break;
    }

  return parameter;
}

/* Parse a template-id.

   template-id:
     template-name < template-argument-list [opt] >

   If TEMPLATE_KEYWORD_P is TRUE, then we have just seen the
   `template' keyword.  In this case, a TEMPLATE_ID_EXPR will be
   returned.  Otherwise, if the template-name names a function, or set
   of functions, returns a TEMPLATE_ID_EXPR.  If the template-name
   names a class, returns a TYPE_DECL for the specialization.

   If CHECK_DEPENDENCY_P is FALSE, names are looked up in
   uninstantiated templates.  */

static tree
cp_parser_template_id (cp_parser *parser,
		       bool template_keyword_p,
		       bool check_dependency_p,
		       enum tag_types tag_type,
		       bool is_declaration)
{
  tree templ;
  tree arguments;
  tree template_id;
  cp_token_position start_of_id = 0;
  cp_token *next_token = NULL, *next_token_2 = NULL;
  bool is_identifier;

  /* If the next token corresponds to a template-id, there is no need
     to reparse it.  */
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  if (token->type == CPP_TEMPLATE_ID)
    {
      cp_lexer_consume_token (parser->lexer);
      return saved_checks_value (token->u.tree_check_value);
    }

  /* Avoid performing name lookup if there is no possibility of
     finding a template-id.  */
  if ((token->type != CPP_NAME && token->keyword != RID_OPERATOR)
      || (token->type == CPP_NAME
	  && !cp_parser_nth_token_starts_template_argument_list_p
	       (parser, 2)))
    {
      cp_parser_error (parser, "expected template-id");
      return error_mark_node;
    }

  /* Remember where the template-id starts.  */
  if (cp_parser_uncommitted_to_tentative_parse_p (parser))
    start_of_id = cp_lexer_token_position (parser->lexer, false);

  push_deferring_access_checks (dk_deferred);

  /* Parse the template-name.  */
  is_identifier = false;
  templ = cp_parser_template_name (parser, template_keyword_p,
				   check_dependency_p,
				   is_declaration,
				   tag_type,
				   &is_identifier);

  /* Push any access checks inside the firewall we're about to create.  */
  vec<deferred_access_check, va_gc> *checks = get_deferred_access_checks ();
  pop_deferring_access_checks ();
  if (templ == error_mark_node || is_identifier)
    return templ;

  /* Since we're going to preserve any side-effects from this parse, set up a
     firewall to protect our callers from cp_parser_commit_to_tentative_parse
     in the template arguments.  */
  tentative_firewall firewall (parser);
  reopen_deferring_access_checks (checks);

  /* If we find the sequence `[:' after a template-name, it's probably
     a digraph-typo for `< ::'. Substitute the tokens and check if we can
     parse correctly the argument list.  */
  if (((next_token = cp_lexer_peek_token (parser->lexer))->type
       == CPP_OPEN_SQUARE)
      && next_token->flags & DIGRAPH
      && ((next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2))->type
	  == CPP_COLON)
      && !(next_token_2->flags & PREV_WHITE))
    {
      cp_parser_parse_tentatively (parser);
      /* Change `:' into `::'.  */
      next_token_2->type = CPP_SCOPE;
      /* Consume the first token (CPP_OPEN_SQUARE - which we pretend it is
	 CPP_LESS.  */
      cp_lexer_consume_token (parser->lexer);

      /* Parse the arguments.  */
      arguments = cp_parser_enclosed_template_argument_list (parser);
      if (!cp_parser_parse_definitely (parser))
	{
	  /* If we couldn't parse an argument list, then we revert our changes
	     and return simply an error. Maybe this is not a template-id
	     after all.  */
	  next_token_2->type = CPP_COLON;
	  cp_parser_error (parser, "expected %<<%>");
	  pop_deferring_access_checks ();
	  return error_mark_node;
	}
      /* Otherwise, emit an error about the invalid digraph, but continue
	 parsing because we got our argument list.  */
      if (permerror (next_token->location,
		     "%<<::%> cannot begin a template-argument list"))
	{
	  static bool hint = false;
	  inform (next_token->location,
		  "%<<:%> is an alternate spelling for %<[%>."
		  " Insert whitespace between %<<%> and %<::%>");
	  if (!hint && !flag_permissive)
	    {
	      inform (next_token->location, "(if you use %<-fpermissive%> "
		      "or %<-std=c++11%>, or %<-std=gnu++11%> G++ will "
		      "accept your code)");
	      hint = true;
	    }
	}
    }
  else
    {
      /* Look for the `<' that starts the template-argument-list.  */
      if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
	{
	  pop_deferring_access_checks ();
	  return error_mark_node;
	}
      /* Parse the arguments.  */
      arguments = cp_parser_enclosed_template_argument_list (parser);

      if ((cxx_dialect > cxx17)
	  && (TREE_CODE (templ) == FUNCTION_DECL || identifier_p (templ))
	  && !template_keyword_p
	  && (cp_parser_error_occurred (parser)
	      || cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)))
	{
	  /* This didn't go well.  */
	  if (TREE_CODE (templ) == FUNCTION_DECL)
	    {
	      /* C++20 says that "function-name < a;" is now ill-formed.  */
	      if (cp_parser_error_occurred (parser))
		{
		  error_at (token->location, "invalid template-argument-list");
		  inform (token->location, "function name as the left hand "
			  "operand of %<<%> is ill-formed in C++20; wrap the "
			  "function name in %<()%>");
		}
	      else
		/* We expect "f<targs>" to be followed by "(args)".  */
		error_at (cp_lexer_peek_token (parser->lexer)->location,
			  "expected %<(%> after template-argument-list");
	      if (start_of_id)
		/* Purge all subsequent tokens.  */
		cp_lexer_purge_tokens_after (parser->lexer, start_of_id);
	    }
	  else
	    cp_parser_simulate_error (parser);
	  pop_deferring_access_checks ();
	  return error_mark_node;
	}
    }

  /* Set the location to be of the form:
     template-name < template-argument-list [opt] >
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     with caret == start at the start of the template-name,
     ranging until the closing '>'.  */
  location_t combined_loc
    = make_location (token->location, token->location, parser->lexer);

  /* Check for concepts autos where they don't belong.  We could
     identify types in some cases of identifier TEMPL, looking ahead
     for a CPP_SCOPE, but that would buy us nothing: we accept auto in
     types.  We reject them in functions, but if what we have is an
     identifier, even with none_type we can't conclude it's NOT a
     type, we have to wait for template substitution.  */
  if (flag_concepts && check_auto_in_tmpl_args (templ, arguments))
    template_id = error_mark_node;
  /* Build a representation of the specialization.  */
  else if (identifier_p (templ))
    template_id = build_min_nt_loc (combined_loc,
				    TEMPLATE_ID_EXPR,
				    templ, arguments);
  else if (DECL_TYPE_TEMPLATE_P (templ)
	   || DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
    {
      /* In "template <typename T> ... A<T>::", A<T> is the abstract A
	 template (rather than some instantiation thereof) only if
	 is not nested within some other construct.  For example, in
	 "template <typename T> void f(T) { A<T>::", A<T> is just an
	 instantiation of A.  */
      bool entering_scope
	= (template_parm_scope_p ()
	   && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE));
      template_id
	= finish_template_type (templ, arguments, entering_scope);
    }
  else if (concept_definition_p (templ))
    {
      /* The caller will decide whether this is a concept check or type
	 constraint.  */
      template_id = build2_loc (combined_loc, TEMPLATE_ID_EXPR,
				boolean_type_node, templ, arguments);
    }
  else if (variable_template_p (templ))
    {
      template_id = lookup_template_variable (templ, arguments);
      if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
	SET_EXPR_LOCATION (template_id, combined_loc);
    }
  else if (TREE_CODE (templ) == TYPE_DECL
	   && TREE_CODE (TREE_TYPE (templ)) == TYPENAME_TYPE)
    {
      /* Some type template in dependent scope.  */
      tree &name = TYPENAME_TYPE_FULLNAME (TREE_TYPE (templ));
      name = build_min_nt_loc (combined_loc,
			       TEMPLATE_ID_EXPR,
			       name, arguments);
      template_id = templ;
    }
  else
    {
      /* If it's not a class-template or a template-template, it should be
	 a function-template.  */
      gcc_assert (OVL_P (templ) || BASELINK_P (templ));

      template_id = lookup_template_function (templ, arguments);
      if (TREE_CODE (template_id) == TEMPLATE_ID_EXPR)
	SET_EXPR_LOCATION (template_id, combined_loc);
    }

  /* If parsing tentatively, replace the sequence of tokens that makes
     up the template-id with a CPP_TEMPLATE_ID token.  That way,
     should we re-parse the token stream, we will not have to repeat
     the effort required to do the parse, nor will we issue duplicate
     error messages about problems during instantiation of the
     template.  */
  if (start_of_id
      /* Don't do this if we had a parse error in a declarator; re-parsing
	 might succeed if a name changes meaning (60361).  */
      && !(cp_parser_error_occurred (parser)
	   && cp_parser_parsing_tentatively (parser)
	   && parser->in_declarator_p))
    {
      /* Reset the contents of the START_OF_ID token.  */
      token->type = CPP_TEMPLATE_ID;
      token->location = combined_loc;

      /* Retrieve any deferred checks.  Do not pop this access checks yet
	 so the memory will not be reclaimed during token replacing below.  */
      token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
      token->tree_check_p = true;
      token->u.tree_check_value->value = template_id;
      token->u.tree_check_value->checks = get_deferred_access_checks ();
      token->keyword = RID_MAX;

      /* Purge all subsequent tokens.  */
      cp_lexer_purge_tokens_after (parser->lexer, start_of_id);

      /* ??? Can we actually assume that, if template_id ==
	 error_mark_node, we will have issued a diagnostic to the
	 user, as opposed to simply marking the tentative parse as
	 failed?  */
      if (cp_parser_error_occurred (parser) && template_id != error_mark_node)
	error_at (token->location, "parse error in template argument list");
    }

  pop_to_parent_deferring_access_checks ();
  return template_id;
}

/* Like cp_parser_template_id, called in non-type context.  */

static tree
cp_parser_template_id_expr (cp_parser *parser,
			    bool template_keyword_p,
			    bool check_dependency_p,
			    bool is_declaration)
{
  tree x = cp_parser_template_id (parser, template_keyword_p, check_dependency_p,
				  none_type, is_declaration);
  if (TREE_CODE (x) == TEMPLATE_ID_EXPR
      && concept_check_p (x))
    /* We didn't check the arguments in cp_parser_template_id; do that now.  */
    return build_concept_id (x);
  return x;
}

/* Parse a template-name.

   template-name:
     identifier

   The standard should actually say:

   template-name:
     identifier
     operator-function-id

   A defect report has been filed about this issue.

   A conversion-function-id cannot be a template name because they cannot
   be part of a template-id. In fact, looking at this code:

   a.operator K<int>()

   the conversion-function-id is "operator K<int>", and K<int> is a type-id.
   It is impossible to call a templated conversion-function-id with an
   explicit argument list, since the only allowed template parameter is
   the type to which it is converting.

   If TEMPLATE_KEYWORD_P is true, then we have just seen the
   `template' keyword, in a construction like:

     T::template f<3>()

   In that case `f' is taken to be a template-name, even though there
   is no way of knowing for sure.

   Returns the TEMPLATE_DECL for the template, or an OVERLOAD if the
   name refers to a set of overloaded functions, at least one of which
   is a template, or an IDENTIFIER_NODE with the name of the template,
   if TEMPLATE_KEYWORD_P is true.  If CHECK_DEPENDENCY_P is FALSE,
   names are looked up inside uninstantiated templates.  */

static tree
cp_parser_template_name (cp_parser* parser,
			 bool template_keyword_p,
			 bool check_dependency_p,
			 bool is_declaration,
			 enum tag_types tag_type,
			 bool *is_identifier)
{
  tree identifier;
  tree decl;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* If the next token is `operator', then we have either an
     operator-function-id or a conversion-function-id.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_OPERATOR))
    {
      /* We don't know whether we're looking at an
	 operator-function-id or a conversion-function-id.  */
      cp_parser_parse_tentatively (parser);
      /* Try an operator-function-id.  */
      identifier = cp_parser_operator_function_id (parser);
      /* If that didn't work, try a conversion-function-id.  */
      if (!cp_parser_parse_definitely (parser))
	{
	  cp_parser_error (parser, "expected template-name");
	  return error_mark_node;
	}
    }
  /* Look for the identifier.  */
  else
    identifier = cp_parser_identifier (parser);

  /* If we didn't find an identifier, we don't have a template-id.  */
  if (identifier == error_mark_node)
    return error_mark_node;

  /* If the name immediately followed the `template' keyword, then it
     is a template-name.  However, if the next token is not `<', then
     we do not treat it as a template-name, since it is not being used
     as part of a template-id.  This enables us to handle constructs
     like:

       template <typename T> struct S { S(); };
       template <typename T> S<T>::S();

     correctly.  We would treat `S' as a template -- if it were `S<T>'
     -- but we do not if there is no `<'.  */

  if (processing_template_decl
      && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
    {
      /* In a declaration, in a dependent context, we pretend that the
	 "template" keyword was present in order to improve error
	 recovery.  For example, given:

	   template <typename T> void f(T::X<int>);

	 we want to treat "X<int>" as a template-id.  */
      if (is_declaration
	  && !template_keyword_p
	  && parser->scope && TYPE_P (parser->scope)
	  && check_dependency_p
	  && dependent_scope_p (parser->scope)
	  /* Do not do this for dtors (or ctors), since they never
	     need the template keyword before their name.  */
	  && !constructor_name_p (identifier, parser->scope))
	{
	  cp_token_position start = 0;

	  /* Explain what went wrong.  */
	  error_at (token->location, "non-template %qD used as template",
		    identifier);
	  inform (token->location, "use %<%T::template %D%> to indicate that it is a template",
		  parser->scope, identifier);
	  /* If parsing tentatively, find the location of the "<" token.  */
	  if (cp_parser_simulate_error (parser))
	    start = cp_lexer_token_position (parser->lexer, true);
	  /* Parse the template arguments so that we can issue error
	     messages about them.  */
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_enclosed_template_argument_list (parser);
	  /* Skip tokens until we find a good place from which to
	     continue parsing.  */
	  cp_parser_skip_to_closing_parenthesis (parser,
						 /*recovering=*/true,
						 /*or_comma=*/true,
						 /*consume_paren=*/false);
	  /* If parsing tentatively, permanently remove the
	     template argument list.  That will prevent duplicate
	     error messages from being issued about the missing
	     "template" keyword.  */
	  if (start)
	    cp_lexer_purge_tokens_after (parser->lexer, start);
	  if (is_identifier)
	    *is_identifier = true;
	  parser->context->object_type = NULL_TREE;
	  return identifier;
	}

      /* If the "template" keyword is present, then there is generally
	 no point in doing name-lookup, so we just return IDENTIFIER.
	 But, if the qualifying scope is non-dependent then we can
	 (and must) do name-lookup normally.  */
      if (template_keyword_p)
	{
	  tree scope = (parser->scope ? parser->scope
			: parser->context->object_type);
	  if (scope && TYPE_P (scope)
	      && (!CLASS_TYPE_P (scope)
		  || (check_dependency_p && dependent_scope_p (scope))))
	    {
	      /* We're optimizing away the call to cp_parser_lookup_name, but
		 we still need to do this.  */
	      parser->object_scope = parser->context->object_type;
	      parser->context->object_type = NULL_TREE;
	      return identifier;
	    }
	}
    }

  /* cp_parser_lookup_name clears OBJECT_TYPE.  */
  tree scope = (parser->scope ? parser->scope
		: parser->context->object_type);

  /* Look up the name.  */
  decl = cp_parser_lookup_name (parser, identifier,
				tag_type,
				/*is_template=*/true,
				/*is_namespace=*/false,
				check_dependency_p,
				/*ambiguous_decls=*/NULL,
				token->location);

  decl = strip_using_decl (decl);

  /* 13.3 [temp.names] A < is interpreted as the delimiter of a
    template-argument-list if it follows a name that is not a
    conversion-function-id and
    - that follows the keyword template or a ~ after a nested-name-specifier or
    in a class member access expression, or
    - for which name lookup finds the injected-class-name of a class template
    or finds any declaration of a template, or
    - that is an unqualified name for which name lookup either finds one or
    more functions or finds nothing, or
    - that is a terminal name in a using-declarator (9.9), in a declarator-id
    (9.3.4), or in a type-only context other than a nested-name-specifier
    (13.8).  */

  /* Handle injected-class-name.  */
  decl = maybe_get_template_decl_from_type_decl (decl);

  /* If DECL is a template, then the name was a template-name.  */
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      if ((TREE_DEPRECATED (decl) || TREE_UNAVAILABLE (decl))
	  && deprecated_state != UNAVAILABLE_DEPRECATED_SUPPRESS)
	{
	  tree d = DECL_TEMPLATE_RESULT (decl);
	  tree attr;
	  if (TREE_CODE (d) == TYPE_DECL)
	    attr = TYPE_ATTRIBUTES (TREE_TYPE (d));
	  else
	    attr = DECL_ATTRIBUTES (d);
	  if (TREE_UNAVAILABLE (decl))
	    {
	      attr = lookup_attribute ("unavailable", attr);
	      error_unavailable_use (decl, attr);
	    }
	  else if (TREE_DEPRECATED (decl)
		   && deprecated_state != DEPRECATED_SUPPRESS)
	    {
	      attr = lookup_attribute ("deprecated", attr);
	      warn_deprecated_use (decl, attr);
	    }
	}
    }
  else
    {
      /* Look through an overload set for any templates.  */
      bool found = false;

      for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
	   !found && iter; ++iter)
	if (TREE_CODE (*iter) == TEMPLATE_DECL)
	  found = true;

      /* "an unqualified name for which name lookup either finds one or more
	 functions or finds nothing".  */
      if (!found
	  && (cxx_dialect > cxx17)
	  && !scope
	  && cp_lexer_next_token_is (parser->lexer, CPP_LESS)
	  && tag_type == none_type)
	{
	  /* The "more functions" case.  Just use the OVERLOAD as normally.
	     We don't use is_overloaded_fn here to avoid considering
	     BASELINKs.  */
	  if (TREE_CODE (decl) == OVERLOAD
	      /* Name lookup found one function.  */
	      || TREE_CODE (decl) == FUNCTION_DECL
	      /* Name lookup found nothing.  */
	      || decl == error_mark_node)
	    found = true;
	}

      /* "that follows the keyword template"..."in a type-only context" */
      if (!found && scope
	  && (template_keyword_p || tag_type != none_type)
	  && dependentish_scope_p (scope)
	  && cp_parser_nth_token_starts_template_argument_list_p (parser, 1))
	found = true;

      if (!found)
	{
	  /* The name does not name a template.  */
	  cp_parser_error (parser, "expected template-name");
	  return error_mark_node;
	}
      else if ((!DECL_P (decl) && !is_overloaded_fn (decl))
	       || TREE_CODE (decl) == USING_DECL
	       /* cp_parser_template_id can only handle some TYPE_DECLs.  */
	       || (TREE_CODE (decl) == TYPE_DECL
		   && TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE))
	/* Repeat the lookup at instantiation time.  */
	decl = identifier;
    }

  return decl;
}

/* Parse a template-argument-list.

   template-argument-list:
     template-argument ... [opt]
     template-argument-list , template-argument ... [opt]

   Returns a TREE_VEC containing the arguments.  */

static tree
cp_parser_template_argument_list (cp_parser* parser)
{
  bool saved_in_template_argument_list_p;
  bool saved_ice_p;
  bool saved_non_ice_p;

  /* Don't create location wrapper nodes within a template-argument-list.  */
  auto_suppress_location_wrappers sentinel;

  saved_in_template_argument_list_p = parser->in_template_argument_list_p;
  parser->in_template_argument_list_p = true;
  /* Even if the template-id appears in an integral
     constant-expression, the contents of the argument list do
     not.  */
  saved_ice_p = parser->integral_constant_expression_p;
  parser->integral_constant_expression_p = false;
  saved_non_ice_p = parser->non_integral_constant_expression_p;
  parser->non_integral_constant_expression_p = false;

  /* Parse the arguments.  */
  auto_vec<tree, 10> args;
  do
    {
      if (!args.is_empty ())
	/* Consume the comma.  */
	cp_lexer_consume_token (parser->lexer);

      /* Parse the template-argument.  */
      tree argument = cp_parser_template_argument (parser);

      /* If the next token is an ellipsis, we're expanding a template
         argument pack. */
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
        {
	  if (argument == error_mark_node)
	    {
	      cp_token *token = cp_lexer_peek_token (parser->lexer);
	      error_at (token->location,
			"expected parameter pack before %<...%>");
	    }
          /* Consume the `...' token. */
          cp_lexer_consume_token (parser->lexer);

          /* Make the argument into a TYPE_PACK_EXPANSION or
             EXPR_PACK_EXPANSION. */
          argument = make_pack_expansion (argument);
        }

      args.safe_push (argument);
    }
  while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA));

  int n_args = args.length ();
  tree vec = make_tree_vec (n_args);

  for (int i = 0; i < n_args; i++)
    TREE_VEC_ELT (vec, i) = args[i];

  parser->non_integral_constant_expression_p = saved_non_ice_p;
  parser->integral_constant_expression_p = saved_ice_p;
  parser->in_template_argument_list_p = saved_in_template_argument_list_p;
  if (CHECKING_P)
    SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (vec, TREE_VEC_LENGTH (vec));
  return vec;
}

/* Parse a template-argument.

   template-argument:
     assignment-expression
     type-id
     id-expression

   The representation is that of an assignment-expression, type-id, or
   id-expression -- except that the qualified id-expression is
   evaluated, so that the value returned is either a DECL or an
   OVERLOAD.

   Although the standard says "assignment-expression", it forbids
   throw-expressions or assignments in the template argument.
   Therefore, we use "conditional-expression" instead.  */

static tree
cp_parser_template_argument (cp_parser* parser)
{
  tree argument;
  bool template_p;
  bool address_p;
  bool maybe_type_id = false;
  cp_token *token = NULL, *argument_start_token = NULL;
  location_t loc = 0;
  cp_id_kind idk;

  /* There's really no way to know what we're looking at, so we just
     try each alternative in order.

       [temp.arg]

       In a template-argument, an ambiguity between a type-id and an
       expression is resolved to a type-id, regardless of the form of
       the corresponding template-parameter.

     Therefore, we try a type-id first.  */
  cp_parser_parse_tentatively (parser);
  argument = cp_parser_template_type_arg (parser);
  /* If there was no error parsing the type-id but the next token is a
     '>>', our behavior depends on which dialect of C++ we're
     parsing. In C++98, we probably found a typo for '> >'. But there
     are type-id which are also valid expressions. For instance:

     struct X { int operator >> (int); };
     template <int V> struct Foo {};
     Foo<X () >> 5> r;

     Here 'X()' is a valid type-id of a function type, but the user just
     wanted to write the expression "X() >> 5". Thus, we remember that we
     found a valid type-id, but we still try to parse the argument as an
     expression to see what happens.

     In C++0x, the '>>' will be considered two separate '>'
     tokens.  */
  if (!cp_parser_error_occurred (parser)
      && ((cxx_dialect == cxx98
	   && cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
	  /* Similarly for >= which
	     cp_parser_next_token_ends_template_argument_p treats for
	     diagnostics purposes as mistyped > =, but can be valid
	     after a type-id.  */
	  || cp_lexer_next_token_is (parser->lexer, CPP_GREATER_EQ)))
    {
      maybe_type_id = true;
      cp_parser_abort_tentative_parse (parser);
    }
  else
    {
      /* If the next token isn't a `,' or a `>', then this argument wasn't
      really finished. This means that the argument is not a valid
      type-id.  */
      if (!cp_parser_next_token_ends_template_argument_p (parser))
	cp_parser_error (parser, "expected template-argument");
      /* If that worked, we're done.  */
      if (cp_parser_parse_definitely (parser))
	return argument;
    }
  /* We're still not sure what the argument will be.  */
  cp_parser_parse_tentatively (parser);
  /* Try a template.  */
  argument_start_token = cp_lexer_peek_token (parser->lexer);
  argument = cp_parser_id_expression (parser,
				      /*template_keyword_p=*/false,
				      /*check_dependency_p=*/true,
				      &template_p,
				      /*declarator_p=*/false,
				      /*optional_p=*/false);
  /* If the next token isn't a `,' or a `>', then this argument wasn't
     really finished.  */
  if (!cp_parser_next_token_ends_template_argument_p (parser))
    cp_parser_error (parser, "expected template-argument");
  if (!cp_parser_error_occurred (parser))
    {
      /* Figure out what is being referred to.  If the id-expression
	 was for a class template specialization, then we will have a
	 TYPE_DECL at this point.  There is no need to do name lookup
	 at this point in that case.  */
      if (TREE_CODE (argument) != TYPE_DECL)
	argument = cp_parser_lookup_name (parser, argument,
					  none_type,
					  /*is_template=*/template_p,
					  /*is_namespace=*/false,
					  /*check_dependency=*/true,
					  /*ambiguous_decls=*/NULL,
					  argument_start_token->location);
      if (TREE_CODE (argument) != TEMPLATE_DECL
	       && TREE_CODE (argument) != UNBOUND_CLASS_TEMPLATE)
	cp_parser_error (parser, "expected template-name");
    }
  if (cp_parser_parse_definitely (parser))
    {
      if (TREE_UNAVAILABLE (argument))
	error_unavailable_use (argument, NULL_TREE);
      else if (TREE_DEPRECATED (argument))
	warn_deprecated_use (argument, NULL_TREE);
      return argument;
    }
  /* It must be a non-type argument.  In C++17 any constant-expression is
     allowed.  */
  if (cxx_dialect > cxx14)
    goto general_expr;

  /* Otherwise, the permitted cases are given in [temp.arg.nontype]:

     -- an integral constant-expression of integral or enumeration
	type; or

     -- the name of a non-type template-parameter; or

     -- the name of an object or function with external linkage...

     -- the address of an object or function with external linkage...

     -- a pointer to member...  */
  /* Look for a non-type template parameter.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      cp_parser_parse_tentatively (parser);
      argument = cp_parser_primary_expression (parser,
					       /*address_p=*/false,
					       /*cast_p=*/false,
					       /*template_arg_p=*/true,
					       &idk);
      if (TREE_CODE (argument) != TEMPLATE_PARM_INDEX
	  || !cp_parser_next_token_ends_template_argument_p (parser))
	cp_parser_simulate_error (parser);
      if (cp_parser_parse_definitely (parser))
	return argument;
    }

  /* If the next token is "&", the argument must be the address of an
     object or function with external linkage.  */
  address_p = cp_lexer_next_token_is (parser->lexer, CPP_AND);
  if (address_p)
    {
      loc = cp_lexer_peek_token (parser->lexer)->location;
      cp_lexer_consume_token (parser->lexer);
    }
  /* See if we might have an id-expression.  */
  token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_NAME
      || token->keyword == RID_OPERATOR
      || token->type == CPP_SCOPE
      || token->type == CPP_TEMPLATE_ID
      || token->type == CPP_NESTED_NAME_SPECIFIER)
    {
      cp_parser_parse_tentatively (parser);
      argument = cp_parser_primary_expression (parser,
					       address_p,
					       /*cast_p=*/false,
					       /*template_arg_p=*/true,
					       &idk);
      if (cp_parser_error_occurred (parser)
	  || !cp_parser_next_token_ends_template_argument_p (parser))
	cp_parser_abort_tentative_parse (parser);
      else
	{
	  tree probe;

	  if (INDIRECT_REF_P (argument))
	    {
	      /* Strip the dereference temporarily.  */
	      gcc_assert (REFERENCE_REF_P (argument));
	      argument = TREE_OPERAND (argument, 0);
	    }

	  /* If we're in a template, we represent a qualified-id referring
	     to a static data member as a SCOPE_REF even if the scope isn't
	     dependent so that we can check access control later.  */
	  probe = argument;
	  if (TREE_CODE (probe) == SCOPE_REF)
	    probe = TREE_OPERAND (probe, 1);
	  if (VAR_P (probe))
	    {
	      /* A variable without external linkage might still be a
		 valid constant-expression, so no error is issued here
		 if the external-linkage check fails.  */
	      if (!address_p && !DECL_EXTERNAL_LINKAGE_P (probe))
		cp_parser_simulate_error (parser);
	    }
	  else if (is_overloaded_fn (argument))
	    /* All overloaded functions are allowed; if the external
	       linkage test does not pass, an error will be issued
	       later.  */
	    ;
	  else if (address_p
		   && (TREE_CODE (argument) == OFFSET_REF
		       || TREE_CODE (argument) == SCOPE_REF))
	    /* A pointer-to-member.  */
	    ;
	  else if (TREE_CODE (argument) == TEMPLATE_PARM_INDEX)
	    ;
	  else
	    cp_parser_simulate_error (parser);

	  if (cp_parser_parse_definitely (parser))
	    {
	      if (address_p)
		argument = build_x_unary_op (loc, ADDR_EXPR, argument,
					     NULL_TREE, tf_warning_or_error);
	      else
		argument = convert_from_reference (argument);
	      return argument;
	    }
	}
    }
  /* If the argument started with "&", there are no other valid
     alternatives at this point.  */
  if (address_p)
    {
      cp_parser_error (parser, "invalid non-type template argument");
      return error_mark_node;
    }

 general_expr:
  /* If the argument wasn't successfully parsed as a type-id followed
     by '>>', the argument can only be a constant expression now.
     Otherwise, we try parsing the constant-expression tentatively,
     because the argument could really be a type-id.  */
  if (maybe_type_id)
    cp_parser_parse_tentatively (parser);

  if (cxx_dialect <= cxx14)
    argument = cp_parser_constant_expression (parser);
  else
    {
      /* In C++20, we can encounter a braced-init-list.  */
      if (cxx_dialect >= cxx20
	  && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	{
	  bool expr_non_constant_p;
	  return cp_parser_braced_list (parser, &expr_non_constant_p);
	}

      /* With C++17 generalized non-type template arguments we need to handle
	 lvalue constant expressions, too.  */
      argument = cp_parser_assignment_expression (parser);
      require_potential_constant_expression (argument);
    }

  if (!maybe_type_id)
    return argument;
  if (!cp_parser_next_token_ends_template_argument_p (parser))
    cp_parser_error (parser, "expected template-argument");
  if (cp_parser_parse_definitely (parser))
    return argument;
  /* We did our best to parse the argument as a non type-id, but that
     was the only alternative that matched (albeit with a '>' after
     it). We can assume it's just a typo from the user, and a
     diagnostic will then be issued.  */
  return cp_parser_template_type_arg (parser);
}

/* Parse an explicit-instantiation.

   explicit-instantiation:
     template declaration

   Although the standard says `declaration', what it really means is:

   explicit-instantiation:
     template decl-specifier-seq [opt] declarator [opt] ;

   Things like `template int S<int>::i = 5, int S<double>::j;' are not
   supposed to be allowed.  A defect report has been filed about this
   issue.

   GNU Extension:

   explicit-instantiation:
     storage-class-specifier template
       decl-specifier-seq [opt] declarator [opt] ;
     function-specifier template
       decl-specifier-seq [opt] declarator [opt] ;  */

static void
cp_parser_explicit_instantiation (cp_parser* parser)
{
  int declares_class_or_enum;
  cp_decl_specifier_seq decl_specifiers;
  tree extension_specifier = NULL_TREE;

  auto_timevar tv (TV_TEMPLATE_INST);

  /* Look for an (optional) storage-class-specifier or
     function-specifier.  */
  if (cp_parser_allow_gnu_extensions_p (parser))
    {
      extension_specifier
	= cp_parser_storage_class_specifier_opt (parser);
      if (!extension_specifier)
	extension_specifier
	  = cp_parser_function_specifier_opt (parser,
					      /*decl_specs=*/NULL);
    }

  /* Look for the `template' keyword.  */
  cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
  /* Let the front end know that we are processing an explicit
     instantiation.  */
  begin_explicit_instantiation ();
  /* [temp.explicit] says that we are supposed to ignore access
     control while processing explicit instantiation directives.  */
  push_deferring_access_checks (dk_no_check);
  /* Parse a decl-specifier-seq.  */
  cp_parser_decl_specifier_seq (parser,
				CP_PARSER_FLAGS_OPTIONAL,
				&decl_specifiers,
				&declares_class_or_enum);

  cp_omp_declare_simd_data odsd;
  if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
    cp_parser_handle_directive_omp_attributes (parser,
					       &decl_specifiers.attributes,
					       &odsd, true);

  /* If there was exactly one decl-specifier, and it declared a class,
     and there's no declarator, then we have an explicit type
     instantiation.  */
  if (declares_class_or_enum && cp_parser_declares_only_class_p (parser))
    {
      tree type = check_tag_decl (&decl_specifiers,
				  /*explicit_type_instantiation_p=*/true);
      /* Turn access control back on for names used during
	 template instantiation.  */
      pop_deferring_access_checks ();
      if (type)
	do_type_instantiation (type, extension_specifier,
			       /*complain=*/tf_error);
    }
  else
    {
      cp_declarator *declarator;
      tree decl;

      /* Parse the declarator.  */
      declarator
	= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
				CP_PARSER_FLAGS_NONE,
				/*ctor_dtor_or_conv_p=*/NULL,
				/*parenthesized_p=*/NULL,
				/*member_p=*/false,
				/*friend_p=*/false,
				/*static_p=*/false);
      if (declares_class_or_enum & 2)
	cp_parser_check_for_definition_in_return_type (declarator,
						       decl_specifiers.type,
						       decl_specifiers.locations[ds_type_spec]);
      if (declarator != cp_error_declarator)
	{
	  if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_inline))
	    permerror (decl_specifiers.locations[ds_inline],
		       "explicit instantiation shall not use"
		       " %<inline%> specifier");
	  if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_constexpr))
	    permerror (decl_specifiers.locations[ds_constexpr],
		       "explicit instantiation shall not use"
		       " %<constexpr%> specifier");
	  if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_consteval))
	    permerror (decl_specifiers.locations[ds_consteval],
		       "explicit instantiation shall not use"
		       " %<consteval%> specifier");

	  decl = grokdeclarator (declarator, &decl_specifiers,
				 NORMAL, 0, &decl_specifiers.attributes);
	  /* Turn access control back on for names used during
	     template instantiation.  */
	  pop_deferring_access_checks ();
	  /* Do the explicit instantiation.  */
	  do_decl_instantiation (decl, extension_specifier);
	}
      else
	{
	  pop_deferring_access_checks ();
	  /* Skip the body of the explicit instantiation.  */
	  cp_parser_skip_to_end_of_statement (parser);
	}
    }
  /* We're done with the instantiation.  */
  end_explicit_instantiation ();

  cp_parser_consume_semicolon_at_end_of_statement (parser);

  cp_finalize_omp_declare_simd (parser, &odsd);
}

/* Parse an explicit-specialization.

   explicit-specialization:
     template < > declaration

   Although the standard says `declaration', what it really means is:

   explicit-specialization:
     template <> decl-specifier [opt] init-declarator [opt] ;
     template <> function-definition
     template <> explicit-specialization
     template <> template-declaration  */

static void
cp_parser_explicit_specialization (cp_parser* parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Look for the `template' keyword.  */
  cp_parser_require_keyword (parser, RID_TEMPLATE, RT_TEMPLATE);
  /* Look for the `<'.  */
  cp_parser_require (parser, CPP_LESS, RT_LESS);
  /* Look for the `>'.  */
  cp_parser_require (parser, CPP_GREATER, RT_GREATER);
  /* We have processed another parameter list.  */
  ++parser->num_template_parameter_lists;

  /* [temp]

     A template ... explicit specialization ... shall not have C
     linkage.  */
  bool need_lang_pop = current_lang_name == lang_name_c;
  if (need_lang_pop)
    {
      error_at (token->location, "template specialization with C linkage");
      maybe_show_extern_c_location ();

      /* Give it C++ linkage to avoid confusing other parts of the
	 front end.  */
      push_lang_context (lang_name_cplusplus);
    }

  /* Let the front end know that we are beginning a specialization.  */
  if (begin_specialization ())
    {
      /* If the next keyword is `template', we need to figure out
	 whether or not we're looking a template-declaration.  */
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
	{
	  if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
	      && cp_lexer_peek_nth_token (parser->lexer, 3)->type != CPP_GREATER)
	    cp_parser_template_declaration_after_export (parser,
							 /*member_p=*/false);
	  else
	    cp_parser_explicit_specialization (parser);
	}
      else
	/* Parse the dependent declaration.  */
	cp_parser_single_declaration (parser,
				      /*checks=*/NULL,
				      /*member_p=*/false,
				      /*explicit_specialization_p=*/true,
				      /*friend_p=*/NULL);
    }

  /* We're done with the specialization.  */
  end_specialization ();

  /* For the erroneous case of a template with C linkage, we pushed an
     implicit C++ linkage scope; exit that scope now.  */
  if (need_lang_pop)
    pop_lang_context ();

  /* We're done with this parameter list.  */
  --parser->num_template_parameter_lists;
}

/* Preserve the attributes across a garbage collect (by making it a GC
   root), which can occur when parsing a member function.  */

static GTY(()) vec<tree, va_gc> *cp_parser_decl_specs_attrs;

/* Parse a type-specifier.

   type-specifier:
     simple-type-specifier
     class-specifier
     enum-specifier
     elaborated-type-specifier
     cv-qualifier

   GNU Extension:

   type-specifier:
     __complex__

   Returns a representation of the type-specifier.  For a
   class-specifier, enum-specifier, or elaborated-type-specifier, a
   TREE_TYPE is returned; otherwise, a TYPE_DECL is returned.

   The parser flags FLAGS is used to control type-specifier parsing.

   If IS_DECLARATION is TRUE, then this type-specifier is appearing
   in a decl-specifier-seq.

   If DECLARES_CLASS_OR_ENUM is non-NULL, and the type-specifier is a
   class-specifier, enum-specifier, or elaborated-type-specifier, then
   *DECLARES_CLASS_OR_ENUM is set to a nonzero value.  The value is 1
   if a type is declared; 2 if it is defined.  Otherwise, it is set to
   zero.

   If IS_CV_QUALIFIER is non-NULL, and the type-specifier is a
   cv-qualifier, then IS_CV_QUALIFIER is set to TRUE.  Otherwise, it
   is set to FALSE.  */

static tree
cp_parser_type_specifier (cp_parser* parser,
			  cp_parser_flags flags,
			  cp_decl_specifier_seq *decl_specs,
			  bool is_declaration,
			  int* declares_class_or_enum,
			  bool* is_cv_qualifier)
{
  tree type_spec = NULL_TREE;
  cp_token *token;
  enum rid keyword;
  cp_decl_spec ds = ds_last;

  /* Assume this type-specifier does not declare a new type.  */
  if (declares_class_or_enum)
    *declares_class_or_enum = 0;
  /* And that it does not specify a cv-qualifier.  */
  if (is_cv_qualifier)
    *is_cv_qualifier = false;
  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* If we're looking at a keyword, we can use that to guide the
     production we choose.  */
  keyword = token->keyword;
  switch (keyword)
    {
    case RID_ENUM:
      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
	goto elaborated_type_specifier;

      /* Look for the enum-specifier.  */
      type_spec = cp_parser_enum_specifier (parser);
      /* If that worked, we're done.  */
      if (type_spec)
	{
	  if (declares_class_or_enum)
	    *declares_class_or_enum = 2;
	  if (decl_specs)
	    cp_parser_set_decl_spec_type (decl_specs,
					  type_spec,
					  token,
					  /*type_definition_p=*/true);
	  return type_spec;
	}
      else
	goto elaborated_type_specifier;

      /* Any of these indicate either a class-specifier, or an
	 elaborated-type-specifier.  */
    case RID_CLASS:
    case RID_STRUCT:
    case RID_UNION:
      if ((flags & CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS))
	goto elaborated_type_specifier;

      /* Parse tentatively so that we can back up if we don't find a
	 class-specifier.  */
      cp_parser_parse_tentatively (parser);
      if (decl_specs->attributes)
	vec_safe_push (cp_parser_decl_specs_attrs, decl_specs->attributes);
      /* Look for the class-specifier.  */
      type_spec = cp_parser_class_specifier (parser);
      if (decl_specs->attributes)
	cp_parser_decl_specs_attrs->pop ();
      invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, type_spec);
      /* If that worked, we're done.  */
      if (cp_parser_parse_definitely (parser))
	{
	  if (declares_class_or_enum)
	    *declares_class_or_enum = 2;
	  if (decl_specs)
	    cp_parser_set_decl_spec_type (decl_specs,
					  type_spec,
					  token,
					  /*type_definition_p=*/true);
	  return type_spec;
	}

      /* Fall through.  */
    elaborated_type_specifier:
      /* We're declaring (not defining) a class or enum.  */
      if (declares_class_or_enum)
	*declares_class_or_enum = 1;

      /* Fall through.  */
    case RID_TYPENAME:
      /* Look for an elaborated-type-specifier.  */
      type_spec
	= (cp_parser_elaborated_type_specifier
	   (parser,
	    decl_spec_seq_has_spec_p (decl_specs, ds_friend),
	    is_declaration));
      if (decl_specs)
	cp_parser_set_decl_spec_type (decl_specs,
				      type_spec,
				      token,
				      /*type_definition_p=*/false);
      return type_spec;

    case RID_CONST:
      ds = ds_const;
      if (is_cv_qualifier)
	*is_cv_qualifier = true;
      break;

    case RID_VOLATILE:
      ds = ds_volatile;
      if (is_cv_qualifier)
	*is_cv_qualifier = true;
      break;

    case RID_RESTRICT:
      ds = ds_restrict;
      if (is_cv_qualifier)
	*is_cv_qualifier = true;
      break;

    case RID_COMPLEX:
      /* The `__complex__' keyword is a GNU extension.  */
      ds = ds_complex;
      break;

    default:
      break;
    }

  /* Handle simple keywords.  */
  if (ds != ds_last)
    {
      if (decl_specs)
	{
	  set_and_check_decl_spec_loc (decl_specs, ds, token);
	  decl_specs->any_specifiers_p = true;
	}
      return cp_lexer_consume_token (parser->lexer)->u.value;
    }

  /* If we do not already have a type-specifier, assume we are looking
     at a simple-type-specifier.  */
  type_spec = cp_parser_simple_type_specifier (parser,
					       decl_specs,
					       flags);

  /* If we didn't find a type-specifier, and a type-specifier was not
     optional in this context, issue an error message.  */
  if (!type_spec && !(flags & CP_PARSER_FLAGS_OPTIONAL))
    {
      cp_parser_error (parser, "expected type specifier");
      return error_mark_node;
    }

  return type_spec;
}

/* Parse a simple-type-specifier.

   simple-type-specifier:
     :: [opt] nested-name-specifier [opt] type-name
     :: [opt] nested-name-specifier template template-id
     char
     wchar_t
     bool
     short
     int
     long
     signed
     unsigned
     float
     double
     void

   C++11 Extension:

   simple-type-specifier:
     auto
     decltype ( expression )
     char16_t
     char32_t
     __underlying_type ( type-id )

   C++17 extension:

     nested-name-specifier(opt) template-name

   GNU Extension:

   simple-type-specifier:
     __int128
     __typeof__ unary-expression
     __typeof__ ( type-id )
     __typeof__ ( type-id ) { initializer-list , [opt] }

   Concepts Extension:

   simple-type-specifier:
     constrained-type-specifier

   Returns the indicated TYPE_DECL.  If DECL_SPECS is not NULL, it is
   appropriately updated.  */

static tree
cp_parser_simple_type_specifier (cp_parser* parser,
				 cp_decl_specifier_seq *decl_specs,
				 cp_parser_flags flags)
{
  tree type = NULL_TREE;
  cp_token *token;
  int idx;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* If we're looking at a keyword, things are easy.  */
  switch (token->keyword)
    {
    case RID_CHAR:
      if (decl_specs)
	decl_specs->explicit_char_p = true;
      type = char_type_node;
      break;
    case RID_CHAR8:
      type = char8_type_node;
      break;
    case RID_CHAR16:
      type = char16_type_node;
      break;
    case RID_CHAR32:
      type = char32_type_node;
      break;
    case RID_WCHAR:
      type = wchar_type_node;
      break;
    case RID_BOOL:
      type = boolean_type_node;
      break;
    case RID_SHORT:
      set_and_check_decl_spec_loc (decl_specs, ds_short, token);
      type = short_integer_type_node;
      break;
    case RID_INT:
      if (decl_specs)
	decl_specs->explicit_int_p = true;
      type = integer_type_node;
      break;
    case RID_INT_N_0:
    case RID_INT_N_1:
    case RID_INT_N_2:
    case RID_INT_N_3:
      idx = token->keyword - RID_INT_N_0;
      if (! int_n_enabled_p [idx])
	break;
      if (decl_specs)
	{
	  decl_specs->explicit_intN_p = true;
	  decl_specs->int_n_idx = idx;
	  /* Check if the alternate "__intN__" form has been used instead of
	     "__intN".  */
	  if (startswith (IDENTIFIER_POINTER (token->u.value)
			  + (IDENTIFIER_LENGTH (token->u.value) - 2), "__"))
	    decl_specs->int_n_alt = true;
	}
      type = int_n_trees [idx].signed_type;
      break;
    case RID_LONG:
      if (decl_specs)
	set_and_check_decl_spec_loc (decl_specs, ds_long, token);
      type = long_integer_type_node;
      break;
    case RID_SIGNED:
      set_and_check_decl_spec_loc (decl_specs, ds_signed, token);
      type = integer_type_node;
      break;
    case RID_UNSIGNED:
      set_and_check_decl_spec_loc (decl_specs, ds_unsigned, token);
      type = unsigned_type_node;
      break;
    case RID_FLOAT:
      type = float_type_node;
      break;
    case RID_DOUBLE:
      type = double_type_node;
      break;
    CASE_RID_FLOATN_NX:
      type = FLOATN_NX_TYPE_NODE (token->keyword - RID_FLOATN_NX_FIRST);
      if (type == NULL_TREE)
	error ("%<_Float%d%s%> is not supported on this target",
	       floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].n,
	       floatn_nx_types[token->keyword - RID_FLOATN_NX_FIRST].extended
	       ? "x" : "");
      break;
    case RID_VOID:
      type = void_type_node;
      break;

    case RID_AUTO:
      maybe_warn_cpp0x (CPP0X_AUTO);
      if (parser->auto_is_implicit_function_template_parm_p)
	{
	  /* The 'auto' might be the placeholder return type for a function decl
	     with trailing return type.  */
	  bool have_trailing_return_fn_decl = false;

	  cp_parser_parse_tentatively (parser);
	  cp_lexer_consume_token (parser->lexer);
	  while (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ)
		 && cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
		 && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
		 && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
	    {
	      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
		{
		  cp_lexer_consume_token (parser->lexer);
		  cp_parser_skip_to_closing_parenthesis (parser,
							 /*recovering*/false,
							 /*or_comma*/false,
							 /*consume_paren*/true);
		  continue;
		}

	      if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
		{
		  have_trailing_return_fn_decl = true;
		  break;
		}

	      cp_lexer_consume_token (parser->lexer);
	    }
	  cp_parser_abort_tentative_parse (parser);

	  if (have_trailing_return_fn_decl)
	    {
	      type = make_auto ();
	      break;
	    }

	  if (cxx_dialect >= cxx14)
	    {
	      type = synthesize_implicit_template_parm (parser, NULL_TREE);
	      type = TREE_TYPE (type);
	    }
	  else
	    type = error_mark_node;

	  if (current_class_type && LAMBDA_TYPE_P (current_class_type))
	    {
	      if (cxx_dialect < cxx14)
		error_at (token->location,
			 "use of %<auto%> in lambda parameter declaration "
			 "only available with "
			 "%<-std=c++14%> or %<-std=gnu++14%>");
	    }
	  else if (cxx_dialect < cxx14)
	    error_at (token->location,
		     "use of %<auto%> in parameter declaration "
		     "only available with "
		     "%<-std=c++14%> or %<-std=gnu++14%>");
	  else if (!flag_concepts)
	    pedwarn (token->location, 0,
		     "use of %<auto%> in parameter declaration "
		     "only available with %<-std=c++20%> or %<-fconcepts%>");
	}
      else
	type = make_auto ();
      break;

    case RID_DECLTYPE:
      /* Since DR 743, decltype can either be a simple-type-specifier by
	 itself or begin a nested-name-specifier.  Parsing it will replace
	 it with a CPP_DECLTYPE, so just rewind and let the CPP_DECLTYPE
	 handling below decide what to do.  */
      cp_parser_decltype (parser);
      cp_lexer_set_token_position (parser->lexer, token);
      break;

    case RID_TYPEOF:
      /* Consume the `typeof' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Parse the operand to `typeof'.  */
      type = cp_parser_sizeof_operand (parser, RID_TYPEOF);
      /* If it is not already a TYPE, take its type.  */
      if (!TYPE_P (type))
	type = finish_typeof (type);

      if (decl_specs)
	cp_parser_set_decl_spec_type (decl_specs, type,
				      token,
				      /*type_definition_p=*/false);

      return type;

#define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
    case RID_##CODE:
#include "cp-trait.def"
#undef DEFTRAIT_TYPE
      type = cp_parser_trait (parser, token->keyword);
      if (decl_specs)
	cp_parser_set_decl_spec_type (decl_specs, type,
				      token,
				      /*type_definition_p=*/false);

      return type;

    default:
      break;
    }

  /* If token is an already-parsed decltype not followed by ::,
     it's a simple-type-specifier.  */
  if (token->type == CPP_DECLTYPE
      && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
    {
      type = saved_checks_value (token->u.tree_check_value);
      if (decl_specs)
	{
	  cp_parser_set_decl_spec_type (decl_specs, type,
					token,
					/*type_definition_p=*/false);
	  /* Remember that we are handling a decltype in order to
	     implement the resolution of DR 1510 when the argument
	     isn't instantiation dependent.  */
	  decl_specs->decltype_p = true;
	}
      cp_lexer_consume_token (parser->lexer);
      return type;
    }

  /* If the type-specifier was for a built-in type, we're done.  */
  if (type)
    {
      /* Record the type.  */
      if (decl_specs
	  && (token->keyword != RID_SIGNED
	      && token->keyword != RID_UNSIGNED
	      && token->keyword != RID_SHORT
	      && token->keyword != RID_LONG))
	cp_parser_set_decl_spec_type (decl_specs,
				      type,
				      token,
				      /*type_definition_p=*/false);
      if (decl_specs)
	decl_specs->any_specifiers_p = true;

      /* Consume the token.  */
      cp_lexer_consume_token (parser->lexer);

      if (type == error_mark_node)
	return error_mark_node;

      /* There is no valid C++ program where a non-template type is
	 followed by a "<".  That usually indicates that the user thought
	 that the type was a template.  */
      cp_parser_check_for_invalid_template_id (parser, type, none_type,
					       token->location);

      return TYPE_NAME (type);
    }

  /* The type-specifier must be a user-defined type.  */
  if (!(flags & CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES))
    {
      bool qualified_p;
      bool global_p;
      const bool typename_p = (cxx_dialect >= cxx20
			       && (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL));

      /* Don't gobble tokens or issue error messages if this is an
	 optional type-specifier.  */
      if (flags & CP_PARSER_FLAGS_OPTIONAL)
	cp_parser_parse_tentatively (parser);

      /* Remember current tentative parsing state -- if we know we need
	 a type, we can give better diagnostics here.  */
      bool tent = cp_parser_parsing_tentatively (parser);

      token = cp_lexer_peek_token (parser->lexer);

      /* Look for the optional `::' operator.  */
      global_p
	= (cp_parser_global_scope_opt (parser,
				       /*current_scope_valid_p=*/false)
	   != NULL_TREE);
      /* Look for the nested-name specifier.  */
      qualified_p
	= (cp_parser_nested_name_specifier_opt (parser,
						/*typename_keyword_p=*/false,
						/*check_dependency_p=*/true,
						/*type_p=*/false,
						/*is_declaration=*/false)
	   != NULL_TREE);
      /* If we have seen a nested-name-specifier, and the next token
	 is `template', then we are using the template-id production.  */
      if (parser->scope
	  && cp_parser_optional_template_keyword (parser))
	{
	  /* Look for the template-id.  */
	  type = cp_parser_template_id (parser,
					/*template_keyword_p=*/true,
					/*check_dependency_p=*/true,
					none_type,
					/*is_declaration=*/false);
	  /* If the template-id did not name a type, we are out of
	     luck.  */
	  if (TREE_CODE (type) != TYPE_DECL)
	    {
	      /* ...unless we pretend we have seen 'typename'.  */
	      if (typename_p)
		type = cp_parser_make_typename_type (parser, type,
						     token->location);
	      else
		{
		  cp_parser_error (parser, "expected template-id for type");
		  type = error_mark_node;
		}
	    }
	}
      /* DR 1812: A < following a qualified-id in a typename-specifier
	 could safely be assumed to begin a template argument list, so
	 the template keyword should be optional.  */
      else if (parser->scope
	       && qualified_p
	       && typename_p
	       && cp_lexer_next_token_is (parser->lexer, CPP_TEMPLATE_ID))
	{
	  cp_parser_parse_tentatively (parser);

	  type = cp_parser_template_id (parser,
					/*template_keyword_p=*/true,
					/*check_dependency_p=*/true,
					none_type,
					/*is_declaration=*/false);
	  /* This is handled below, so back off.  */
	  if (type && concept_check_p (type))
	    cp_parser_simulate_error (parser);

	  if (!cp_parser_parse_definitely (parser))
	    type = NULL_TREE;
	  else if (TREE_CODE (type) == TEMPLATE_ID_EXPR)
	    type = make_typename_type (parser->scope, type, typename_type,
				       /*complain=*/tf_error);
	  else if (TREE_CODE (type) != TYPE_DECL)
	    type = NULL_TREE;
	}

      /* Otherwise, look for a type-name.  */
      if (!type)
	{
	  if (cxx_dialect >= cxx17)
	    cp_parser_parse_tentatively (parser);

	  type = cp_parser_type_name (parser, (qualified_p && typename_p));

	  if (cxx_dialect >= cxx17 && !cp_parser_parse_definitely (parser))
	    type = NULL_TREE;
	}

      if (!type && flag_concepts && decl_specs)
	{
	  /* Try for a type-constraint with template arguments.  We check
	     decl_specs here to avoid trying this for a functional cast.  */

	  cp_parser_parse_tentatively (parser);

	  type = cp_parser_template_id (parser,
					/*template_keyword_p=*/false,
					/*check_dependency_p=*/true,
					none_type,
					/*is_declaration=*/false);
	  if (type && concept_check_p (type))
	    {
	      location_t loc = EXPR_LOCATION (type);
	      type = cp_parser_placeholder_type_specifier (parser, loc,
							   type, tent);
	      if (tent && type == error_mark_node)
		/* Perhaps it's a concept-check expression.  */
		cp_parser_simulate_error (parser);
	    }
	  else
	    cp_parser_simulate_error (parser);

	  if (!cp_parser_parse_definitely (parser))
	    type = NULL_TREE;
	}

      if (!type && cxx_dialect >= cxx17)
	{
	  /* Try class template argument deduction or type-constraint without
	     template arguments.  */
	  tree name = cp_parser_identifier (parser);
	  if (name && TREE_CODE (name) == IDENTIFIER_NODE
	      && parser->scope != error_mark_node)
	    {
	      location_t loc
		= cp_lexer_previous_token (parser->lexer)->location;
	      tree tmpl = cp_parser_lookup_name (parser, name,
						 none_type,
						 /*is_template=*/false,
						 /*is_namespace=*/false,
						 /*check_dependency=*/true,
						 /*ambiguous_decls=*/NULL,
						 token->location);
	      if (tmpl && tmpl != error_mark_node
		  && ctad_template_p (tmpl))
		type = make_template_placeholder (tmpl);
	      else if (flag_concepts && tmpl && concept_definition_p (tmpl))
		type = cp_parser_placeholder_type_specifier (parser, loc,
							     tmpl, tent);
	      else
		{
		  type = error_mark_node;
		  if (!cp_parser_simulate_error (parser))
		    cp_parser_name_lookup_error (parser, name, tmpl,
						 NLE_TYPE, token->location);
		}
	    }
	  else
	    type = error_mark_node;
	}

      /* If it didn't work out, we don't have a TYPE.  */
      if ((flags & CP_PARSER_FLAGS_OPTIONAL)
	  && !cp_parser_parse_definitely (parser))
	type = NULL_TREE;

      /* Keep track of all name-lookups performed in class scopes.  */
      if (type
	  && !global_p
	  && !qualified_p
	  && TREE_CODE (type) == TYPE_DECL
	  && identifier_p (DECL_NAME (type)))
	maybe_note_name_used_in_class (DECL_NAME (type), type);

      if (type && decl_specs)
	cp_parser_set_decl_spec_type (decl_specs, type,
				      token,
				      /*type_definition_p=*/false);
    }

  /* If we didn't get a type-name, issue an error message.  */
  if (!type && !(flags & CP_PARSER_FLAGS_OPTIONAL))
    {
      cp_parser_error (parser, "expected type-name");
      return error_mark_node;
    }

  if (type && type != error_mark_node)
    {
      /* See if TYPE is an Objective-C type, and if so, parse and
	 accept any protocol references following it.  Do this before
	 the cp_parser_check_for_invalid_template_id() call, because
	 Objective-C types can be followed by '<...>' which would
	 enclose protocol names rather than template arguments, and so
	 everything is fine.  */
      if (c_dialect_objc () && !parser->scope
	  && (objc_is_id (type) || objc_is_class_name (type)))
	{
	  tree protos = cp_parser_objc_protocol_refs_opt (parser);
	  tree qual_type = objc_get_protocol_qualified_type (type, protos);

	  /* Clobber the "unqualified" type previously entered into
	     DECL_SPECS with the new, improved protocol-qualified version.  */
	  if (decl_specs)
	    decl_specs->type = qual_type;

	  return qual_type;
	}

      /* There is no valid C++ program where a non-template type is
	 followed by a "<".  That usually indicates that the user
	 thought that the type was a template.  */
      cp_parser_check_for_invalid_template_id (parser, type,
					       none_type,
					       token->location);
    }

  return type;
}

/* Parse the remainder of a placholder-type-specifier.

   placeholder-type-specifier:
     type-constraint_opt auto
     type-constraint_opt decltype(auto)

  The raw form of the constraint is parsed in cp_parser_simple_type_specifier
  and passed as TMPL. This function converts TMPL to an actual type-constraint,
  parses the placeholder type, and performs some contextual syntactic analysis.

  LOC provides the location of the template name.

  TENTATIVE is true if the type-specifier parsing is tentative; in that case,
  don't give an error if TMPL isn't a valid type-constraint, as the template-id
  might actually be a concept-check,

  Note that the Concepts TS allows the auto or decltype(auto) to be
  omitted in a constrained-type-specifier.  */

static tree
cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
				      tree tmpl, bool tentative)
{
  if (tmpl == error_mark_node)
    return error_mark_node;

  tree orig_tmpl = tmpl;

  /* Get the arguments as written for subsequent analysis.  */
  tree args = NULL_TREE;
  if (TREE_CODE (tmpl) == TEMPLATE_ID_EXPR)
    {
      args = TREE_OPERAND (tmpl, 1);
      tmpl = TREE_OPERAND (tmpl, 0);
    }
  else
    /* A concept-name with no arguments can't be an expression.  */
    tentative = false;

  tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error;

  /* Get the concept and prototype parameter for the constraint.  */
  tree_pair info = finish_type_constraints (tmpl, args, complain);
  tree con = info.first;
  tree proto = info.second;
  if (con == error_mark_node)
    return error_mark_node;

  /* As per the standard, require auto or decltype(auto), except in some
     cases (template parameter lists, -fconcepts-ts enabled).  */
  cp_token *placeholder = NULL, *close_paren = NULL;
  if (cxx_dialect >= cxx20)
    {
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
	placeholder = cp_lexer_consume_token (parser->lexer);
      else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DECLTYPE))
	{
	  placeholder = cp_lexer_consume_token (parser->lexer);
	  matching_parens parens;
	  parens.require_open (parser);
	  cp_parser_require_keyword (parser, RID_AUTO, RT_AUTO);
	  close_paren = parens.require_close (parser);
	}
    }

  /* A type constraint constrains a contextually determined type or type
     parameter pack. However, the Concepts TS does allow concepts
     to introduce non-type and template template parameters.  */
  if (TREE_CODE (proto) != TYPE_DECL)
    {
      if (!flag_concepts_ts
	  || !processing_template_parmlist)
	{
	  if (!tentative)
	    {
	      error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
	      inform (DECL_SOURCE_LOCATION (con), "concept defined here");
	    }
	  return error_mark_node;
	}
    }

  /* In a template parameter list, a type-parameter can be introduced
     by type-constraints alone.  */
  if (processing_template_parmlist && !placeholder)
    {
      /* In a default argument we may not be creating new parameters.  */
      if (parser->local_variables_forbidden_p & LOCAL_VARS_FORBIDDEN)
	{
	  /* If this assert turns out to be false, do error() instead.  */
	  gcc_assert (tentative);
	  return error_mark_node;
	}
      return build_constrained_parameter (con, proto, args);
    }

  /* Diagnose issues placeholder issues.  */
  if (!flag_concepts_ts
      && !parser->in_result_type_constraint_p
      && !placeholder)
    {
      if (tentative)
	/* Perhaps it's a concept-check expression (c++/91073).  */
	return error_mark_node;

      tree id = build_nt (TEMPLATE_ID_EXPR, tmpl, args);
      tree expr = DECL_P (orig_tmpl) ? DECL_NAME (con) : id;
      error_at (input_location,
		"expected %<auto%> or %<decltype(auto)%> after %qE", expr);
      /* Fall through. This is an error of omission.  */
    }
  else if (parser->in_result_type_constraint_p && placeholder)
    {
      /* A trailing return type only allows type-constraints.  */
      error_at (input_location,
		"unexpected placeholder in constrained result type");
    }

  /* In a parameter-declaration-clause, a placeholder-type-specifier
     results in an invented template parameter.  */
  if (parser->auto_is_implicit_function_template_parm_p)
    {
      if (close_paren)
	{
	  location_t loc = make_location (placeholder->location,
					  placeholder->location,
					  close_paren->location);
	  error_at (loc, "cannot declare a parameter with %<decltype(auto)%>");
	  return error_mark_node;
	}
      tree parm = build_constrained_parameter (con, proto, args);
      return synthesize_implicit_template_parm (parser, parm);
    }

  /* Determine if the type should be deduced using template argument
     deduction or decltype deduction. Note that the latter is always
     used for type-constraints in trailing return types.  */
  bool decltype_p = placeholder
    ? placeholder->keyword == RID_DECLTYPE
    : parser->in_result_type_constraint_p;

  /* Otherwise, this is the type of a variable or return type.  */
  if (decltype_p)
    return make_constrained_decltype_auto (con, args);
  else
    return make_constrained_auto (con, args);
}

/* Parse a type-name.

   type-name:
     class-name
     enum-name
     typedef-name
     simple-template-id [in c++0x]

   enum-name:
     identifier

   typedef-name:
     identifier

  Concepts:

   type-name:
     concept-name
     partial-concept-id

   concept-name:
     identifier

   Returns a TYPE_DECL for the type.  */

static tree
cp_parser_type_name (cp_parser* parser, bool typename_keyword_p)
{
  tree type_decl;

  /* We can't know yet whether it is a class-name or not.  */
  cp_parser_parse_tentatively (parser);
  /* Try a class-name.  */
  type_decl = cp_parser_class_name (parser,
				    typename_keyword_p,
				    /*template_keyword_p=*/false,
				    none_type,
				    /*check_dependency_p=*/true,
				    /*class_head_p=*/false,
				    /*is_declaration=*/false);
  /* If it's not a class-name, keep looking.  */
  if (!cp_parser_parse_definitely (parser))
    {
      if (cxx_dialect < cxx11)
	/* It must be a typedef-name or an enum-name.  */
	return cp_parser_nonclass_name (parser);

      cp_parser_parse_tentatively (parser);
      /* It is either a simple-template-id representing an
	 instantiation of an alias template...  */
      type_decl = cp_parser_template_id (parser,
					 /*template_keyword_p=*/false,
					 /*check_dependency_p=*/true,
					 none_type,
					 /*is_declaration=*/false);
      /* Note that this must be an instantiation of an alias template
	 because [temp.names]/6 says:

	     A template-id that names an alias template specialization
	     is a type-name.

	 Whereas [temp.names]/7 says:

	     A simple-template-id that names a class template
	     specialization is a class-name.

         With concepts, this could also be a partial-concept-id that
         declares a non-type template parameter. */
      if (type_decl != NULL_TREE
	  && TREE_CODE (type_decl) == TYPE_DECL
	  && TYPE_DECL_ALIAS_P (type_decl))
	gcc_assert (DECL_TEMPLATE_INSTANTIATION (type_decl));
      else
	cp_parser_simulate_error (parser);

      if (!cp_parser_parse_definitely (parser))
	/* ... Or a typedef-name or an enum-name.  */
	return cp_parser_nonclass_name (parser);
    }

  return type_decl;
}

/* Parse a non-class type-name, that is, either an enum-name, a typedef-name,
   or a concept-name.

   enum-name:
     identifier

   typedef-name:
     identifier

   concept-name:
     identifier

   Returns a TYPE_DECL for the type.  */

static tree
cp_parser_nonclass_name (cp_parser* parser)
{
  tree type_decl;
  tree identifier;

  cp_token *token = cp_lexer_peek_token (parser->lexer);
  identifier = cp_parser_identifier (parser);
  if (identifier == error_mark_node)
    return error_mark_node;

  /* Look up the type-name.  */
  type_decl = cp_parser_lookup_name_simple (parser, identifier, token->location);

  type_decl = strip_using_decl (type_decl);

  if (TREE_CODE (type_decl) != TYPE_DECL
      && (objc_is_id (identifier) || objc_is_class_name (identifier)))
    {
      /* See if this is an Objective-C type.  */
      tree protos = cp_parser_objc_protocol_refs_opt (parser);
      tree type = objc_get_protocol_qualified_type (identifier, protos);
      if (type)
	type_decl = TYPE_NAME (type);
    }

  /* Issue an error if we did not find a type-name.  */
  if (TREE_CODE (type_decl) != TYPE_DECL
      /* In Objective-C, we have the complication that class names are
	 normally type names and start declarations (eg, the
	 "NSObject" in "NSObject *object;"), but can be used in an
	 Objective-C 2.0 dot-syntax (as in "NSObject.version") which
	 is an expression.  So, a classname followed by a dot is not a
	 valid type-name.  */
      || (objc_is_class_name (TREE_TYPE (type_decl))
	  && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT))
    {
      if (!cp_parser_simulate_error (parser))
	cp_parser_name_lookup_error (parser, identifier, type_decl,
				     NLE_TYPE, token->location);
      return error_mark_node;
    }
  /* Remember that the name was used in the definition of the
     current class so that we can check later to see if the
     meaning would have been different after the class was
     entirely defined.  */
  else if (type_decl != error_mark_node
	   && !parser->scope)
    maybe_note_name_used_in_class (identifier, type_decl);

  return type_decl;
}

/* Parse an elaborated-type-specifier.  Note that the grammar given
   here incorporates the resolution to DR68.

   elaborated-type-specifier:
     class-key :: [opt] nested-name-specifier [opt] identifier
     class-key :: [opt] nested-name-specifier [opt] template [opt] template-id
     enum-key :: [opt] nested-name-specifier [opt] identifier
     typename :: [opt] nested-name-specifier identifier
     typename :: [opt] nested-name-specifier template [opt]
       template-id

   GNU extension:

   elaborated-type-specifier:
     class-key attributes :: [opt] nested-name-specifier [opt] identifier
     class-key attributes :: [opt] nested-name-specifier [opt]
	       template [opt] template-id
     enum attributes :: [opt] nested-name-specifier [opt] identifier

   If IS_FRIEND is TRUE, then this elaborated-type-specifier is being
   declared `friend'.  If IS_DECLARATION is TRUE, then this
   elaborated-type-specifier appears in a decl-specifiers-seq, i.e.,
   something is being declared.

   Returns the TYPE specified.  */

static tree
cp_parser_elaborated_type_specifier (cp_parser* parser,
				     bool is_friend,
				     bool is_declaration)
{
  enum tag_types tag_type;
  tree identifier;
  tree type = NULL_TREE;
  tree attributes = NULL_TREE;
  tree globalscope;
  cp_token *token = NULL;

  /* For class and enum types the location of the class-key or enum-key.  */
  location_t key_loc = cp_lexer_peek_token (parser->lexer)->location;
  /* For a scoped enum, the 'class' or 'struct' keyword id.  */
  rid scoped_key = RID_MAX;

  /* See if we're looking at the `enum' keyword.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM))
    {
      /* Consume the `enum' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Remember that it's an enumeration type.  */
      tag_type = enum_type;
      /* Issue a warning if the `struct' or `class' key (for C++0x scoped
	 enums) is used here.  */
      cp_token *token = cp_lexer_peek_token (parser->lexer);
      if (cp_parser_is_keyword (token, scoped_key = RID_CLASS)
	  || cp_parser_is_keyword (token, scoped_key = RID_STRUCT))
	{
	  location_t loc = token->location;
	  gcc_rich_location richloc (loc);
	  richloc.add_range (input_location);
	  richloc.add_fixit_remove ();
	  pedwarn (&richloc, 0, "elaborated-type-specifier for "
		   "a scoped enum must not use the %qD keyword",
		   token->u.value);
	  /* Consume the `struct' or `class' and parse it anyway.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Create a combined location for the whole scoped-enum-key.  */
	  key_loc = make_location (key_loc, key_loc, loc);
	}
      else
	scoped_key = RID_MAX;

      /* Parse the attributes.  */
      attributes = cp_parser_attributes_opt (parser);
    }
  /* Or, it might be `typename'.  */
  else if (cp_lexer_next_token_is_keyword (parser->lexer,
					   RID_TYPENAME))
    {
      /* Consume the `typename' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Remember that it's a `typename' type.  */
      tag_type = typename_type;
    }
  /* Otherwise it must be a class-key.  */
  else
    {
      key_loc = cp_lexer_peek_token (parser->lexer)->location;
      tag_type = cp_parser_class_key (parser);
      if (tag_type == none_type)
	return error_mark_node;
      /* Parse the attributes.  */
      attributes = cp_parser_attributes_opt (parser);
    }

  /* Look for the `::' operator.  */
  globalscope =  cp_parser_global_scope_opt (parser,
					     /*current_scope_valid_p=*/false);
  /* Look for the nested-name-specifier.  */
  tree nested_name_specifier;
  if (tag_type == typename_type && !globalscope)
    {
      nested_name_specifier
	= cp_parser_nested_name_specifier (parser,
					   /*typename_keyword_p=*/true,
					   /*check_dependency_p=*/true,
					   /*type_p=*/true,
					   is_declaration);
      if (!nested_name_specifier)
	return error_mark_node;
    }
  else
    /* Even though `typename' is not present, the proposed resolution
       to Core Issue 180 says that in `class A<T>::B', `B' should be
       considered a type-name, even if `A<T>' is dependent.  */
    nested_name_specifier
      = cp_parser_nested_name_specifier_opt (parser,
					     /*typename_keyword_p=*/true,
					     /*check_dependency_p=*/true,
					     /*type_p=*/true,
					     is_declaration);
 /* For everything but enumeration types, consider a template-id.
    For an enumeration type, consider only a plain identifier.  */
  if (tag_type != enum_type)
    {
      bool template_p = false;
      tree decl;

      /* Allow the `template' keyword.  */
      template_p = cp_parser_optional_template_keyword (parser);
      /* If we didn't see `template', we don't know if there's a
	 template-id or not.  */
      if (!template_p)
	cp_parser_parse_tentatively (parser);
      /* The `template' keyword must follow a nested-name-specifier.  */
      else if (!nested_name_specifier && !globalscope)
	{
	  cp_parser_error (parser, "%<template%> must follow a nested-"
			   "name-specifier");
	  return error_mark_node;
	}

      /* Parse the template-id.  */
      token = cp_lexer_peek_token (parser->lexer);
      decl = cp_parser_template_id (parser, template_p,
				    /*check_dependency_p=*/true,
				    tag_type,
				    is_declaration);
      /* If we didn't find a template-id, look for an ordinary
	 identifier.  */
      if (!template_p && !cp_parser_parse_definitely (parser))
	;
      /* We can get here when cp_parser_template_id, called by
	 cp_parser_class_name with tag_type == none_type, succeeds
	 and caches a BASELINK.  Then, when called again here,
	 instead of failing and returning an error_mark_node
	 returns it (see template/typename17.C in C++11).
	 ??? Could we diagnose this earlier?  */
      else if (tag_type == typename_type && BASELINK_P (decl))
	{
	  cp_parser_diagnose_invalid_type_name (parser, decl, token->location);
	  type = error_mark_node;
	}
      /* If DECL is a TEMPLATE_ID_EXPR, and the `typename' keyword is
	 in effect, then we must assume that, upon instantiation, the
	 template will correspond to a class.  */
      else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
	       && tag_type == typename_type)
	type = make_typename_type (parser->scope, decl,
				   typename_type,
				   /*complain=*/tf_error);
      /* If the `typename' keyword is in effect and DECL is not a type
	 decl, then type is non existent.   */
      else if (tag_type == typename_type && TREE_CODE (decl) != TYPE_DECL)
        ;
      else if (TREE_CODE (decl) == TYPE_DECL)
	{
	  type = check_elaborated_type_specifier (tag_type, decl,
						  /*allow_template_p=*/true);

	  /* If the next token is a semicolon, this must be a specialization,
	     instantiation, or friend declaration.  Check the scope while we
	     still know whether or not we had a nested-name-specifier.  */
	  if (type != error_mark_node
	      && !nested_name_specifier && !is_friend
	      && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	    check_unqualified_spec_or_inst (type, token->location);
	}
      else if (decl == error_mark_node)
	type = error_mark_node;
    }

  if (!type)
    {
      token = cp_lexer_peek_token (parser->lexer);
      identifier = cp_parser_identifier (parser);

      if (identifier == error_mark_node)
	{
	  parser->scope = NULL_TREE;
	  return error_mark_node;
	}

      /* For a `typename', we needn't call xref_tag.  */
      if (tag_type == typename_type
	  && TREE_CODE (parser->scope) != NAMESPACE_DECL)
	return cp_parser_make_typename_type (parser, identifier,
					     token->location);

      /* Template parameter lists apply only if we are not within a
	 function parameter list.  */
      bool template_parm_lists_apply
	  = parser->num_template_parameter_lists;
      if (template_parm_lists_apply)
	for (cp_binding_level *s = current_binding_level;
	     s && s->kind != sk_template_parms;
	     s = s->level_chain)
	  if (s->kind == sk_function_parms)
	    template_parm_lists_apply = false;

      /* Look up a qualified name in the usual way.  */
      if (parser->scope)
	{
	  tree decl;
	  tree ambiguous_decls;

	  decl = cp_parser_lookup_name (parser, identifier,
					tag_type,
					/*is_template=*/false,
					/*is_namespace=*/false,
					/*check_dependency=*/true,
					&ambiguous_decls,
					token->location);

	  /* If the lookup was ambiguous, an error will already have been
	     issued.  */
	  if (ambiguous_decls)
	    return error_mark_node;

	  /* If we are parsing friend declaration, DECL may be a
	     TEMPLATE_DECL tree node here.  However, we need to check
	     whether this TEMPLATE_DECL results in valid code.  Consider
	     the following example:

	       namespace N {
		 template <class T> class C {};
	       }
	       class X {
		 template <class T> friend class N::C; // #1, valid code
	       };
	       template <class T> class Y {
		 friend class N::C;		       // #2, invalid code
	       };

	     For both case #1 and #2, we arrive at a TEMPLATE_DECL after
	     name lookup of `N::C'.  We see that friend declaration must
	     be template for the code to be valid.  Note that
	     processing_template_decl does not work here since it is
	     always 1 for the above two cases.  */

	  decl = (cp_parser_maybe_treat_template_as_class
		  (decl, /*tag_name_p=*/is_friend
			 && template_parm_lists_apply));

	  if (TREE_CODE (decl) != TYPE_DECL)
	    {
	      cp_parser_diagnose_invalid_type_name (parser,
						    identifier,
						    token->location);
	      return error_mark_node;
	    }

	  if (TREE_CODE (TREE_TYPE (decl)) != TYPENAME_TYPE)
            {
              bool allow_template = (template_parm_lists_apply
		                     || DECL_SELF_REFERENCE_P (decl));
              type = check_elaborated_type_specifier (tag_type, decl,
                                                      allow_template);

              if (type == error_mark_node)
                return error_mark_node;
            }

          /* Forward declarations of nested types, such as

               class C1::C2;
               class C1::C2::C3;

             are invalid unless all components preceding the final '::'
             are complete.  If all enclosing types are complete, these
             declarations become merely pointless.

             Invalid forward declarations of nested types are errors
             caught elsewhere in parsing.  Those that are pointless arrive
             here.  */

          if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
	      && !is_friend && is_declaration
	      && !processing_explicit_instantiation)
            warning (0, "declaration %qD does not declare anything", decl);

	  type = TREE_TYPE (decl);
	}
      else
	{
	  /* An elaborated-type-specifier sometimes introduces a new type and
	     sometimes names an existing type.  Normally, the rule is that it
	     introduces a new type only if there is not an existing type of
	     the same name already in scope.  For example, given:

	       struct S {};
	       void f() { struct S s; }

	     the `struct S' in the body of `f' is the same `struct S' as in
	     the global scope; the existing definition is used.  However, if
	     there were no global declaration, this would introduce a new
	     local class named `S'.

	     An exception to this rule applies to the following code:

	       namespace N { struct S; }

	     Here, the elaborated-type-specifier names a new type
	     unconditionally; even if there is already an `S' in the
	     containing scope this declaration names a new type.
	     This exception only applies if the elaborated-type-specifier
	     forms the complete declaration:

	       [class.name]

	       A declaration consisting solely of `class-key identifier ;' is
	       either a redeclaration of the name in the current scope or a
	       forward declaration of the identifier as a class name.  It
	       introduces the name into the current scope.

	     We are in this situation precisely when the next token is a `;'.

	     An exception to the exception is that a `friend' declaration does
	     *not* name a new type; i.e., given:

	       struct S { friend struct T; };

	     `T' is not a new type in the scope of `S'.

	     Also, `new struct S' or `sizeof (struct S)' never results in the
	     definition of a new type; a new type can only be declared in a
	     declaration context.  */

	  TAG_how how;

	  if (is_friend)
	    /* Friends have special name lookup rules.  */
	    how = TAG_how::HIDDEN_FRIEND;
	  else if (is_declaration
		   && cp_lexer_next_token_is (parser->lexer,
					      CPP_SEMICOLON))
	    /* This is a `class-key identifier ;' */
	    how = TAG_how::CURRENT_ONLY;
	  else
	    how = TAG_how::GLOBAL;

	  bool template_p =
	    (template_parm_lists_apply
	     && (cp_parser_next_token_starts_class_definition_p (parser)
		 || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)));
	  /* An unqualified name was used to reference this type, so
	     there were no qualifying templates.  */
	  if (template_parm_lists_apply
	      && !cp_parser_check_template_parameters (parser,
						       /*num_templates=*/0,
						       /*template_id*/false,
						       token->location,
						       /*declarator=*/NULL))
	    return error_mark_node;

	  type = xref_tag (tag_type, identifier, how, template_p);
	}
    }

  if (type == error_mark_node)
    return error_mark_node;

  /* Allow attributes on forward declarations of classes.  */
  if (attributes)
    {
      if (TREE_CODE (type) == TYPENAME_TYPE)
	warning (OPT_Wattributes,
		 "attributes ignored on uninstantiated type");
      else if (tag_type != enum_type
	       && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM
	       && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
	       && ! processing_explicit_instantiation)
	warning (OPT_Wattributes,
		 "attributes ignored on template instantiation");
      else if (is_friend && cxx11_attribute_p (attributes))
	{
	  if (warning (OPT_Wattributes, "attribute ignored"))
	    inform (input_location, "an attribute that appertains to a friend "
		    "declaration that is not a definition is ignored");
	}
      else if (is_declaration && cp_parser_declares_only_class_p (parser))
	cplus_decl_attributes (&type, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
      else
	warning (OPT_Wattributes,
		 "attributes ignored on elaborated-type-specifier that is "
		 "not a forward declaration");
    }

  if (tag_type == enum_type)
    cp_parser_maybe_warn_enum_key (parser, key_loc, type, scoped_key);
  else
    {
      /* Diagnose class/struct/union mismatches.  IS_DECLARATION is false
	 for alias definition.  */
      bool decl_class = (is_declaration
			 && cp_parser_declares_only_class_p (parser));
      cp_parser_check_class_key (parser, key_loc, tag_type, type, false,
				 decl_class);

      /* Indicate whether this class was declared as a `class' or as a
	 `struct'.  */
      if (CLASS_TYPE_P (type) && !currently_open_class (type))
	CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type);
    }

  /* A "<" cannot follow an elaborated type specifier.  If that
     happens, the user was probably trying to form a template-id.  */
  cp_parser_check_for_invalid_template_id (parser, type, tag_type,
					   token->location);

  return type;
}

/* Parse an enum-specifier.

   enum-specifier:
     enum-head { enumerator-list [opt] }
     enum-head { enumerator-list , } [C++0x]

   enum-head:
     enum-key identifier [opt] enum-base [opt]
     enum-key nested-name-specifier identifier enum-base [opt]

   enum-key:
     enum
     enum class   [C++0x]
     enum struct  [C++0x]

   enum-base:   [C++0x]
     : type-specifier-seq

   opaque-enum-specifier:
     enum-key identifier enum-base [opt] ;

   GNU Extensions:
     enum-key attributes[opt] identifier [opt] enum-base [opt]
       { enumerator-list [opt] }attributes[opt]
     enum-key attributes[opt] identifier [opt] enum-base [opt]
       { enumerator-list, }attributes[opt] [C++0x]

   Returns an ENUM_TYPE representing the enumeration, or NULL_TREE
   if the token stream isn't an enum-specifier after all.  */

static tree
cp_parser_enum_specifier (cp_parser* parser)
{
  tree identifier;
  tree type = NULL_TREE;
  tree prev_scope;
  tree nested_name_specifier = NULL_TREE;
  tree attributes;
  bool scoped_enum_p = false;
  bool has_underlying_type = false;
  bool nested_being_defined = false;
  bool new_value_list = false;
  bool is_new_type = false;
  bool is_unnamed = false;
  tree underlying_type = NULL_TREE;
  cp_token *type_start_token = NULL;
  auto cleanup = make_temp_override (parser->colon_corrects_to_scope_p, false);

  /* Parse tentatively so that we can back up if we don't find a
     enum-specifier.  */
  cp_parser_parse_tentatively (parser);

  /* Caller guarantees that the current token is 'enum', an identifier
     possibly follows, and the token after that is an opening brace.
     If we don't have an identifier, fabricate an anonymous name for
     the enumeration being defined.  */
  cp_lexer_consume_token (parser->lexer);

  /* Parse the "class" or "struct", which indicates a scoped
     enumeration type in C++0x.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_CLASS)
      || cp_lexer_next_token_is_keyword (parser->lexer, RID_STRUCT))
    {
      if (cxx_dialect < cxx11)
        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);

      /* Consume the `struct' or `class' token.  */
      cp_lexer_consume_token (parser->lexer);

      scoped_enum_p = true;
    }

  attributes = cp_parser_attributes_opt (parser);

  /* Clear the qualification.  */
  parser->scope = NULL_TREE;
  parser->qualifying_scope = NULL_TREE;
  parser->object_scope = NULL_TREE;

  /* Figure out in what scope the declaration is being placed.  */
  prev_scope = current_scope ();

  type_start_token = cp_lexer_peek_token (parser->lexer);

  push_deferring_access_checks (dk_no_check);
  nested_name_specifier
    = cp_parser_nested_name_specifier_opt (parser,
					   /*typename_keyword_p=*/true,
					   /*check_dependency_p=*/false,
					   /*type_p=*/false,
					   /*is_declaration=*/false);

  if (nested_name_specifier)
    {
      tree name;

      identifier = cp_parser_identifier (parser);
      name = cp_parser_lookup_name (parser, identifier,
				    enum_type,
				    /*is_template=*/false,
				    /*is_namespace=*/false,
				    /*check_dependency=*/true,
				    /*ambiguous_decls=*/NULL,
				    input_location);
      if (name && name != error_mark_node)
	{
	  type = TREE_TYPE (name);
	  if (TREE_CODE (type) == TYPENAME_TYPE)
	    {
	      /* Are template enums allowed in ISO? */
	      if (template_parm_scope_p ())
		pedwarn (type_start_token->location, OPT_Wpedantic,
			 "%qD is an enumeration template", name);
	      /* ignore a typename reference, for it will be solved by name
	         in start_enum.  */
	      type = NULL_TREE;
	    }
	}
      else if (nested_name_specifier == error_mark_node)
	/* We already issued an error.  */;
      else
	{
	  error_at (type_start_token->location,
		    "%qD does not name an enumeration in %qT",
		    identifier, nested_name_specifier);
	  nested_name_specifier = error_mark_node;
	}
    }
  else
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	identifier = cp_parser_identifier (parser);
      else
	{
	  identifier = make_anon_name ();
	  is_unnamed = true;
	  if (scoped_enum_p)
	    error_at (type_start_token->location,
		      "unnamed scoped enum is not allowed");
	}
    }
  pop_deferring_access_checks ();

  /* Check for the `:' that denotes a specified underlying type in C++0x.
     Note that a ':' could also indicate a bitfield width, however.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      cp_decl_specifier_seq type_specifiers;

      /* Consume the `:'.  */
      cp_lexer_consume_token (parser->lexer);

      auto tdf
	= make_temp_override (parser->type_definition_forbidden_message,
			      G_("types may not be defined in enum-base"));

      /* Parse the type-specifier-seq.  */
      cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
				    /*is_declaration=*/false,
				    /*is_trailing_return=*/false,
                                    &type_specifiers);

      /* At this point this is surely not elaborated type specifier.  */
      if (!cp_parser_parse_definitely (parser))
	return NULL_TREE;

      if (cxx_dialect < cxx11)
        maybe_warn_cpp0x (CPP0X_SCOPED_ENUMS);

      has_underlying_type = true;

      /* If that didn't work, stop.  */
      if (type_specifiers.type != error_mark_node)
        {
          underlying_type = grokdeclarator (NULL, &type_specifiers, TYPENAME,
                                            /*initialized=*/0, NULL);
          if (underlying_type == error_mark_node
	      || check_for_bare_parameter_packs (underlying_type))
            underlying_type = NULL_TREE;
        }
    }

  /* Look for the `{' but don't consume it yet.  */
  if (!cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      if (cxx_dialect < cxx11 || (!scoped_enum_p && !underlying_type))
	{
	  if (has_underlying_type)
	    cp_parser_commit_to_tentative_parse (parser);
	  cp_parser_error (parser, "expected %<{%>");
	  if (has_underlying_type)
	    return error_mark_node;
	}
      /* An opaque-enum-specifier must have a ';' here.  */
      if ((scoped_enum_p || underlying_type)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	{
	  if (has_underlying_type)
	    cp_parser_commit_to_tentative_parse (parser);
	  cp_parser_error (parser, "expected %<;%> or %<{%>");
	  if (has_underlying_type)
	    return error_mark_node;
	}
    }

  if (!has_underlying_type && !cp_parser_parse_definitely (parser))
    return NULL_TREE;

  if (nested_name_specifier)
    {
      if (CLASS_TYPE_P (nested_name_specifier))
	{
	  nested_being_defined = TYPE_BEING_DEFINED (nested_name_specifier);
	  TYPE_BEING_DEFINED (nested_name_specifier) = 1;
	  push_scope (nested_name_specifier);
	}
      else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
	push_nested_namespace (nested_name_specifier);
    }

  /* Issue an error message if type-definitions are forbidden here.  */
  if (!cp_parser_check_type_definition (parser))
    type = error_mark_node;
  else
    /* Create the new type.  We do this before consuming the opening
       brace so the enum will be recorded as being on the line of its
       tag (or the 'enum' keyword, if there is no tag).  */
    type = start_enum (identifier, type, underlying_type,
		       attributes, scoped_enum_p, &is_new_type);

  /* If the next token is not '{' it is an opaque-enum-specifier or an
     elaborated-type-specifier.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      auto_timevar tv (TV_PARSE_ENUM);

      if (nested_name_specifier
	  && nested_name_specifier != error_mark_node)
	{
	  /* The following catches invalid code such as:
	     enum class S<int>::E { A, B, C }; */
	  if (!processing_specialization
	      && CLASS_TYPE_P (nested_name_specifier)
	      && CLASSTYPE_USE_TEMPLATE (nested_name_specifier))
	    error_at (type_start_token->location, "cannot add an enumerator "
		      "list to a template instantiation");

	  if (TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
	    {
	      error_at (type_start_token->location,
			"%<%T::%E%> has not been declared",
			TYPE_CONTEXT (nested_name_specifier),
			nested_name_specifier);
	      type = error_mark_node;
	    }
	  else if (TREE_CODE (nested_name_specifier) != NAMESPACE_DECL
		   && !CLASS_TYPE_P (nested_name_specifier))
	    {
	      error_at (type_start_token->location, "nested name specifier "
			"%qT for enum declaration does not name a class "
			"or namespace", nested_name_specifier);
	      type = error_mark_node;
	    }
	  /* If that scope does not contain the scope in which the
	     class was originally declared, the program is invalid.  */
	  else if (prev_scope && !is_ancestor (prev_scope,
					       nested_name_specifier))
	    {
	      if (at_namespace_scope_p ())
		error_at (type_start_token->location,
			  "declaration of %qD in namespace %qD which does not "
			  "enclose %qD",
			  type, prev_scope, nested_name_specifier);
	      else
		error_at (type_start_token->location,
			  "declaration of %qD in %qD which does not "
			  "enclose %qD",
			  type, prev_scope, nested_name_specifier);
	      type = error_mark_node;
	    }
	  /* If that scope is the scope where the declaration is being placed
	     the program is invalid.  */
	  else if (CLASS_TYPE_P (nested_name_specifier)
		   && CLASS_TYPE_P (prev_scope)
		   && same_type_p (nested_name_specifier, prev_scope))
	    {
	      permerror (type_start_token->location,
			 "extra qualification not allowed");
	      nested_name_specifier = NULL_TREE;
	    }
	}

      if (scoped_enum_p)
	begin_scope (sk_scoped_enum, type);

      /* Consume the opening brace.  */
      matching_braces braces;
      braces.consume_open (parser);

      if (type == error_mark_node)
	; /* Nothing to add */
      else if (OPAQUE_ENUM_P (type)
	       || (cxx_dialect > cxx98 && processing_specialization))
	{
	  new_value_list = true;
	  SET_OPAQUE_ENUM_P (type, false);
	  DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
	}
      else
	{
	  error_at (type_start_token->location,
		    "multiple definition of %q#T", type);
	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
		  "previous definition here");
	  type = error_mark_node;
	}

      if (type == error_mark_node)
	cp_parser_skip_to_end_of_block_or_statement (parser);
      /* If the next token is not '}', then there are some enumerators.  */
      else if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
	{
	  if (is_unnamed && !scoped_enum_p
	      /* Don't warn for enum {} a; here.  */
	      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SEMICOLON))
	    pedwarn (type_start_token->location, OPT_Wpedantic,
		     "ISO C++ forbids empty unnamed enum");
	}
      else
	{
	  /* We've seen a '{' so we know we're in an enum-specifier.
	     Commit to any tentative parse to get syntax errors.  */
	  cp_parser_commit_to_tentative_parse (parser);
	  cp_parser_enumerator_list (parser, type);
	}

      /* Consume the final '}'.  */
      braces.require_close (parser);

      if (scoped_enum_p)
	finish_scope ();
    }
  else
    {
      /* If a ';' follows, then it is an opaque-enum-specifier
	and additional restrictions apply.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	{
	  if (is_unnamed)
	    error_at (type_start_token->location,
		      "opaque-enum-specifier without name");
	  else if (nested_name_specifier)
	    error_at (type_start_token->location,
		      "opaque-enum-specifier must use a simple identifier");
	}
    }

  /* Look for trailing attributes to apply to this enumeration, and
     apply them if appropriate.  */
  if (cp_parser_allow_gnu_extensions_p (parser))
    {
      tree trailing_attr = cp_parser_gnu_attributes_opt (parser);
      cplus_decl_attributes (&type,
			     trailing_attr,
			     (int) ATTR_FLAG_TYPE_IN_PLACE);
    }

  /* Finish up the enumeration.  */
  if (type != error_mark_node)
    {
      if (new_value_list)
	finish_enum_value_list (type);
      if (is_new_type)
	finish_enum (type);
    }

  if (nested_name_specifier)
    {
      if (CLASS_TYPE_P (nested_name_specifier))
	{
	  TYPE_BEING_DEFINED (nested_name_specifier) = nested_being_defined;
	  pop_scope (nested_name_specifier);
	}
      else if (TREE_CODE (nested_name_specifier) == NAMESPACE_DECL)
	pop_nested_namespace (nested_name_specifier);
    }
  return type;
}

/* Parse an enumerator-list.  The enumerators all have the indicated
   TYPE.

   enumerator-list:
     enumerator-definition
     enumerator-list , enumerator-definition  */

static void
cp_parser_enumerator_list (cp_parser* parser, tree type)
{
  while (true)
    {
      /* Parse an enumerator-definition.  */
      cp_parser_enumerator_definition (parser, type);

      /* If the next token is not a ',', we've reached the end of
	 the list.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Otherwise, consume the `,' and keep going.  */
      cp_lexer_consume_token (parser->lexer);
      /* If the next token is a `}', there is a trailing comma.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
	{
	  if (cxx_dialect < cxx11)
	    pedwarn (input_location, OPT_Wpedantic,
                     "comma at end of enumerator list");
	  break;
	}
    }
}

/* Parse an enumerator-definition.  The enumerator has the indicated
   TYPE.

   enumerator-definition:
     enumerator
     enumerator = constant-expression

   enumerator:
     identifier

   GNU Extensions:

   enumerator-definition:
     enumerator attributes [opt]
     enumerator attributes [opt] = constant-expression  */

static void
cp_parser_enumerator_definition (cp_parser* parser, tree type)
{
  tree identifier;
  tree value;
  location_t loc;

  /* Save the input location because we are interested in the location
     of the identifier and not the location of the explicit value.  */
  loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Look for the identifier.  */
  identifier = cp_parser_identifier (parser);
  if (identifier == error_mark_node)
    return;

  /* Parse any specified attributes.  */
  tree attrs = cp_parser_attributes_opt (parser);

  /* If the next token is an '=', then there is an explicit value.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
    {
      /* Consume the `=' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Parse the value.  */
      value = cp_parser_constant_expression (parser);
    }
  else
    value = NULL_TREE;

  /* If we are processing a template, make sure the initializer of the
     enumerator doesn't contain any bare template parameter pack.  */
  if (current_lambda_expr ())
    {
      /* In a lambda it should work, but doesn't currently.  */
      if (uses_parameter_packs (value))
	{
	  sorry ("unexpanded parameter pack in enumerator in lambda");
	  value = error_mark_node;
	}
    }
  else if (check_for_bare_parameter_packs (value))
    value = error_mark_node;

  /* Create the enumerator.  */
  build_enumerator (identifier, value, type, attrs, loc);
}

/* Parse a namespace-name.

   namespace-name:
     original-namespace-name
     namespace-alias

   Returns the NAMESPACE_DECL for the namespace.  */

static tree
cp_parser_namespace_name (cp_parser* parser)
{
  tree identifier;
  tree namespace_decl;

  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Get the name of the namespace.  */
  identifier = cp_parser_identifier (parser);
  if (identifier == error_mark_node)
    return error_mark_node;

  /* Look up the identifier in the currently active scope.  Look only
     for namespaces, due to:

       [basic.lookup.udir]

       When looking up a namespace-name in a using-directive or alias
       definition, only namespace names are considered.

     And:

       [basic.lookup.qual]

       During the lookup of a name preceding the :: scope resolution
       operator, object, function, and enumerator names are ignored.

     (Note that cp_parser_qualifying_entity only calls this
     function if the token after the name is the scope resolution
     operator.)  */
  namespace_decl = cp_parser_lookup_name (parser, identifier,
					  none_type,
					  /*is_template=*/false,
					  /*is_namespace=*/true,
					  /*check_dependency=*/true,
					  /*ambiguous_decls=*/NULL,
					  token->location);
  /* If it's not a namespace, issue an error.  */
  if (namespace_decl == error_mark_node
      || TREE_CODE (namespace_decl) != NAMESPACE_DECL)
    {
      if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
	{
	  auto_diagnostic_group d;
	  name_hint hint;
	  if (namespace_decl == error_mark_node
	      && parser->scope && TREE_CODE (parser->scope) == NAMESPACE_DECL)
	    hint = suggest_alternative_in_explicit_scope (token->location,
							  identifier,
							  parser->scope);
	  if (const char *suggestion = hint.suggestion ())
	    {
	      gcc_rich_location richloc (token->location);
	      richloc.add_fixit_replace (suggestion);
	      error_at (&richloc,
			"%qD is not a namespace-name; did you mean %qs?",
			identifier, suggestion);
	    }
	  else
	    error_at (token->location, "%qD is not a namespace-name",
		      identifier);
	}
      else
	cp_parser_error (parser, "expected namespace-name");
      namespace_decl = error_mark_node;
    }

  return namespace_decl;
}

/* Parse a namespace-definition.

   namespace-definition:
     named-namespace-definition
     unnamed-namespace-definition

   named-namespace-definition:
     original-namespace-definition
     extension-namespace-definition

   original-namespace-definition:
     namespace identifier { namespace-body }

   extension-namespace-definition:
     namespace original-namespace-name { namespace-body }

   unnamed-namespace-definition:
     namespace { namespace-body } */

static void
cp_parser_namespace_definition (cp_parser* parser)
{
  tree identifier;
  int nested_definition_count = 0;

  cp_ensure_no_omp_declare_simd (parser);
  cp_ensure_no_oacc_routine (parser);

  bool is_inline = cp_lexer_next_token_is_keyword (parser->lexer, RID_INLINE);
  const bool topmost_inline_p = is_inline;

  if (is_inline)
    {
      maybe_warn_cpp0x (CPP0X_INLINE_NAMESPACES);
      cp_lexer_consume_token (parser->lexer);
    }

  /* Look for the `namespace' keyword.  */
  cp_token* token
    = cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);

  /* Parse any specified attributes before the identifier.  */
  tree attribs = cp_parser_attributes_opt (parser);

  for (;;)
    {
      identifier = NULL_TREE;

      bool nested_inline_p = cp_lexer_next_token_is_keyword (parser->lexer,
							     RID_INLINE);
      if (nested_inline_p && nested_definition_count != 0)
	{
	  if (pedantic && cxx_dialect < cxx20)
	    pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		     OPT_Wc__20_extensions, "nested inline namespace "
		     "definitions only available with %<-std=c++20%> or "
		     "%<-std=gnu++20%>");
	  cp_lexer_consume_token (parser->lexer);
	}

      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  identifier = cp_parser_identifier (parser);

	  if (cp_next_tokens_can_be_std_attribute_p (parser))
	    pedwarn (input_location, OPT_Wpedantic,
		     "standard attributes on namespaces must precede "
		     "the namespace name");

	  /* Parse any attributes specified after the identifier.  */
	  attribs = attr_chainon (attribs, cp_parser_attributes_opt (parser));
	}

      if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
	{
	  /* Don't forget that the innermost namespace might have been
	     marked as inline.  Use |= because we cannot overwrite
	     IS_INLINE in case the outermost namespace is inline, but
	     there are no nested inlines.  */
	  is_inline |= nested_inline_p;
	  break;
	}

      if (!nested_definition_count && pedantic && cxx_dialect < cxx17)
        pedwarn (input_location, OPT_Wc__17_extensions,
		 "nested namespace definitions only available with "
		 "%<-std=c++17%> or %<-std=gnu++17%>");

      /* Nested namespace names can create new namespaces (unlike
	 other qualified-ids).  */
      if (int count = (identifier
		       ? push_namespace (identifier, nested_inline_p)
		       : 0))
	nested_definition_count += count;
      else
	cp_parser_error (parser, "nested namespace name required");
      cp_lexer_consume_token (parser->lexer);
    }

  if (nested_definition_count && !identifier)
    cp_parser_error (parser, "namespace name required");

  if (nested_definition_count && attribs)
    error_at (token->location,
	      "a nested namespace definition cannot have attributes");
  if (nested_definition_count && topmost_inline_p)
    error_at (token->location,
	      "a nested namespace definition cannot be inline");

  /* Start the namespace.  */
  nested_definition_count += push_namespace (identifier, is_inline);

  bool has_visibility = handle_namespace_attrs (current_namespace, attribs);

  warning (OPT_Wnamespaces, "namespace %qD entered", current_namespace);

  /* Look for the `{' to validate starting the namespace.  */
  matching_braces braces;
  if (braces.require_open (parser))
    {
      /* Parse the body of the namespace.  */
      cp_parser_namespace_body (parser);

      /* Look for the final `}'.  */
      braces.require_close (parser);
    }

  if (has_visibility)
    pop_visibility (1);

  /* Pop the nested namespace definitions.  */
  while (nested_definition_count--)
    pop_namespace ();
}

/* Parse a namespace-body.

   namespace-body:
     declaration-seq [opt]  */

static void
cp_parser_namespace_body (cp_parser* parser)
{
  cp_parser_declaration_seq_opt (parser);
}

/* Parse a namespace-alias-definition.

   namespace-alias-definition:
     namespace identifier = qualified-namespace-specifier ;  */

static void
cp_parser_namespace_alias_definition (cp_parser* parser)
{
  tree identifier;
  tree namespace_specifier;

  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* Look for the `namespace' keyword.  */
  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
  /* Look for the identifier.  */
  identifier = cp_parser_identifier (parser);
  if (identifier == error_mark_node)
    return;
  /* Look for the `=' token.  */
  if (!cp_parser_uncommitted_to_tentative_parse_p (parser)
      && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      error_at (token->location, "%<namespace%> definition is not allowed here");
      /* Skip the definition.  */
      cp_lexer_consume_token (parser->lexer);
      if (cp_parser_skip_to_closing_brace (parser))
	cp_lexer_consume_token (parser->lexer);
      return;
    }
  cp_parser_require (parser, CPP_EQ, RT_EQ);
  /* Look for the qualified-namespace-specifier.  */
  namespace_specifier
    = cp_parser_qualified_namespace_specifier (parser);
  cp_warn_deprecated_use_scopes (namespace_specifier);
  /* Look for the `;' token.  */
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

  /* Register the alias in the symbol table.  */
  do_namespace_alias (identifier, namespace_specifier);
}

/* Parse a qualified-namespace-specifier.

   qualified-namespace-specifier:
     :: [opt] nested-name-specifier [opt] namespace-name

   Returns a NAMESPACE_DECL corresponding to the specified
   namespace.  */

static tree
cp_parser_qualified_namespace_specifier (cp_parser* parser)
{
  /* Look for the optional `::'.  */
  cp_parser_global_scope_opt (parser,
			      /*current_scope_valid_p=*/false);

  /* Look for the optional nested-name-specifier.  */
  cp_parser_nested_name_specifier_opt (parser,
				       /*typename_keyword_p=*/false,
				       /*check_dependency_p=*/true,
				       /*type_p=*/false,
				       /*is_declaration=*/true);

  return cp_parser_namespace_name (parser);
}

/* Subroutine of cp_parser_using_declaration.  */

static tree
finish_using_decl (tree qscope, tree identifier, bool typename_p = false)
{
  tree decl = NULL_TREE;
  if (at_class_scope_p ())
    {
      /* Create the USING_DECL.  */
      decl = do_class_using_decl (qscope, identifier);

      if (check_for_bare_parameter_packs (decl))
	return error_mark_node;

      if (decl && typename_p)
	USING_DECL_TYPENAME_P (decl) = 1;

      /* Add it to the list of members in this class.  */
      finish_member_declaration (decl);
    }
  else
    finish_nonmember_using_decl (qscope, identifier);
  return decl;
}

/* Parse a using-declaration, or, if ACCESS_DECLARATION_P is true, an
   access declaration.

   using-declaration:
     using typename [opt] :: [opt] nested-name-specifier unqualified-id ;
     using :: unqualified-id ;

   access-declaration:
     qualified-id ;

   */

static bool
cp_parser_using_declaration (cp_parser* parser,
			     bool access_declaration_p)
{
  cp_token *token;
  bool typename_p = false;
  bool global_scope_p;
  tree identifier;
  tree qscope;
  int oldcount = errorcount;
  cp_token *diag_token = NULL;

  if (access_declaration_p)
    {
      diag_token = cp_lexer_peek_token (parser->lexer);
      cp_parser_parse_tentatively (parser);
    }
  else
    {
      /* Look for the `using' keyword.  */
      cp_parser_require_keyword (parser, RID_USING, RT_USING);

 again:
      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* See if it's `typename'.  */
      if (token->keyword == RID_TYPENAME)
	{
	  /* Remember that we've seen it.  */
	  typename_p = true;
	  /* Consume the `typename' token.  */
	  cp_lexer_consume_token (parser->lexer);
	}
    }

  /* Look for the optional global scope qualification.  */
  global_scope_p
    = (cp_parser_global_scope_opt (parser,
				   /*current_scope_valid_p=*/false)
       != NULL_TREE);

  /* If we saw `typename', or didn't see `::', then there must be a
     nested-name-specifier present.  */
  if (typename_p || !global_scope_p)
    {
      qscope = cp_parser_nested_name_specifier (parser, typename_p,
						/*check_dependency_p=*/true,
						/*type_p=*/false,
						/*is_declaration=*/true);
      if (!qscope && !cp_parser_uncommitted_to_tentative_parse_p (parser))
	{
	  cp_parser_skip_to_end_of_block_or_statement (parser);
	  return false;
	}
    }
  /* Otherwise, we could be in either of the two productions.  In that
     case, treat the nested-name-specifier as optional.  */
  else
    qscope = cp_parser_nested_name_specifier_opt (parser,
						  /*typename_keyword_p=*/false,
						  /*check_dependency_p=*/true,
						  /*type_p=*/false,
						  /*is_declaration=*/true);
  if (!qscope)
    qscope = global_namespace;

  cp_warn_deprecated_use_scopes (qscope);

  if (access_declaration_p
      && !MAYBE_CLASS_TYPE_P (qscope)
      && TREE_CODE (qscope) != ENUMERAL_TYPE)
    /* If the qualifying scope of an access-declaration isn't a class
       or enumeration type then it can't be valid.  */
    cp_parser_simulate_error (parser);

  if (access_declaration_p && cp_parser_error_occurred (parser))
    /* Something has already gone wrong; there's no need to parse
       further.  Since an error has occurred, the return value of
       cp_parser_parse_definitely will be false, as required.  */
    return cp_parser_parse_definitely (parser);

  token = cp_lexer_peek_token (parser->lexer);
  /* Parse the unqualified-id.  */
  identifier = cp_parser_unqualified_id (parser,
					 /*template_keyword_p=*/false,
					 /*check_dependency_p=*/true,
					 /*declarator_p=*/true,
					 /*optional_p=*/false);

  if (access_declaration_p)
    {
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	cp_parser_simulate_error (parser);
      if (!cp_parser_parse_definitely (parser))
	return false;
    }
  else if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    {
      cp_token *ell = cp_lexer_consume_token (parser->lexer);
      if (cxx_dialect < cxx17)
	pedwarn (ell->location, OPT_Wc__17_extensions,
		 "pack expansion in using-declaration only available "
		 "with %<-std=c++17%> or %<-std=gnu++17%>");

      /* A parameter pack can appear in the qualifying scope, and/or in the
	 terminal name (if naming a conversion function).  Logically they're
	 part of a single pack expansion of the overall USING_DECL, but we
	 express them as separate pack expansions within the USING_DECL since
	 we can't create a pack expansion over a USING_DECL.  */
      bool saw_parm_pack = false;
      if (uses_parameter_packs (qscope))
	{
	  qscope = make_pack_expansion (qscope);
	  saw_parm_pack = true;
	}
      if (identifier_p (identifier)
	  && IDENTIFIER_CONV_OP_P (identifier)
	  && uses_parameter_packs (TREE_TYPE (identifier)))
	{
	  identifier = make_conv_op_name (make_pack_expansion
					  (TREE_TYPE (identifier)));
	  saw_parm_pack = true;
	}
      if (!saw_parm_pack)
	{
	  /* Issue an error in terms using a SCOPE_REF that includes both
	     components.  */
	  tree name
	    = build_qualified_name (NULL_TREE, qscope, identifier, false);
	  make_pack_expansion (name);
	  gcc_assert (seen_error ());
	  qscope = identifier = error_mark_node;
	}
    }

  /* The function we call to handle a using-declaration is different
     depending on what scope we are in.  */
  if (qscope == error_mark_node || identifier == error_mark_node)
    ;
  else if (!identifier_p (identifier)
	   && TREE_CODE (identifier) != BIT_NOT_EXPR)
    /* [namespace.udecl]

       A using declaration shall not name a template-id.  */
    error_at (token->location,
	      "a template-id may not appear in a using-declaration");
  else
    {
      tree decl = finish_using_decl (qscope, identifier, typename_p);

      if (decl == error_mark_node)
	{
	  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
	  return false;
	}
    }

  if (!access_declaration_p
      && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
    {
      cp_token *comma = cp_lexer_consume_token (parser->lexer);
      if (cxx_dialect < cxx17)
	pedwarn (comma->location, OPT_Wc__17_extensions,
		 "comma-separated list in using-declaration only available "
		 "with %<-std=c++17%> or %<-std=gnu++17%>");
      goto again;
    }

  /* Look for the final `;'.  */
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

  if (access_declaration_p && errorcount == oldcount)
    warning_at (diag_token->location, OPT_Wdeprecated,
		"access declarations are deprecated "
		"in favour of using-declarations; "
		"suggestion: add the %<using%> keyword");

  return true;
}

/* C++20 using enum declaration.

   using-enum-declaration :
       using elaborated-enum-specifier ;  */

static void
cp_parser_using_enum (cp_parser *parser)
{
  cp_parser_require_keyword (parser, RID_USING, RT_USING);

  /* Using cp_parser_elaborated_type_specifier rejects typedef-names, which
     breaks one of the motivating examples in using-enum-5.C.
     cp_parser_simple_type_specifier seems to be closer to what we actually
     want, though that hasn't been properly specified yet.  */

  /* Consume 'enum'.  */
  gcc_checking_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_ENUM));
  cp_lexer_consume_token (parser->lexer);

  cp_token *start = cp_lexer_peek_token (parser->lexer);

  tree type = (cp_parser_simple_type_specifier
	       (parser, NULL, CP_PARSER_FLAGS_TYPENAME_OPTIONAL));

  cp_token *end = cp_lexer_previous_token (parser->lexer);

  if (type == error_mark_node
      || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
    {
      cp_parser_skip_to_end_of_block_or_statement (parser);
      return;
    }
  if (TREE_CODE (type) == TYPE_DECL)
    type = TREE_TYPE (type);

  /* The elaborated-enum-specifier shall not name a dependent type and the type
     shall have a reachable enum-specifier.  */
  const char *msg = nullptr;
  if (cxx_dialect < cxx20)
    msg = _("%<using enum%> "
	    "only available with %<-std=c++20%> or %<-std=gnu++20%>");
  else if (dependent_type_p (type))
    msg = _("%<using enum%> of dependent type %qT");
  else if (TREE_CODE (type) != ENUMERAL_TYPE)
    msg = _("%<using enum%> of non-enumeration type %q#T");
  else if (!COMPLETE_TYPE_P (type))
    msg = _("%<using enum%> of incomplete type %qT");
  else if (OPAQUE_ENUM_P (type))
    msg = _("%<using enum%> of %qT before its enum-specifier");
  if (msg)
    {
      location_t loc = make_location (start, start, end);
      auto_diagnostic_group g;
      error_at (loc, msg, type);
      loc = location_of (type);
      if (cxx_dialect < cxx20 || loc == input_location)
	;
      else if (OPAQUE_ENUM_P (type))
	inform (loc, "opaque-enum-declaration here");
      else
	inform (loc, "declared here");
    }

  /* A using-enum-declaration introduces the enumerator names of the named
     enumeration as if by a using-declaration for each enumerator.  */
  if (TREE_CODE (type) == ENUMERAL_TYPE)
    for (tree v = TYPE_VALUES (type); v; v = TREE_CHAIN (v))
      finish_using_decl (type, DECL_NAME (TREE_VALUE (v)));
}

/* Parse an alias-declaration.

   alias-declaration:
     using identifier attribute-specifier-seq [opt] = type-id  */

static tree
cp_parser_alias_declaration (cp_parser* parser)
{
  tree id, type, decl, pushed_scope = NULL_TREE, attributes;
  location_t id_location, type_location;
  cp_declarator *declarator;
  cp_decl_specifier_seq decl_specs;
  bool member_p;
  const char *saved_message = NULL;

  /* Look for the `using' keyword.  */
  cp_token *using_token
    = cp_parser_require_keyword (parser, RID_USING, RT_USING);
  if (using_token == NULL)
    return error_mark_node;

  id_location = cp_lexer_peek_token (parser->lexer)->location;
  id = cp_parser_identifier (parser);
  if (id == error_mark_node)
    return error_mark_node;

  cp_token *attrs_token = cp_lexer_peek_token (parser->lexer);
  attributes = cp_parser_attributes_opt (parser);
  if (attributes == error_mark_node)
    return error_mark_node;

  cp_parser_require (parser, CPP_EQ, RT_EQ);

  if (cp_parser_error_occurred (parser))
    return error_mark_node;

  cp_parser_commit_to_tentative_parse (parser);

  /* Now we are going to parse the type-id of the declaration.  */

  /*
    [dcl.type]/3 says:

	"A type-specifier-seq shall not define a class or enumeration
	 unless it appears in the type-id of an alias-declaration (7.1.3) that
	 is not the declaration of a template-declaration."

    In other words, if we currently are in an alias template, the
    type-id should not define a type.

    So let's set parser->type_definition_forbidden_message in that
    case; cp_parser_check_type_definition (called by
    cp_parser_class_specifier) will then emit an error if a type is
    defined in the type-id.  */
  if (parser->num_template_parameter_lists)
    {
      saved_message = parser->type_definition_forbidden_message;
      parser->type_definition_forbidden_message =
	G_("types may not be defined in alias template declarations");
    }

  type = cp_parser_type_id (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
			    &type_location);

  /* Restore the error message if need be.  */
  if (parser->num_template_parameter_lists)
    parser->type_definition_forbidden_message = saved_message;

  if (type == error_mark_node
      || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
    {
      cp_parser_skip_to_end_of_block_or_statement (parser);
      return error_mark_node;
    }

  /* A typedef-name can also be introduced by an alias-declaration. The
     identifier following the using keyword becomes a typedef-name. It has
     the same semantics as if it were introduced by the typedef
     specifier. In particular, it does not define a new type and it shall
     not appear in the type-id.  */

  clear_decl_specs (&decl_specs);
  decl_specs.type = type;
  if (attributes != NULL_TREE)
    {
      decl_specs.attributes = attributes;
      set_and_check_decl_spec_loc (&decl_specs,
				   ds_attribute,
				   attrs_token);
    }
  set_and_check_decl_spec_loc (&decl_specs,
			       ds_typedef,
			       using_token);
  set_and_check_decl_spec_loc (&decl_specs,
			       ds_alias,
			       using_token);
  decl_specs.locations[ds_type_spec] = type_location;

  if (parser->num_template_parameter_lists
      && !cp_parser_check_template_parameters (parser,
					       /*num_templates=*/0,
					       /*template_id*/false,
					       id_location,
					       /*declarator=*/NULL))
    return error_mark_node;

  declarator = make_id_declarator (NULL_TREE, id, sfk_none, id_location);

  member_p = at_class_scope_p ();
  if (member_p)
    decl = grokfield (declarator, &decl_specs, NULL_TREE, false,
		      NULL_TREE, attributes);
  else
    decl = start_decl (declarator, &decl_specs, 0,
		       attributes, NULL_TREE, &pushed_scope);
  if (decl == error_mark_node)
    return decl;

  cp_finish_decl (decl, NULL_TREE, 0, NULL_TREE, 0);

  if (pushed_scope)
    pop_scope (pushed_scope);

  /* If decl is a template, return its TEMPLATE_DECL so that it gets
     added into the symbol table; otherwise, return the TYPE_DECL.  */
  if (DECL_LANG_SPECIFIC (decl)
      && DECL_TEMPLATE_INFO (decl)
      && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
    {
      decl = DECL_TI_TEMPLATE (decl);
      if (member_p)
	check_member_template (decl);
    }

  return decl;
}

/* Parse a using-directive.

   using-directive:
     attribute-specifier-seq [opt] using namespace :: [opt]
       nested-name-specifier [opt] namespace-name ;  */

static void
cp_parser_using_directive (cp_parser* parser)
{
  tree namespace_decl;
  tree attribs = cp_parser_std_attribute_spec_seq (parser);
  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    {
      /* Error during attribute parsing that resulted in skipping
	 to next semicolon.  */
      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      return;
    }

  /* Look for the `using' keyword.  */
  cp_parser_require_keyword (parser, RID_USING, RT_USING);
  /* And the `namespace' keyword.  */
  cp_parser_require_keyword (parser, RID_NAMESPACE, RT_NAMESPACE);
  /* Look for the optional `::' operator.  */
  cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
  /* And the optional nested-name-specifier.  */
  cp_parser_nested_name_specifier_opt (parser,
				       /*typename_keyword_p=*/false,
				       /*check_dependency_p=*/true,
				       /*type_p=*/false,
				       /*is_declaration=*/true);
  /* Get the namespace being used.  */
  namespace_decl = cp_parser_namespace_name (parser);
  cp_warn_deprecated_use_scopes (namespace_decl);
  /* And any specified GNU attributes.  */
  if (cp_next_tokens_can_be_gnu_attribute_p (parser))
    attribs = chainon (attribs, cp_parser_gnu_attributes_opt (parser));

  /* Update the symbol table.  */
  finish_using_directive (namespace_decl, attribs);

  /* Look for the final `;'.  */
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
}

/* Parse an asm-definition.

  asm-qualifier:
    volatile
    inline
    goto

  asm-qualifier-list:
    asm-qualifier
    asm-qualifier-list asm-qualifier

   asm-definition:
     asm ( string-literal ) ;

   GNU Extension:

   asm-definition:
     asm asm-qualifier-list [opt] ( string-literal ) ;
     asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt] ) ;
     asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt]
				    : asm-operand-list [opt] ) ;
     asm asm-qualifier-list [opt] ( string-literal : asm-operand-list [opt]
				    : asm-operand-list [opt]
			  : asm-clobber-list [opt] ) ;
     asm asm-qualifier-list [opt] ( string-literal : : asm-operand-list [opt]
				    : asm-clobber-list [opt]
				    : asm-goto-list ) ;

  The form with asm-goto-list is valid if and only if the asm-qualifier-list
  contains goto, and is the only allowed form in that case.  No duplicates are
  allowed in an asm-qualifier-list.  */

static void
cp_parser_asm_definition (cp_parser* parser)
{
  tree outputs = NULL_TREE;
  tree inputs = NULL_TREE;
  tree clobbers = NULL_TREE;
  tree labels = NULL_TREE;
  tree asm_stmt;
  bool extended_p = false;
  bool invalid_inputs_p = false;
  bool invalid_outputs_p = false;
  required_token missing = RT_NONE;
  location_t asm_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Look for the `asm' keyword.  */
  cp_parser_require_keyword (parser, RID_ASM, RT_ASM);

  /* In C++20, unevaluated inline assembly is permitted in constexpr
     functions.  */
  if (parser->in_function_body
      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
      && cxx_dialect < cxx20)
    pedwarn (asm_loc, OPT_Wc__20_extensions, "%<asm%> in %<constexpr%> "
	     "function only available with %<-std=c++20%> or "
	     "%<-std=gnu++20%>");

  /* Handle the asm-qualifier-list.  */
  location_t volatile_loc = UNKNOWN_LOCATION;
  location_t inline_loc = UNKNOWN_LOCATION;
  location_t goto_loc = UNKNOWN_LOCATION;
  location_t first_loc = UNKNOWN_LOCATION;

  if (cp_parser_allow_gnu_extensions_p (parser))
    for (;;)
      {
	cp_token *token = cp_lexer_peek_token (parser->lexer);
	location_t loc = token->location;
	switch (cp_lexer_peek_token (parser->lexer)->keyword)
	  {
	  case RID_VOLATILE:
	    if (volatile_loc)
	      {
		error_at (loc, "duplicate %<asm%> qualifier %qT",
			  token->u.value);
		inform (volatile_loc, "first seen here");
	      }
	    else
	      {
		if (!parser->in_function_body)
		  warning_at (loc, 0, "%<asm%> qualifier %qT ignored "
			      "outside of function body", token->u.value);
		volatile_loc = loc;
	      }
	    cp_lexer_consume_token (parser->lexer);
	    continue;

	  case RID_INLINE:
	    if (inline_loc)
	      {
		error_at (loc, "duplicate %<asm%> qualifier %qT",
			  token->u.value);
		inform (inline_loc, "first seen here");
	      }
	    else
	      inline_loc = loc;
	    if (!first_loc)
	      first_loc = loc;
	    cp_lexer_consume_token (parser->lexer);
	    continue;

	  case RID_GOTO:
	    if (goto_loc)
	      {
		error_at (loc, "duplicate %<asm%> qualifier %qT",
			  token->u.value);
		inform (goto_loc, "first seen here");
	      }
	    else
	      goto_loc = loc;
	    if (!first_loc)
	      first_loc = loc;
	    cp_lexer_consume_token (parser->lexer);
	    continue;

	  case RID_CONST:
	  case RID_RESTRICT:
	    error_at (loc, "%qT is not an %<asm%> qualifier", token->u.value);
	    cp_lexer_consume_token (parser->lexer);
	    continue;

	  default:
	    break;
	  }
	break;
      }

  bool volatile_p = (volatile_loc != UNKNOWN_LOCATION);
  bool inline_p = (inline_loc != UNKNOWN_LOCATION);
  bool goto_p = (goto_loc != UNKNOWN_LOCATION);

  if (!parser->in_function_body && (inline_p || goto_p))
    {
      error_at (first_loc, "%<asm%> qualifier outside of function body");
      inline_p = goto_p = false;
    }

  /* Look for the opening `('.  */
  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return;
  /* Look for the string.  */
  tree string = cp_parser_string_literal (parser, /*translate=*/false,
					  /*wide_ok=*/false);
  if (string == error_mark_node)
    {
      cp_parser_skip_to_closing_parenthesis (parser, true, false,
					     /*consume_paren=*/true);
      return;
    }

  /* If we're allowing GNU extensions, check for the extended assembly
     syntax.  Unfortunately, the `:' tokens need not be separated by
     a space in C, and so, for compatibility, we tolerate that here
     too.  Doing that means that we have to treat the `::' operator as
     two `:' tokens.  */
  if (cp_parser_allow_gnu_extensions_p (parser)
      && parser->in_function_body
      && (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
	  || cp_lexer_next_token_is (parser->lexer, CPP_SCOPE)))
    {
      bool inputs_p = false;
      bool clobbers_p = false;
      bool labels_p = false;

      /* The extended syntax was used.  */
      extended_p = true;

      /* Look for outputs.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
	{
	  /* Consume the `:'.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Parse the output-operands.  */
	  if (cp_lexer_next_token_is_not (parser->lexer,
					  CPP_COLON)
	      && cp_lexer_next_token_is_not (parser->lexer,
					     CPP_SCOPE)
	      && cp_lexer_next_token_is_not (parser->lexer,
					     CPP_CLOSE_PAREN))
            {
              outputs = cp_parser_asm_operand_list (parser);
              if (outputs == error_mark_node)
                invalid_outputs_p = true;
            }
	}
      /* If the next token is `::', there are no outputs, and the
	 next token is the beginning of the inputs.  */
      else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
	/* The inputs are coming next.  */
	inputs_p = true;

      /* Look for inputs.  */
      if (inputs_p
	  || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
	{
	  /* Consume the `:' or `::'.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Parse the output-operands.  */
	  if (cp_lexer_next_token_is_not (parser->lexer,
					  CPP_COLON)
	      && cp_lexer_next_token_is_not (parser->lexer,
					     CPP_SCOPE)
	      && cp_lexer_next_token_is_not (parser->lexer,
					     CPP_CLOSE_PAREN))
            {
              inputs = cp_parser_asm_operand_list (parser);
              if (inputs == error_mark_node)
                invalid_inputs_p = true;
            }
	}
      else if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
	/* The clobbers are coming next.  */
	clobbers_p = true;

      /* Look for clobbers.  */
      if (clobbers_p
	  || cp_lexer_next_token_is (parser->lexer, CPP_COLON))
	{
	  clobbers_p = true;
	  /* Consume the `:' or `::'.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Parse the clobbers.  */
	  if (cp_lexer_next_token_is_not (parser->lexer,
					  CPP_COLON)
	      && cp_lexer_next_token_is_not (parser->lexer,
					     CPP_CLOSE_PAREN))
	    clobbers = cp_parser_asm_clobber_list (parser);
	}
      else if (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
	/* The labels are coming next.  */
	labels_p = true;

      /* Look for labels.  */
      if (labels_p
	  || (goto_p && cp_lexer_next_token_is (parser->lexer, CPP_COLON)))
	{
	  labels_p = true;
	  /* Consume the `:' or `::'.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Parse the labels.  */
	  labels = cp_parser_asm_label_list (parser);
	}

      if (goto_p && !labels_p)
	missing = clobbers_p ? RT_COLON : RT_COLON_SCOPE;
    }
  else if (goto_p)
    missing = RT_COLON_SCOPE;

  /* Look for the closing `)'.  */
  if (!cp_parser_require (parser, missing ? CPP_COLON : CPP_CLOSE_PAREN,
			  missing ? missing : RT_CLOSE_PAREN))
    cp_parser_skip_to_closing_parenthesis (parser, true, false,
					   /*consume_paren=*/true);
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

  if (!invalid_inputs_p && !invalid_outputs_p)
    {
      /* Create the ASM_EXPR.  */
      if (parser->in_function_body)
	{
	  asm_stmt = finish_asm_stmt (asm_loc, volatile_p, string, outputs,
				      inputs, clobbers, labels, inline_p);
	  /* If the extended syntax was not used, mark the ASM_EXPR.  */
	  if (!extended_p)
	    {
	      tree temp = asm_stmt;
	      if (TREE_CODE (temp) == CLEANUP_POINT_EXPR)
		temp = TREE_OPERAND (temp, 0);

	      ASM_INPUT_P (temp) = 1;
	    }
	}
      else
	symtab->finalize_toplevel_asm (string);
    }
}

/* Given the type TYPE of a declaration with declarator DECLARATOR, return the
   type that comes from the decl-specifier-seq.  */

static tree
strip_declarator_types (tree type, cp_declarator *declarator)
{
  for (cp_declarator *d = declarator; d;)
    switch (d->kind)
      {
      case cdk_id:
      case cdk_decomp:
      case cdk_error:
	d = NULL;
	break;

      default:
	if (TYPE_PTRMEMFUNC_P (type))
	  type = TYPE_PTRMEMFUNC_FN_TYPE (type);
	type = TREE_TYPE (type);
	d = d->declarator;
	break;
      }

  return type;
}

/* Warn about the most vexing parse syntactic ambiguity, i.e., warn when
   a construct looks like a variable definition but is actually a function
   declaration.  DECL_SPECIFIERS is the decl-specifier-seq and DECLARATOR
   is the declarator for this function declaration.  */

static void
warn_about_ambiguous_parse (const cp_decl_specifier_seq *decl_specifiers,
			    const cp_declarator *declarator)
{
  /* Only warn if we are declaring a function at block scope.  */
  if (!at_function_scope_p ())
    return;

  /* And only if there is no storage class specified.  */
  if (decl_specifiers->storage_class != sc_none
      || decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
    return;

  if (declarator->kind != cdk_function
      || !declarator->declarator
      || declarator->declarator->kind != cdk_id
      || !identifier_p (get_unqualified_id
			(const_cast<cp_declarator *>(declarator))))
    return;

  /* Don't warn when the whole declarator (not just the declarator-id!)
     was parenthesized.  That is, don't warn for int(n()) but do warn
     for int(f)().  */
  if (declarator->parenthesized != UNKNOWN_LOCATION)
    return;

  tree type;
  if (decl_specifiers->type)
    {
      type = decl_specifiers->type;
      if (TREE_CODE (type) == TYPE_DECL)
	type = TREE_TYPE (type);

      /* If the return type is void there is no ambiguity.  */
      if (same_type_p (type, void_type_node))
	return;
    }
  else if (decl_specifiers->any_type_specifiers_p)
    /* Code like long f(); will have null ->type.  If we have any
       type-specifiers, pretend we've seen int.  */
    type = integer_type_node;
  else
    return;

  auto_diagnostic_group d;
  location_t loc = declarator->u.function.parens_loc;
  tree params = declarator->u.function.parameters;
  const bool has_list_ctor_p = CLASS_TYPE_P (type) && TYPE_HAS_LIST_CTOR (type);

  /* The T t() case.  */
  if (params == void_list_node)
    {
      if (warning_at (loc, OPT_Wvexing_parse,
		      "empty parentheses were disambiguated as a function "
		      "declaration"))
	{
	  /* () means value-initialization (C++03 and up); {} (C++11 and up)
	     means value-initialization or aggregate-initialization, nothing
	     means default-initialization.  We can only suggest removing the
	     parentheses/adding {} if T has a default constructor.  */
	  if (!CLASS_TYPE_P (type) || TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
	    {
	      gcc_rich_location iloc (loc);
	      iloc.add_fixit_remove ();
	      inform (&iloc, "remove parentheses to default-initialize "
		      "a variable");
	      if (cxx_dialect >= cxx11 && !has_list_ctor_p)
		{
		  if (CP_AGGREGATE_TYPE_P (type))
		    inform (loc, "or replace parentheses with braces to "
			    "aggregate-initialize a variable");
		  else
		    inform (loc, "or replace parentheses with braces to "
			    "value-initialize a variable");
		}
	    }
	}
      return;
    }

  /* If we had (...) or the parameter-list wasn't parenthesized,
     we're done.  */
  if (params == NULL_TREE || !PARENTHESIZED_LIST_P (params))
    return;

  /* The T t(X()) case.  */
  if (list_length (params) == 2)
    {
      if (warning_at (loc, OPT_Wvexing_parse,
		      "parentheses were disambiguated as a function "
		      "declaration"))
	{
	  gcc_rich_location iloc (loc);
	  /* {}-initialization means that we can use an initializer-list
	     constructor if no default constructor is available, so don't
	     suggest using {} for classes that have an initializer_list
	     constructor.  */
	  if (cxx_dialect >= cxx11 && !has_list_ctor_p)
	    {
	      iloc.add_fixit_replace (get_start (loc), "{");
	      iloc.add_fixit_replace (get_finish (loc), "}");
	      inform (&iloc, "replace parentheses with braces to declare a "
		      "variable");
	    }
	  else
	    {
	      iloc.add_fixit_insert_after (get_start (loc), "(");
	      iloc.add_fixit_insert_before (get_finish (loc), ")");
	      inform (&iloc, "add parentheses to declare a variable");
	    }
	}
    }
  /* The T t(X(), X()) case.  */
  else if (warning_at (loc, OPT_Wvexing_parse,
		       "parentheses were disambiguated as a function "
		       "declaration"))
    {
      gcc_rich_location iloc (loc);
      if (cxx_dialect >= cxx11 && !has_list_ctor_p)
	{
	  iloc.add_fixit_replace (get_start (loc), "{");
	  iloc.add_fixit_replace (get_finish (loc), "}");
	  inform (&iloc, "replace parentheses with braces to declare a "
		  "variable");
	}
    }
}

/* If DECLARATOR with DECL_SPECS is a function declarator that has
   the form of a deduction guide, tag it as such.  CTOR_DTOR_OR_CONV_P
   has the same meaning as in cp_parser_declarator.  */

static void
cp_parser_maybe_adjust_declarator_for_dguide (cp_parser *parser,
					      cp_decl_specifier_seq *decl_specs,
					      cp_declarator *declarator,
					      int *ctor_dtor_or_conv_p)
{
  if (cxx_dialect >= cxx17
      && *ctor_dtor_or_conv_p <= 0
      && !decl_specs->type
      && !decl_specs->any_type_specifiers_p
      && function_declarator_p (declarator))
    {
      cp_declarator *id = get_id_declarator (declarator);
      tree name = id->u.id.unqualified_name;
      parser->scope = id->u.id.qualifying_scope;
      tree tmpl = cp_parser_lookup_name_simple (parser, name, id->id_loc);
      if (tmpl
	  && (DECL_CLASS_TEMPLATE_P (tmpl)
	      || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)))
	{
	  id->u.id.unqualified_name = dguide_name (tmpl);
	  id->u.id.sfk = sfk_deduction_guide;
	  *ctor_dtor_or_conv_p = 1;
	}
    }
}

/* Declarators [gram.dcl.decl] */

/* Parse an init-declarator.

   init-declarator:
     declarator initializer [opt]

   GNU Extension:

   init-declarator:
     declarator asm-specification [opt] attributes [opt] initializer [opt]

   function-definition:
     decl-specifier-seq [opt] declarator ctor-initializer [opt]
       function-body
     decl-specifier-seq [opt] declarator function-try-block

   GNU Extension:

   function-definition:
     __extension__ function-definition

   TM Extension:

   function-definition:
     decl-specifier-seq [opt] declarator function-transaction-block

   The parser flags FLAGS is used to control type-specifier parsing.

   The DECL_SPECIFIERS apply to this declarator.  Returns a
   representation of the entity declared.  If MEMBER_P is TRUE, then
   this declarator appears in a class scope.  The new DECL created by
   this declarator is returned.

   The CHECKS are access checks that should be performed once we know
   what entity is being declared (and, therefore, what classes have
   befriended it).

   If FUNCTION_DEFINITION_ALLOWED_P then we handle the declarator and
   for a function-definition here as well.  If the declarator is a
   declarator for a function-definition, *FUNCTION_DEFINITION_P will
   be TRUE upon return.  By that point, the function-definition will
   have been completely parsed.

   FUNCTION_DEFINITION_P may be NULL if FUNCTION_DEFINITION_ALLOWED_P
   is FALSE.

   If MAYBE_RANGE_FOR_DECL is not NULL, the pointed tree will be set to the
   parsed declaration if it is an uninitialized single declarator not followed
   by a `;', or to error_mark_node otherwise. Either way, the trailing `;',
   if present, will not be consumed.  If returned, this declarator will be
   created with SD_INITIALIZED but will not call cp_finish_decl.

   If INIT_LOC is not NULL, and *INIT_LOC is equal to UNKNOWN_LOCATION,
   and there is an initializer, the pointed location_t is set to the
   location of the '=' or `(', or '{' in C++11 token introducing the
   initializer.  */

static tree
cp_parser_init_declarator (cp_parser* parser,
			   cp_parser_flags flags,
			   cp_decl_specifier_seq *decl_specifiers,
			   vec<deferred_access_check, va_gc> *checks,
			   bool function_definition_allowed_p,
			   bool member_p,
			   int declares_class_or_enum,
			   bool* function_definition_p,
			   tree* maybe_range_for_decl,
			   location_t* init_loc,
			   tree* auto_result)
{
  cp_token *token = NULL, *asm_spec_start_token = NULL,
           *attributes_start_token = NULL;
  cp_declarator *declarator;
  tree prefix_attributes;
  tree attributes = NULL;
  tree asm_specification;
  tree initializer;
  tree decl = NULL_TREE;
  tree scope;
  int is_initialized;
  /* Only valid if IS_INITIALIZED is true.  In that case, CPP_EQ if
     initialized with "= ..", CPP_OPEN_PAREN if initialized with
     "(...)".  */
  enum cpp_ttype initialization_kind;
  bool is_direct_init = false;
  bool is_non_constant_init;
  int ctor_dtor_or_conv_p;
  bool friend_p = cp_parser_friend_p (decl_specifiers);
  bool static_p = decl_specifiers->storage_class == sc_static;
  tree pushed_scope = NULL_TREE;
  bool range_for_decl_p = false;
  bool saved_default_arg_ok_p = parser->default_arg_ok_p;
  location_t tmp_init_loc = UNKNOWN_LOCATION;

  if (decl_spec_seq_has_spec_p (decl_specifiers, ds_consteval))
    flags |= CP_PARSER_FLAGS_CONSTEVAL;

  /* Assume that this is not the declarator for a function
     definition.  */
  if (function_definition_p)
    *function_definition_p = false;

  /* Default arguments are only permitted for function parameters.  */
  if (decl_spec_seq_has_spec_p (decl_specifiers, ds_typedef))
    parser->default_arg_ok_p = false;

  /* Defer access checks while parsing the declarator; we cannot know
     what names are accessible until we know what is being
     declared.  */
  resume_deferring_access_checks ();

  token = cp_lexer_peek_token (parser->lexer);

  /* Parse the declarator.  */
  declarator
    = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
			    flags, &ctor_dtor_or_conv_p,
			    /*parenthesized_p=*/NULL,
			    member_p, friend_p, static_p);
  /* Gather up the deferred checks.  */
  stop_deferring_access_checks ();

  parser->default_arg_ok_p = saved_default_arg_ok_p;

  /* If the DECLARATOR was erroneous, there's no need to go
     further.  */
  if (declarator == cp_error_declarator)
    return error_mark_node;

  /* Check that the number of template-parameter-lists is OK.  */
  if (!cp_parser_check_declarator_template_parameters (parser, declarator,
						       token->location))
    return error_mark_node;

  if (declares_class_or_enum & 2)
    cp_parser_check_for_definition_in_return_type (declarator,
						   decl_specifiers->type,
						   decl_specifiers->locations[ds_type_spec]);

  /* Figure out what scope the entity declared by the DECLARATOR is
     located in.  `grokdeclarator' sometimes changes the scope, so
     we compute it now.  */
  scope = get_scope_of_declarator (declarator);

  /* Perform any lookups in the declared type which were thought to be
     dependent, but are not in the scope of the declarator.  */
  decl_specifiers->type
    = maybe_update_decl_type (decl_specifiers->type, scope);

  /* If we're allowing GNU extensions, look for an
     asm-specification.  */
  if (cp_parser_allow_gnu_extensions_p (parser))
    {
      /* Look for an asm-specification.  */
      asm_spec_start_token = cp_lexer_peek_token (parser->lexer);
      asm_specification = cp_parser_asm_specification_opt (parser);
    }
  else
    asm_specification = NULL_TREE;

  /* Gather the attributes that were provided with the
     decl-specifiers.  */
  prefix_attributes = decl_specifiers->attributes;

  /* Look for attributes.  */
  attributes_start_token = cp_lexer_peek_token (parser->lexer);
  attributes = cp_parser_attributes_opt (parser);

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  bool bogus_implicit_tmpl = false;

  if (function_declarator_p (declarator))
    {
      /* Handle C++17 deduction guides.  Note that class-scope
	 non-template deduction guides are instead handled in
	 cp_parser_member_declaration.  */
      cp_parser_maybe_adjust_declarator_for_dguide (parser,
						    decl_specifiers,
						    declarator,
						    &ctor_dtor_or_conv_p);

      if (!member_p && !cp_parser_error_occurred (parser))
	warn_about_ambiguous_parse (decl_specifiers, declarator);

      /* Check to see if the token indicates the start of a
	 function-definition.  */
      if (cp_parser_token_starts_function_definition_p (token))
	{
	  if (!function_definition_allowed_p)
	    {
	      /* If a function-definition should not appear here, issue an
		 error message.  */
	      cp_parser_error (parser,
			       "a function-definition is not allowed here");
	      return error_mark_node;
	    }

	  location_t func_brace_location
	    = cp_lexer_peek_token (parser->lexer)->location;

	  /* Neither attributes nor an asm-specification are allowed
	     on a function-definition.  */
	  if (asm_specification)
	    error_at (asm_spec_start_token->location,
		      "an %<asm%> specification is not allowed "
		      "on a function-definition");
	  if (attributes)
	    error_at (attributes_start_token->location,
		      "attributes are not allowed "
		      "on a function-definition");
	  /* This is a function-definition.  */
	  *function_definition_p = true;

	  /* Parse the function definition.  */
	  if (member_p)
	    decl = cp_parser_save_member_function_body (parser,
							decl_specifiers,
							declarator,
							prefix_attributes);
	  else
	    decl =
	      (cp_parser_function_definition_from_specifiers_and_declarator
	       (parser, decl_specifiers, prefix_attributes, declarator));

	  if (decl != error_mark_node && DECL_STRUCT_FUNCTION (decl))
	    {
	      /* This is where the prologue starts...  */
	      DECL_STRUCT_FUNCTION (decl)->function_start_locus
		= func_brace_location;
	    }

	  return decl;
	}
    }
  else if (parser->fully_implicit_function_template_p)
    {
      /* A non-template declaration involving a function parameter list
	 containing an implicit template parameter will be made into a
	 template.  If the resulting declaration is not going to be an
	 actual function then finish the template scope here to prevent it.
	 An error message will be issued once we have a decl to talk about.

         FIXME probably we should do type deduction rather than create an
         implicit template, but the standard currently doesn't allow it. */
      bogus_implicit_tmpl = true;
      finish_fully_implicit_template (parser, NULL_TREE);
    }

  /* [dcl.dcl]

     Only in function declarations for constructors, destructors, type
     conversions, and deduction guides can the decl-specifier-seq be omitted.

     We explicitly postpone this check past the point where we handle
     function-definitions because we tolerate function-definitions
     that are missing their return types in some modes.  */
  if (!decl_specifiers->any_specifiers_p && ctor_dtor_or_conv_p <= 0)
    {
      cp_parser_error (parser,
		       "expected constructor, destructor, or type conversion");
      return error_mark_node;
    }

  /* An `=' or an '{' in C++11, indicate an initializer.  An '(' may indicate
     an initializer as well. */
  if (token->type == CPP_EQ
      || token->type == CPP_OPEN_PAREN
      || token->type == CPP_OPEN_BRACE)
    {
      /* Don't get fooled into thinking that F(i)(1)(2) is an initializer.
	 It isn't; it's an expression.  (Here '(i)' would have already been
	 parsed as a declarator.)   */
      if (token->type == CPP_OPEN_PAREN
	  && cp_parser_uncommitted_to_tentative_parse_p (parser))
	{
	  cp_lexer_save_tokens (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_skip_to_closing_parenthesis (parser,
						 /*recovering*/false,
						 /*or_comma*/false,
						 /*consume_paren*/true);
	  /* If this is an initializer, only a ',' or ';' can follow: either
	     we have another init-declarator, or we're at the end of an
	     init-declarator-list which can only be followed by a ';'.  */
	  bool ok = (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
		     || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
	  cp_lexer_rollback_tokens (parser->lexer);
	  if (UNLIKELY (!ok))
	    /* Not an init-declarator.  */
	    return error_mark_node;
	}
      is_initialized = SD_INITIALIZED;
      initialization_kind = token->type;
      declarator->init_loc = token->location;
      if (maybe_range_for_decl)
	*maybe_range_for_decl = error_mark_node;
      tmp_init_loc = token->location;
      if (init_loc && *init_loc == UNKNOWN_LOCATION)
	*init_loc = tmp_init_loc;

      if (token->type == CPP_EQ
	  && function_declarator_p (declarator))
	{
	  cp_token *t2 = cp_lexer_peek_nth_token (parser->lexer, 2);
	  if (t2->keyword == RID_DEFAULT)
	    is_initialized = SD_DEFAULTED;
	  else if (t2->keyword == RID_DELETE)
	    is_initialized = SD_DELETED;
	}
    }
  else
    {
      /* If the init-declarator isn't initialized and isn't followed by a
	 `,' or `;', it's not a valid init-declarator.  */
      if (token->type != CPP_COMMA
	  && token->type != CPP_SEMICOLON)
	{
	  if (maybe_range_for_decl && *maybe_range_for_decl != error_mark_node)
	    range_for_decl_p = true;
	  else
	    {
	      if (!maybe_range_for_decl)
		cp_parser_error (parser, "expected initializer");
	      return error_mark_node;
	    }
	}
      is_initialized = SD_UNINITIALIZED;
      initialization_kind = CPP_EOF;
    }

  /* Because start_decl has side-effects, we should only call it if we
     know we're going ahead.  By this point, we know that we cannot
     possibly be looking at any other construct.  */
  cp_parser_commit_to_tentative_parse (parser);

  /* Enter the newly declared entry in the symbol table.  If we're
     processing a declaration in a class-specifier, we wait until
     after processing the initializer.  */
  if (!member_p)
    {
      if (parser->in_unbraced_linkage_specification_p)
	decl_specifiers->storage_class = sc_extern;
      decl = start_decl (declarator, decl_specifiers,
			 range_for_decl_p? SD_INITIALIZED : is_initialized,
			 attributes, prefix_attributes, &pushed_scope);
      cp_finalize_omp_declare_simd (parser, decl);
      cp_finalize_oacc_routine (parser, decl, false);
      /* Adjust location of decl if declarator->id_loc is more appropriate:
	 set, and decl wasn't merged with another decl, in which case its
	 location would be different from input_location, and more accurate.  */
      if (DECL_P (decl)
	  && declarator->id_loc != UNKNOWN_LOCATION
	  && DECL_SOURCE_LOCATION (decl) == input_location)
	DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
    }
  else if (scope)
    /* Enter the SCOPE.  That way unqualified names appearing in the
       initializer will be looked up in SCOPE.  */
    pushed_scope = push_scope (scope);

  /* Perform deferred access control checks, now that we know in which
     SCOPE the declared entity resides.  */
  if (!member_p && decl)
    {
      tree saved_current_function_decl = NULL_TREE;

      /* If the entity being declared is a function, pretend that we
	 are in its scope.  If it is a `friend', it may have access to
	 things that would not otherwise be accessible.  */
      if (TREE_CODE (decl) == FUNCTION_DECL)
	{
	  saved_current_function_decl = current_function_decl;
	  current_function_decl = decl;
	}

      /* Perform access checks for template parameters.  */
      cp_parser_perform_template_parameter_access_checks (checks);

      /* Perform the access control checks for the declarator and the
	 decl-specifiers.  */
      perform_deferred_access_checks (tf_warning_or_error);

      /* Restore the saved value.  */
      if (TREE_CODE (decl) == FUNCTION_DECL)
	current_function_decl = saved_current_function_decl;
    }

  /* Parse the initializer.  */
  initializer = NULL_TREE;
  is_direct_init = false;
  is_non_constant_init = true;
  if (is_initialized)
    {
      if (function_declarator_p (declarator))
	{
	   if (initialization_kind == CPP_EQ)
	     initializer = cp_parser_pure_specifier (parser);
	   else
	     {
	       /* If the declaration was erroneous, we don't really
		  know what the user intended, so just silently
		  consume the initializer.  */
	       if (decl != error_mark_node)
		 error_at (tmp_init_loc, "initializer provided for function");
	       cp_parser_skip_to_closing_parenthesis (parser,
						      /*recovering=*/true,
						      /*or_comma=*/false,
						      /*consume_paren=*/true);
	     }
	}
      else
	{
	  /* We want to record the extra mangling scope for in-class
	     initializers of class members and initializers of static
	     data member templates and namespace-scope initializers.
	     The former involves deferring parsing of the initializer
	     until end of class as with default arguments.  So right
	     here we only handle the latter two.  */
	  bool has_lambda_scope = false;

	  if (decl != error_mark_node
	      && !member_p
	      && (processing_template_decl || DECL_NAMESPACE_SCOPE_P (decl)))
	    has_lambda_scope = true;

	  if (has_lambda_scope)
	    start_lambda_scope (decl);
	  initializer = cp_parser_initializer (parser,
					       &is_direct_init,
					       &is_non_constant_init);
	  if (has_lambda_scope)
	    finish_lambda_scope ();
	  if (initializer == error_mark_node)
	    cp_parser_skip_to_end_of_statement (parser);
	}
    }

  /* The old parser allows attributes to appear after a parenthesized
     initializer.  Mark Mitchell proposed removing this functionality
     on the GCC mailing lists on 2002-08-13.  This parser accepts the
     attributes -- but ignores them.  Made a permerror in GCC 8.  */
  if (cp_parser_allow_gnu_extensions_p (parser)
      && initialization_kind == CPP_OPEN_PAREN
      && cp_parser_attributes_opt (parser)
      && permerror (input_location,
		    "attributes after parenthesized initializer ignored"))
    {
      static bool hint;
      if (flag_permissive && !hint)
	{
	  hint = true;
	  inform (input_location,
		  "this flexibility is deprecated and will be removed");
	}
    }

  /* And now complain about a non-function implicit template.  */
  if (bogus_implicit_tmpl && decl != error_mark_node)
    error_at (DECL_SOURCE_LOCATION (decl),
	      "non-function %qD declared as implicit template", decl);

  /* For an in-class declaration, use `grokfield' to create the
     declaration.  */
  if (member_p)
    {
      if (pushed_scope)
	{
	  pop_scope (pushed_scope);
	  pushed_scope = NULL_TREE;
	}
      decl = grokfield (declarator, decl_specifiers,
			initializer, !is_non_constant_init,
			/*asmspec=*/NULL_TREE,
			attr_chainon (attributes, prefix_attributes));
      if (decl && TREE_CODE (decl) == FUNCTION_DECL)
	cp_parser_save_default_args (parser, decl);
      cp_finalize_omp_declare_simd (parser, decl);
      cp_finalize_oacc_routine (parser, decl, false);
    }

  /* Finish processing the declaration.  But, skip member
     declarations.  */
  if (!member_p && decl && decl != error_mark_node && !range_for_decl_p)
    {
      cp_finish_decl (decl,
		      initializer, !is_non_constant_init,
		      asm_specification,
		      /* If the initializer is in parentheses, then this is
			 a direct-initialization, which means that an
			 `explicit' constructor is OK.  Otherwise, an
			 `explicit' constructor cannot be used.  */
		      ((is_direct_init || !is_initialized)
		       ? LOOKUP_NORMAL : LOOKUP_IMPLICIT));
    }
  else if ((cxx_dialect != cxx98) && friend_p
	   && decl && TREE_CODE (decl) == FUNCTION_DECL)
    /* Core issue #226 (C++0x only): A default template-argument
       shall not be specified in a friend class template
       declaration. */
    check_default_tmpl_args (decl, current_template_parms, /*is_primary=*/true,
                             /*is_partial=*/false, /*is_friend_decl=*/1);

  if (!friend_p && pushed_scope)
    pop_scope (pushed_scope);

  if (function_declarator_p (declarator)
      && parser->fully_implicit_function_template_p)
    {
      if (member_p)
	decl = finish_fully_implicit_template (parser, decl);
      else
	finish_fully_implicit_template (parser, /*member_decl_opt=*/0);
    }

  if (auto_result && is_initialized && decl_specifiers->type
      && type_uses_auto (decl_specifiers->type))
    *auto_result = strip_declarator_types (TREE_TYPE (decl), declarator);

  return decl;
}

/* Parse a declarator.

   declarator:
     direct-declarator
     ptr-operator declarator

   abstract-declarator:
     ptr-operator abstract-declarator [opt]
     direct-abstract-declarator

   GNU Extensions:

   declarator:
     attributes [opt] direct-declarator
     attributes [opt] ptr-operator declarator

   abstract-declarator:
     attributes [opt] ptr-operator abstract-declarator [opt]
     attributes [opt] direct-abstract-declarator

   The parser flags FLAGS is used to control type-specifier parsing.

   If CTOR_DTOR_OR_CONV_P is not NULL, *CTOR_DTOR_OR_CONV_P is used to
   detect constructors, destructors, deduction guides, or conversion operators.
   It is set to -1 if the declarator is a name, and +1 if it is a
   function. Otherwise it is set to zero. Usually you just want to
   test for >0, but internally the negative value is used.

   (The reason for CTOR_DTOR_OR_CONV_P is that a declaration must have
   a decl-specifier-seq unless it declares a constructor, destructor,
   or conversion.  It might seem that we could check this condition in
   semantic analysis, rather than parsing, but that makes it difficult
   to handle something like `f()'.  We want to notice that there are
   no decl-specifiers, and therefore realize that this is an
   expression, not a declaration.)

   If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to true iff
   the declarator is a direct-declarator of the form "(...)".

   MEMBER_P is true iff this declarator is a member-declarator.

   FRIEND_P is true iff this declarator is a friend.

   STATIC_P is true iff the keyword static was seen.  */

static cp_declarator *
cp_parser_declarator (cp_parser* parser,
		      cp_parser_declarator_kind dcl_kind,
		      cp_parser_flags flags,
		      int* ctor_dtor_or_conv_p,
		      bool* parenthesized_p,
		      bool member_p, bool friend_p, bool static_p)
{
  cp_declarator *declarator;
  enum tree_code code;
  cp_cv_quals cv_quals;
  tree class_type;
  tree gnu_attributes = NULL_TREE, std_attributes = NULL_TREE;

  /* Assume this is not a constructor, destructor, or type-conversion
     operator.  */
  if (ctor_dtor_or_conv_p)
    *ctor_dtor_or_conv_p = 0;

  if (cp_parser_allow_gnu_extensions_p (parser))
    gnu_attributes = cp_parser_gnu_attributes_opt (parser);

  /* Check for the ptr-operator production.  */
  cp_parser_parse_tentatively (parser);
  /* Parse the ptr-operator.  */
  code = cp_parser_ptr_operator (parser,
				 &class_type,
				 &cv_quals,
				 &std_attributes);

  /* If that worked, then we have a ptr-operator.  */
  if (cp_parser_parse_definitely (parser))
    {
      /* If a ptr-operator was found, then this declarator was not
	 parenthesized.  */
      if (parenthesized_p)
	*parenthesized_p = false;
      /* The dependent declarator is optional if we are parsing an
	 abstract-declarator.  */
      if (dcl_kind != CP_PARSER_DECLARATOR_NAMED)
	cp_parser_parse_tentatively (parser);

      /* Parse the dependent declarator.  */
      declarator = cp_parser_declarator (parser, dcl_kind, flags,
					 /*ctor_dtor_or_conv_p=*/NULL,
					 /*parenthesized_p=*/NULL,
					 member_p, friend_p, static_p);

      /* If we are parsing an abstract-declarator, we must handle the
	 case where the dependent declarator is absent.  */
      if (dcl_kind != CP_PARSER_DECLARATOR_NAMED
	  && !cp_parser_parse_definitely (parser))
	declarator = NULL;

      declarator = cp_parser_make_indirect_declarator
	(code, class_type, cv_quals, declarator, std_attributes);
    }
  /* Everything else is a direct-declarator.  */
  else
    {
      if (parenthesized_p)
	*parenthesized_p = cp_lexer_next_token_is (parser->lexer,
						   CPP_OPEN_PAREN);
      declarator = cp_parser_direct_declarator (parser, dcl_kind,
						flags, ctor_dtor_or_conv_p,
						member_p, friend_p, static_p);
    }

  if (gnu_attributes && declarator && declarator != cp_error_declarator)
    declarator->attributes = gnu_attributes;
  return declarator;
}

/* Parse a direct-declarator or direct-abstract-declarator.

   direct-declarator:
     declarator-id
     direct-declarator ( parameter-declaration-clause )
       cv-qualifier-seq [opt]
       ref-qualifier [opt]
       exception-specification [opt]
     direct-declarator [ constant-expression [opt] ]
     ( declarator )

   direct-abstract-declarator:
     direct-abstract-declarator [opt]
       ( parameter-declaration-clause )
       cv-qualifier-seq [opt]
       ref-qualifier [opt]
       exception-specification [opt]
     direct-abstract-declarator [opt] [ constant-expression [opt] ]
     ( abstract-declarator )

   Returns a representation of the declarator.  DCL_KIND is
   CP_PARSER_DECLARATOR_ABSTRACT, if we are parsing a
   direct-abstract-declarator.  It is CP_PARSER_DECLARATOR_NAMED, if
   we are parsing a direct-declarator.  It is
   CP_PARSER_DECLARATOR_EITHER, if we can accept either - in the case
   of ambiguity we prefer an abstract declarator, as per
   [dcl.ambig.res].
   The parser flags FLAGS is used to control type-specifier parsing.
   CTOR_DTOR_OR_CONV_P, MEMBER_P, FRIEND_P, and STATIC_P are
   as for cp_parser_declarator.  */

static cp_declarator *
cp_parser_direct_declarator (cp_parser* parser,
			     cp_parser_declarator_kind dcl_kind,
			     cp_parser_flags flags,
			     int* ctor_dtor_or_conv_p,
			     bool member_p, bool friend_p, bool static_p)
{
  cp_token *token;
  cp_declarator *declarator = NULL;
  tree scope = NULL_TREE;
  bool saved_default_arg_ok_p = parser->default_arg_ok_p;
  bool saved_in_declarator_p = parser->in_declarator_p;
  bool first = true;
  tree pushed_scope = NULL_TREE;
  cp_token *open_paren = NULL, *close_paren = NULL;

  while (true)
    {
      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_OPEN_PAREN)
	{
	  /* This is either a parameter-declaration-clause, or a
	     parenthesized declarator. When we know we are parsing a
	     named declarator, it must be a parenthesized declarator
	     if FIRST is true. For instance, `(int)' is a
	     parameter-declaration-clause, with an omitted
	     direct-abstract-declarator. But `((*))', is a
	     parenthesized abstract declarator. Finally, when T is a
	     template parameter `(T)' is a
	     parameter-declaration-clause, and not a parenthesized
	     named declarator.

	     We first try and parse a parameter-declaration-clause,
	     and then try a nested declarator (if FIRST is true).

	     It is not an error for it not to be a
	     parameter-declaration-clause, even when FIRST is
	     false. Consider,

	       int i (int);
	       int i (3);

	     The first is the declaration of a function while the
	     second is the definition of a variable, including its
	     initializer.

	     Having seen only the parenthesis, we cannot know which of
	     these two alternatives should be selected.  Even more
	     complex are examples like:

	       int i (int (a));
	       int i (int (3));

	     The former is a function-declaration; the latter is a
	     variable initialization.

	     Thus again, we try a parameter-declaration-clause, and if
	     that fails, we back out and return.  */

	  if (!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
	    {
	      tree params;
	      bool is_declarator = false;

	      open_paren = NULL;

	      /* In a member-declarator, the only valid interpretation
		 of a parenthesis is the start of a
		 parameter-declaration-clause.  (It is invalid to
		 initialize a static data member with a parenthesized
		 initializer; only the "=" form of initialization is
		 permitted.)  */
	      if (!member_p)
		cp_parser_parse_tentatively (parser);

	      /* Consume the `('.  */
	      const location_t parens_start = token->location;
	      matching_parens parens;
	      parens.consume_open (parser);
	      if (first)
		{
		  /* If this is going to be an abstract declarator, we're
		     in a declarator and we can't have default args.  */
		  parser->default_arg_ok_p = false;
		  parser->in_declarator_p = true;
		}

	      begin_scope (sk_function_parms, NULL_TREE);

	      /* Parse the parameter-declaration-clause.  */
	      params
		= cp_parser_parameter_declaration_clause (parser, flags);
	      const location_t parens_end
		= cp_lexer_peek_token (parser->lexer)->location;

	      /* Consume the `)'.  */
	      parens.require_close (parser);

	      /* If all went well, parse the cv-qualifier-seq,
		 ref-qualifier and the exception-specification.  */
	      if (member_p || cp_parser_parse_definitely (parser))
		{
		  cp_cv_quals cv_quals;
		  cp_virt_specifiers virt_specifiers;
		  cp_ref_qualifier ref_qual;
		  tree exception_specification;
		  tree late_return;
		  tree attrs;
		  bool memfn = (member_p || (pushed_scope
					     && CLASS_TYPE_P (pushed_scope)));
		  unsigned char local_variables_forbidden_p
		    = parser->local_variables_forbidden_p;
		  /* 'this' is not allowed in static member functions.  */
		  if (static_p || friend_p)
		    parser->local_variables_forbidden_p |= THIS_FORBIDDEN;

		  is_declarator = true;

		  if (ctor_dtor_or_conv_p)
		    *ctor_dtor_or_conv_p = *ctor_dtor_or_conv_p < 0;
		  first = false;

		  /* Parse the cv-qualifier-seq.  */
		  cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
		  /* Parse the ref-qualifier. */
		  ref_qual = cp_parser_ref_qualifier_opt (parser);
		  /* Parse the tx-qualifier.  */
		  tree tx_qual = cp_parser_tx_qualifier_opt (parser);

		  tree save_ccp = current_class_ptr;
		  tree save_ccr = current_class_ref;
		  if (memfn && !friend_p && !static_p)
		    /* DR 1207: 'this' is in scope after the cv-quals.  */
		    inject_this_parameter (current_class_type, cv_quals);

		  /* If it turned out that this is e.g. a pointer to a
		     function, we don't want to delay noexcept parsing.  */
		  if (declarator == NULL || declarator->kind != cdk_id)
		    flags &= ~CP_PARSER_FLAGS_DELAY_NOEXCEPT;

		  /* Parse the exception-specification.  */
		  exception_specification
		    = cp_parser_exception_specification_opt (parser,
							     flags);

		  attrs = cp_parser_std_attribute_spec_seq (parser);

		  cp_omp_declare_simd_data odsd;
		  if ((flag_openmp || flag_openmp_simd)
		      && declarator
		      && declarator->std_attributes
		      && declarator->kind == cdk_id)
		    {
		      tree *pa = &declarator->std_attributes;
		      cp_parser_handle_directive_omp_attributes (parser, pa,
								 &odsd, false);
		    }

		  /* In here, we handle cases where attribute is used after
		     the function declaration.  For example:
		     void func (int x) __attribute__((vector(..)));  */
		  tree gnu_attrs = NULL_TREE;
		  tree requires_clause = NULL_TREE;
		  late_return
		    = cp_parser_late_return_type_opt (parser, declarator,
						      requires_clause);

		  cp_finalize_omp_declare_simd (parser, &odsd);

		  /* Parse the virt-specifier-seq.  */
		  virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);

		  location_t parens_loc = make_location (parens_start,
							 parens_start,
							 parens_end);
		  /* Create the function-declarator.  */
		  declarator = make_call_declarator (declarator,
						     params,
						     cv_quals,
						     virt_specifiers,
						     ref_qual,
						     tx_qual,
						     exception_specification,
						     late_return,
						     requires_clause,
						     attrs,
						     parens_loc);
		  declarator->attributes = gnu_attrs;
		  /* Any subsequent parameter lists are to do with
		     return type, so are not those of the declared
		     function.  */
		  parser->default_arg_ok_p = false;

		  current_class_ptr = save_ccp;
		  current_class_ref = save_ccr;

		  /* Restore the state of local_variables_forbidden_p.  */
		  parser->local_variables_forbidden_p
		    = local_variables_forbidden_p;
		}

	      /* Remove the function parms from scope.  */
	      pop_bindings_and_leave_scope ();

	      if (is_declarator)
		/* Repeat the main loop.  */
		continue;
	    }

	  /* If this is the first, we can try a parenthesized
	     declarator.  */
	  if (first)
	    {
	      bool saved_in_type_id_in_expr_p;

	      parser->default_arg_ok_p = saved_default_arg_ok_p;
	      parser->in_declarator_p = saved_in_declarator_p;

	      open_paren = token;
	      /* Consume the `('.  */
	      matching_parens parens;
	      parens.consume_open (parser);
	      /* Parse the nested declarator.  */
	      saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
	      parser->in_type_id_in_expr_p = true;
	      declarator
		= cp_parser_declarator (parser, dcl_kind, flags,
					ctor_dtor_or_conv_p,
					/*parenthesized_p=*/NULL,
					member_p, friend_p,
					/*static_p=*/false);
	      parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
	      first = false;
	      /* Expect a `)'.  */
	      close_paren = cp_lexer_peek_token (parser->lexer);
	      if (!parens.require_close (parser))
		declarator = cp_error_declarator;
	      if (declarator == cp_error_declarator)
		break;

	      goto handle_declarator;
	    }
	  /* Otherwise, we must be done.  */
	  else
	    break;
	}
      else if ((!first || dcl_kind != CP_PARSER_DECLARATOR_NAMED)
	       && token->type == CPP_OPEN_SQUARE
	       && !cp_next_tokens_can_be_attribute_p (parser))
	{
	  /* Parse an array-declarator.  */
	  tree bounds, attrs;

	  if (ctor_dtor_or_conv_p)
	    *ctor_dtor_or_conv_p = 0;

	  open_paren = NULL;
	  first = false;
	  parser->default_arg_ok_p = false;
	  parser->in_declarator_p = true;
	  /* Consume the `['.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Peek at the next token.  */
	  token = cp_lexer_peek_token (parser->lexer);
	  /* If the next token is `]', then there is no
	     constant-expression.  */
	  if (token->type != CPP_CLOSE_SQUARE)
	    {
	      bool non_constant_p;
	      bounds
		= cp_parser_constant_expression (parser,
						 /*allow_non_constant=*/true,
						 &non_constant_p);
	      if (!non_constant_p)
		/* OK */;
	      else if (error_operand_p (bounds))
		/* Already gave an error.  */;
	      else if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
		/* Let compute_array_index_type diagnose this.  */;
	      else if (!parser->in_function_body
		       || parsing_function_declarator ())
		{
		  /* Normally, the array bound must be an integral constant
		     expression.  However, as an extension, we allow VLAs
		     in function scopes as long as they aren't part of a
		     parameter declaration.  */
		  cp_parser_error (parser,
				   "array bound is not an integer constant");
		  bounds = error_mark_node;
		}
	      else if (processing_template_decl
		       && !type_dependent_expression_p (bounds))
		{
		  /* Remember this wasn't a constant-expression.  */
		  bounds = build_nop (TREE_TYPE (bounds), bounds);
		  TREE_SIDE_EFFECTS (bounds) = 1;
		}
	    }
	  else
	    bounds = NULL_TREE;
	  /* Look for the closing `]'.  */
	  if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
	    {
	      declarator = cp_error_declarator;
	      break;
	    }

	  attrs = cp_parser_std_attribute_spec_seq (parser);
	  declarator = make_array_declarator (declarator, bounds);
	  declarator->std_attributes = attrs;
	}
      else if (first && dcl_kind != CP_PARSER_DECLARATOR_ABSTRACT)
	{
	  {
	    tree qualifying_scope;
	    tree unqualified_name;
	    tree attrs;
	    special_function_kind sfk;
	    bool abstract_ok;
	    bool pack_expansion_p = false;
	    cp_token *declarator_id_start_token;

	    /* Parse a declarator-id */
	    abstract_ok = (dcl_kind == CP_PARSER_DECLARATOR_EITHER);
	    if (abstract_ok)
	      {
		cp_parser_parse_tentatively (parser);

		/* If we see an ellipsis, we should be looking at a
		   parameter pack. */
		if (token->type == CPP_ELLIPSIS)
		  {
		    /* Consume the `...' */
		    cp_lexer_consume_token (parser->lexer);

		    pack_expansion_p = true;
		  }
	      }

	    declarator_id_start_token = cp_lexer_peek_token (parser->lexer);
	    unqualified_name
	      = cp_parser_declarator_id (parser, /*optional_p=*/abstract_ok);
	    qualifying_scope = parser->scope;
	    if (abstract_ok)
	      {
		bool okay = false;

		if (!unqualified_name && pack_expansion_p)
		  {
		    /* Check whether an error occurred. */
		    okay = !cp_parser_error_occurred (parser);

		    /* We already consumed the ellipsis to mark a
		       parameter pack, but we have no way to report it,
		       so abort the tentative parse. We will be exiting
		       immediately anyway. */
		    cp_parser_abort_tentative_parse (parser);
		  }
		else
		  okay = cp_parser_parse_definitely (parser);

		if (!okay)
		  unqualified_name = error_mark_node;
		else if (unqualified_name
			 && (qualifying_scope
			     || (!identifier_p (unqualified_name))))
		  {
		    cp_parser_error (parser, "expected unqualified-id");
		    unqualified_name = error_mark_node;
		  }
	      }

	    if (!unqualified_name)
	      return NULL;
	    if (unqualified_name == error_mark_node)
	      {
		declarator = cp_error_declarator;
		pack_expansion_p = false;
		declarator->parameter_pack_p = false;
		break;
	      }

	    attrs = cp_parser_std_attribute_spec_seq (parser);

	    if (qualifying_scope && at_namespace_scope_p ()
		&& TREE_CODE (qualifying_scope) == TYPENAME_TYPE)
	      {
		/* In the declaration of a member of a template class
		   outside of the class itself, the SCOPE will sometimes
		   be a TYPENAME_TYPE.  For example, given:

		   template <typename T>
		   int S<T>::R::i = 3;

		   the SCOPE will be a TYPENAME_TYPE for `S<T>::R'.  In
		   this context, we must resolve S<T>::R to an ordinary
		   type, rather than a typename type.

		   The reason we normally avoid resolving TYPENAME_TYPEs
		   is that a specialization of `S' might render
		   `S<T>::R' not a type.  However, if `S' is
		   specialized, then this `i' will not be used, so there
		   is no harm in resolving the types here.  */
		tree type;

		/* Resolve the TYPENAME_TYPE.  */
		type = resolve_typename_type (qualifying_scope,
					      /*only_current_p=*/false);
		/* If that failed, the declarator is invalid.  */
		if (TREE_CODE (type) == TYPENAME_TYPE)
		  {
		    if (typedef_variant_p (type))
		      error_at (declarator_id_start_token->location,
				"cannot define member of dependent typedef "
				"%qT", type);
		    else
		      error_at (declarator_id_start_token->location,
				"%<%T::%E%> is not a type",
				TYPE_CONTEXT (qualifying_scope),
				TYPE_IDENTIFIER (qualifying_scope));
		  }
		qualifying_scope = type;
	      }

	    sfk = sfk_none;

	    if (unqualified_name)
	      {
		tree class_type;

		if (qualifying_scope
		    && CLASS_TYPE_P (qualifying_scope))
		  class_type = qualifying_scope;
		else
		  class_type = current_class_type;

		if (TREE_CODE (unqualified_name) == TYPE_DECL)
		  {
		    tree name_type = TREE_TYPE (unqualified_name);

		    if (!class_type || !same_type_p (name_type, class_type))
		      {
			/* We do not attempt to print the declarator
			   here because we do not have enough
			   information about its original syntactic
			   form.  */
			cp_parser_error (parser, "invalid declarator");
			declarator = cp_error_declarator;
			break;
		      }
		    else if (qualifying_scope
			     && CLASSTYPE_USE_TEMPLATE (name_type))
		      {
			error_at (declarator_id_start_token->location,
				  "invalid use of constructor as a template");
			inform (declarator_id_start_token->location,
				"use %<%T::%D%> instead of %<%T::%D%> to "
				"name the constructor in a qualified name",
				class_type,
				DECL_NAME (TYPE_TI_TEMPLATE (class_type)),
				class_type, name_type);
			declarator = cp_error_declarator;
			break;
		      }
		    unqualified_name = constructor_name (class_type);
		  }

		if (class_type)
		  {
		    if (TREE_CODE (unqualified_name) == BIT_NOT_EXPR)
		      sfk = sfk_destructor;
		    else if (identifier_p (unqualified_name)
			     && IDENTIFIER_CONV_OP_P (unqualified_name))
		      sfk = sfk_conversion;
		    else if (/* There's no way to declare a constructor
				for an unnamed type, even if the type
				got a name for linkage purposes.  */
			     !TYPE_WAS_UNNAMED (class_type)
			     /* Handle correctly (c++/19200):

				struct S {
				  struct T{};
				  friend void S(T);
				};

				and also:

				namespace N {
				  void S();
				}

				struct S {
				  friend void N::S();
				};  */
			     && (!friend_p || class_type == qualifying_scope)
			     && constructor_name_p (unqualified_name,
						    class_type))
		      sfk = sfk_constructor;
		    else if (is_overloaded_fn (unqualified_name)
			     && DECL_CONSTRUCTOR_P (get_first_fn
						    (unqualified_name)))
		      sfk = sfk_constructor;

		    if (ctor_dtor_or_conv_p && sfk != sfk_none)
		      *ctor_dtor_or_conv_p = -1;
		  }
	      }
	    declarator = make_id_declarator (qualifying_scope,
					     unqualified_name,
					     sfk, token->location);
	    declarator->std_attributes = attrs;
	    declarator->parameter_pack_p = pack_expansion_p;

	    if (pack_expansion_p)
	      maybe_warn_variadic_templates ();

	    /* We're looking for this case in [temp.res]:
	       A qualified-id is assumed to name a type if [...]
	       - it is a decl-specifier of the decl-specifier-seq of a
		 parameter-declaration in a declarator of a function or
		 function template declaration, ... */
	    if (cxx_dialect >= cxx20
		&& (flags & CP_PARSER_FLAGS_TYPENAME_OPTIONAL)
		&& declarator->kind == cdk_id
		&& !at_class_scope_p ()
		&& cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
	      {
		/* ...whose declarator-id is qualified.  If it isn't, never
		   assume the parameters to refer to types.  */
		if (qualifying_scope == NULL_TREE)
		  flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
		else
		  {
		    /* Now we have something like
		       template <typename T> int C::x(S::p);
		       which can be a function template declaration or a
		       variable template definition.  If name lookup for
		       the declarator-id C::x finds one or more function
		       templates, assume S::p to name a type.  Otherwise,
		       don't.  */
		    tree decl
		      = cp_parser_lookup_name (parser, unqualified_name,
					       none_type,
					       /*is_template=*/false,
					       /*is_namespace=*/false,
					       /*check_dependency=*/false,
					       /*ambiguous_decls=*/NULL,
					       token->location);

		    if (!is_overloaded_fn (decl)
			/* Allow
			   template<typename T>
			   A<T>::A(T::type) { }  */
			&& !(MAYBE_CLASS_TYPE_P (qualifying_scope)
			     && constructor_name_p (unqualified_name,
						    qualifying_scope)))
		      flags &= ~CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
		  }
	      }
	  }

	handle_declarator:;
	  scope = get_scope_of_declarator (declarator);
	  if (scope)
	    {
	      /* Any names that appear after the declarator-id for a
		 member are looked up in the containing scope.  */
	      if (at_function_scope_p ())
		{
		  /* But declarations with qualified-ids can't appear in a
		     function.  */
		  cp_parser_error (parser, "qualified-id in declaration");
		  declarator = cp_error_declarator;
		  break;
		}
	      pushed_scope = push_scope (scope);
	    }
	  parser->in_declarator_p = true;
	  if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
	      || (declarator && declarator->kind == cdk_id))
	    /* Default args are only allowed on function
	       declarations.  */
	    parser->default_arg_ok_p = saved_default_arg_ok_p;
	  else
	    parser->default_arg_ok_p = false;

	  first = false;
	}
      /* We're done.  */
      else
	break;
    }

  /* For an abstract declarator, we might wind up with nothing at this
     point.  That's an error; the declarator is not optional.  */
  if (!declarator)
    cp_parser_error (parser, "expected declarator");
  else if (open_paren)
    {
      /* Record overly parenthesized declarator so we can give a
	 diagnostic about confusing decl/expr disambiguation.  */
      if (declarator->kind == cdk_array)
	{
	  /* If the open and close parens are on different lines, this
	     is probably a formatting thing, so ignore.  */
	  expanded_location open = expand_location (open_paren->location);
	  expanded_location close = expand_location (close_paren->location);
	  if (open.line != close.line || open.file != close.file)
	    open_paren = NULL;
	}
      if (open_paren)
	declarator->parenthesized = make_location (open_paren->location,
						   open_paren->location,
						   close_paren->location);
    }

  /* If we entered a scope, we must exit it now.  */
  if (pushed_scope)
    pop_scope (pushed_scope);

  parser->default_arg_ok_p = saved_default_arg_ok_p;
  parser->in_declarator_p = saved_in_declarator_p;

  return declarator;
}

/* Parse a ptr-operator.

   ptr-operator:
     * attribute-specifier-seq [opt] cv-qualifier-seq [opt] (C++11)
     * cv-qualifier-seq [opt]
     &
     :: [opt] nested-name-specifier * cv-qualifier-seq [opt]
     nested-name-specifier * attribute-specifier-seq [opt] cv-qualifier-seq [opt] (C++11)

   GNU Extension:

   ptr-operator:
     & cv-qualifier-seq [opt]

   Returns INDIRECT_REF if a pointer, or pointer-to-member, was used.
   Returns ADDR_EXPR if a reference was used, or NON_LVALUE_EXPR for
   an rvalue reference. In the case of a pointer-to-member, *TYPE is
   filled in with the TYPE containing the member.  *CV_QUALS is
   filled in with the cv-qualifier-seq, or TYPE_UNQUALIFIED, if there
   are no cv-qualifiers.  Returns ERROR_MARK if an error occurred.
   Note that the tree codes returned by this function have nothing
   to do with the types of trees that will be eventually be created
   to represent the pointer or reference type being parsed. They are
   just constants with suggestive names. */
static enum tree_code
cp_parser_ptr_operator (cp_parser* parser,
			tree* type,
			cp_cv_quals *cv_quals,
			tree *attributes)
{
  enum tree_code code = ERROR_MARK;
  cp_token *token;
  tree attrs = NULL_TREE;

  /* Assume that it's not a pointer-to-member.  */
  *type = NULL_TREE;
  /* And that there are no cv-qualifiers.  */
  *cv_quals = TYPE_UNQUALIFIED;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* If it's a `*', `&' or `&&' we have a pointer or reference.  */
  if (token->type == CPP_MULT)
    code = INDIRECT_REF;
  else if (token->type == CPP_AND)
    code = ADDR_EXPR;
  else if ((cxx_dialect != cxx98) &&
	   token->type == CPP_AND_AND) /* C++0x only */
    code = NON_LVALUE_EXPR;

  if (code != ERROR_MARK)
    {
      /* Consume the `*', `&' or `&&'.  */
      cp_lexer_consume_token (parser->lexer);

      /* A `*' can be followed by a cv-qualifier-seq, and so can a
	 `&', if we are allowing GNU extensions.  (The only qualifier
	 that can legally appear after `&' is `restrict', but that is
	 enforced during semantic analysis.  */
      if (code == INDIRECT_REF
	  || cp_parser_allow_gnu_extensions_p (parser))
	*cv_quals = cp_parser_cv_qualifier_seq_opt (parser);

      attrs = cp_parser_std_attribute_spec_seq (parser);
      if (attributes != NULL)
	*attributes = attrs;
    }
  else
    {
      /* Try the pointer-to-member case.  */
      cp_parser_parse_tentatively (parser);
      /* Look for the optional `::' operator.  */
      cp_parser_global_scope_opt (parser,
				  /*current_scope_valid_p=*/false);
      /* Look for the nested-name specifier.  */
      token = cp_lexer_peek_token (parser->lexer);
      cp_parser_nested_name_specifier (parser,
				       /*typename_keyword_p=*/false,
				       /*check_dependency_p=*/true,
				       /*type_p=*/false,
				       /*is_declaration=*/false);
      /* If we found it, and the next token is a `*', then we are
	 indeed looking at a pointer-to-member operator.  */
      if (!cp_parser_error_occurred (parser)
	  && cp_parser_require (parser, CPP_MULT, RT_MULT))
	{
	  /* Indicate that the `*' operator was used.  */
	  code = INDIRECT_REF;

	  if (TREE_CODE (parser->scope) == NAMESPACE_DECL)
	    error_at (token->location, "%qD is a namespace", parser->scope);
	  else if (TREE_CODE (parser->scope) == ENUMERAL_TYPE)
	    error_at (token->location, "cannot form pointer to member of "
		      "non-class %q#T", parser->scope);
	  else
	    {
	      /* The type of which the member is a member is given by the
		 current SCOPE.  */
	      *type = parser->scope;
	      /* The next name will not be qualified.  */
	      parser->scope = NULL_TREE;
	      parser->qualifying_scope = NULL_TREE;
	      parser->object_scope = NULL_TREE;
	      /* Look for optional c++11 attributes.  */
	      attrs = cp_parser_std_attribute_spec_seq (parser);
	      if (attributes != NULL)
		*attributes = attrs;
	      /* Look for the optional cv-qualifier-seq.  */
	      *cv_quals = cp_parser_cv_qualifier_seq_opt (parser);
	    }
	}
      /* If that didn't work we don't have a ptr-operator.  */
      if (!cp_parser_parse_definitely (parser))
	cp_parser_error (parser, "expected ptr-operator");
    }

  return code;
}

/* Parse an (optional) cv-qualifier-seq.

   cv-qualifier-seq:
     cv-qualifier cv-qualifier-seq [opt]

   cv-qualifier:
     const
     volatile

   GNU Extension:

   cv-qualifier:
     __restrict__

   Returns a bitmask representing the cv-qualifiers.  */

static cp_cv_quals
cp_parser_cv_qualifier_seq_opt (cp_parser* parser)
{
  cp_cv_quals cv_quals = TYPE_UNQUALIFIED;

  while (true)
    {
      cp_token *token;
      cp_cv_quals cv_qualifier;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* See if it's a cv-qualifier.  */
      switch (token->keyword)
	{
	case RID_CONST:
	  cv_qualifier = TYPE_QUAL_CONST;
	  break;

	case RID_VOLATILE:
	  cv_qualifier = TYPE_QUAL_VOLATILE;
	  break;

	case RID_RESTRICT:
	  cv_qualifier = TYPE_QUAL_RESTRICT;
	  break;

	default:
	  cv_qualifier = TYPE_UNQUALIFIED;
	  break;
	}

      if (!cv_qualifier)
	break;

      if (cv_quals & cv_qualifier)
	{
	  gcc_rich_location richloc (token->location);
	  richloc.add_fixit_remove ();
	  error_at (&richloc, "duplicate cv-qualifier");
	  cp_lexer_purge_token (parser->lexer);
	}
      else
	{
	  cp_lexer_consume_token (parser->lexer);
	  cv_quals |= cv_qualifier;
	}
    }

  return cv_quals;
}

/* Parse an (optional) ref-qualifier

   ref-qualifier:
     &
     &&

   Returns cp_ref_qualifier representing ref-qualifier. */

static cp_ref_qualifier
cp_parser_ref_qualifier_opt (cp_parser* parser)
{
  cp_ref_qualifier ref_qual = REF_QUAL_NONE;

  /* Don't try to parse bitwise '&' as a ref-qualifier (c++/57532).  */
  if (cxx_dialect < cxx11 && cp_parser_parsing_tentatively (parser))
    return ref_qual;

  while (true)
    {
      cp_ref_qualifier curr_ref_qual = REF_QUAL_NONE;
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_AND:
	  curr_ref_qual = REF_QUAL_LVALUE;
	  break;

	case CPP_AND_AND:
	  curr_ref_qual = REF_QUAL_RVALUE;
	  break;

	default:
	  curr_ref_qual = REF_QUAL_NONE;
	  break;
	}

      if (!curr_ref_qual)
	break;
      else if (ref_qual)
	{
	  error_at (token->location, "multiple ref-qualifiers");
	  cp_lexer_purge_token (parser->lexer);
	}
      else
	{
	  ref_qual = curr_ref_qual;
	  cp_lexer_consume_token (parser->lexer);
	}
    }

  return ref_qual;
}

/* Parse an optional tx-qualifier.

   tx-qualifier:
     transaction_safe
     transaction_safe_dynamic  */

static tree
cp_parser_tx_qualifier_opt (cp_parser *parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_NAME)
    {
      tree name = token->u.value;
      const char *p = IDENTIFIER_POINTER (name);
      const int len = strlen ("transaction_safe");
      if (startswith (p, "transaction_safe"))
	{
	  p += len;
	  if (*p == '\0'
	      || !strcmp (p, "_dynamic"))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      if (!flag_tm)
		{
		  error ("%qE requires %<-fgnu-tm%>", name);
		  return NULL_TREE;
		}
	      else
		return name;
	    }
	}
    }
  return NULL_TREE;
}

/* Parse an (optional) virt-specifier-seq.

   virt-specifier-seq:
     virt-specifier virt-specifier-seq [opt]

   virt-specifier:
     override
     final

   Returns a bitmask representing the virt-specifiers.  */

static cp_virt_specifiers
cp_parser_virt_specifier_seq_opt (cp_parser* parser)
{
  cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;

  while (true)
    {
      cp_token *token;
      cp_virt_specifiers virt_specifier;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* See if it's a virt-specifier-qualifier.  */
      if (token->type != CPP_NAME)
        break;
      if (id_equal (token->u.value, "override"))
        {
          maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
          virt_specifier = VIRT_SPEC_OVERRIDE;
        }
      else if (id_equal (token->u.value, "final"))
        {
          maybe_warn_cpp0x (CPP0X_OVERRIDE_CONTROLS);
          virt_specifier = VIRT_SPEC_FINAL;
        }
      else if (id_equal (token->u.value, "__final"))
        {
          virt_specifier = VIRT_SPEC_FINAL;
        }
      else
	break;

      if (virt_specifiers & virt_specifier)
	{
	  gcc_rich_location richloc (token->location);
	  richloc.add_fixit_remove ();
	  error_at (&richloc, "duplicate virt-specifier");
	  cp_lexer_purge_token (parser->lexer);
	}
      else
	{
	  cp_lexer_consume_token (parser->lexer);
	  virt_specifiers |= virt_specifier;
	}
    }
  return virt_specifiers;
}

/* Used by handling of trailing-return-types and NSDMI, in which 'this'
   is in scope even though it isn't real.  */

void
inject_this_parameter (tree ctype, cp_cv_quals quals)
{
  tree this_parm;

  if (current_class_ptr)
    {
      /* We don't clear this between NSDMIs.  Is it already what we want?  */
      tree type = TREE_TYPE (TREE_TYPE (current_class_ptr));
      if (DECL_P (current_class_ptr)
	  && DECL_CONTEXT (current_class_ptr) == NULL_TREE
	  && same_type_ignoring_top_level_qualifiers_p (ctype, type)
	  && cp_type_quals (type) == quals)
	return;
    }

  this_parm = build_this_parm (NULL_TREE, ctype, quals);
  /* Clear this first to avoid shortcut in cp_build_indirect_ref.  */
  current_class_ptr = NULL_TREE;
  current_class_ref
    = cp_build_fold_indirect_ref (this_parm);
  current_class_ptr = this_parm;
}

/* Return true iff our current scope is a non-static data member
   initializer.  */

bool
parsing_nsdmi (void)
{
  /* We recognize NSDMI context by the context-less 'this' pointer set up
     by the function above.  */
  if (current_class_ptr
      && TREE_CODE (current_class_ptr) == PARM_DECL
      && DECL_CONTEXT (current_class_ptr) == NULL_TREE)
    return true;
  return false;
}

/* True if we're parsing a function declarator.  */

bool
parsing_function_declarator ()
{
  /* this_entity is NULL for a function parameter scope while parsing the
     declarator; it is set when parsing the body of the function.  */
  return (current_binding_level->kind == sk_function_parms
	  && !current_binding_level->this_entity);
}

/* Parse a late-specified return type, if any.  This is not a separate
   non-terminal, but part of a function declarator, which looks like

   -> trailing-type-specifier-seq abstract-declarator(opt)

   Returns the type indicated by the type-id.

   In addition to this, parse any queued up #pragma omp declare simd
   clauses, and #pragma acc routine clauses.

   QUALS is either a bitmask of cv_qualifiers or -1 for a non-member
   function.  */

static tree
cp_parser_late_return_type_opt (cp_parser* parser, cp_declarator *declarator,
				tree& requires_clause)
{
  cp_token *token;
  tree type = NULL_TREE;
  bool declare_simd_p = (parser->omp_declare_simd
			 && declarator
			 && declarator->kind == cdk_id);

  bool oacc_routine_p = (parser->oacc_routine
			 && declarator
			 && declarator->kind == cdk_id);

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* A late-specified return type is indicated by an initial '->'. */
  if (token->type != CPP_DEREF
      && token->keyword != RID_REQUIRES
      && !(token->type == CPP_NAME
	   && token->u.value == ridpointers[RID_REQUIRES])
      && !(declare_simd_p || oacc_routine_p))
    return NULL_TREE;

  if (token->type == CPP_DEREF)
    {
      /* Consume the ->.  */
      cp_lexer_consume_token (parser->lexer);

      type = cp_parser_trailing_type_id (parser);
    }

  /* Function declarations may be followed by a trailing
     requires-clause.  */
  requires_clause = cp_parser_requires_clause_opt (parser, false);

  if (declare_simd_p)
    declarator->attributes
      = cp_parser_late_parsing_omp_declare_simd (parser,
						 declarator->attributes);
  if (oacc_routine_p)
    declarator->attributes
      = cp_parser_late_parsing_oacc_routine (parser,
					     declarator->attributes);

  return type;
}

/* Parse a declarator-id.

   declarator-id:
     id-expression
     :: [opt] nested-name-specifier [opt] type-name

   In the `id-expression' case, the value returned is as for
   cp_parser_id_expression if the id-expression was an unqualified-id.
   If the id-expression was a qualified-id, then a SCOPE_REF is
   returned.  The first operand is the scope (either a NAMESPACE_DECL
   or TREE_TYPE), but the second is still just a representation of an
   unqualified-id.  */

static tree
cp_parser_declarator_id (cp_parser* parser, bool optional_p)
{
  tree id;
  /* The expression must be an id-expression.  Assume that qualified
     names are the names of types so that:

       template <class T>
       int S<T>::R::i = 3;

     will work; we must treat `S<T>::R' as the name of a type.
     Similarly, assume that qualified names are templates, where
     required, so that:

       template <class T>
       int S<T>::R<T>::i = 3;

     will work, too.  */
  id = cp_parser_id_expression (parser,
				/*template_keyword_p=*/false,
				/*check_dependency_p=*/false,
				/*template_p=*/NULL,
				/*declarator_p=*/true,
				optional_p);
  if (id && BASELINK_P (id))
    id = BASELINK_FUNCTIONS (id);
  return id;
}

/* Parse a type-id.

   type-id:
     type-specifier-seq abstract-declarator [opt]

   The parser flags FLAGS is used to control type-specifier parsing.

   If IS_TEMPLATE_ARG is true, we are parsing a template argument.

   If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
   i.e. we've just seen "->".

   Returns the TYPE specified.  */

static tree
cp_parser_type_id_1 (cp_parser *parser, cp_parser_flags flags,
		     bool is_template_arg, bool is_trailing_return,
		     location_t *type_location)
{
  cp_decl_specifier_seq type_specifier_seq;
  cp_declarator *abstract_declarator;

  /* Parse the type-specifier-seq.  */
  cp_parser_type_specifier_seq (parser, flags,
				/*is_declaration=*/false,
				is_trailing_return,
				&type_specifier_seq);
  if (type_location)
    *type_location = type_specifier_seq.locations[ds_type_spec];

  if (is_template_arg && type_specifier_seq.type
      && TREE_CODE (type_specifier_seq.type) == TEMPLATE_TYPE_PARM
      && CLASS_PLACEHOLDER_TEMPLATE (type_specifier_seq.type))
    /* A bare template name as a template argument is a template template
       argument, not a placeholder, so fail parsing it as a type argument.  */
    {
      gcc_assert (cp_parser_uncommitted_to_tentative_parse_p (parser));
      cp_parser_simulate_error (parser);
      return error_mark_node;
    }
  if (type_specifier_seq.type == error_mark_node)
    return error_mark_node;

  /* There might or might not be an abstract declarator.  */
  cp_parser_parse_tentatively (parser);
  /* Look for the declarator.  */
  abstract_declarator
    = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_ABSTRACT,
			    CP_PARSER_FLAGS_NONE, NULL,
			    /*parenthesized_p=*/NULL,
			    /*member_p=*/false,
			    /*friend_p=*/false,
			    /*static_p=*/false);
  /* Check to see if there really was a declarator.  */
  if (!cp_parser_parse_definitely (parser))
    abstract_declarator = NULL;

  bool auto_typeid_ok = false;
  /* The concepts TS allows 'auto' as a type-id.  */
  if (flag_concepts_ts)
    auto_typeid_ok = !parser->in_type_id_in_expr_p;
  /* DR 625 prohibits use of auto as a template-argument.  We allow 'auto'
     outside the template-argument-list context here only for the sake of
     diagnostic: grokdeclarator then can emit a better error message for
     e.g. using T = auto.  */
  else if (flag_concepts)
    auto_typeid_ok = (!parser->in_type_id_in_expr_p
		      && !parser->in_template_argument_list_p);

  if (type_specifier_seq.type
      && !auto_typeid_ok
      /* None of the valid uses of 'auto' in C++14 involve the type-id
	 nonterminal, but it is valid in a trailing-return-type.  */
      && !(cxx_dialect >= cxx14 && is_trailing_return))
    if (tree auto_node = type_uses_auto (type_specifier_seq.type))
      {
	/* A type-id with type 'auto' is only ok if the abstract declarator
	   is a function declarator with a late-specified return type.

	   A type-id with 'auto' is also valid in a trailing-return-type
	   in a compound-requirement. */
	if (abstract_declarator
	    && abstract_declarator->kind == cdk_function
	    && abstract_declarator->u.function.late_return_type)
	  /* OK */;
	else if (parser->in_result_type_constraint_p)
	  /* OK */;
	else
	  {
	    if (!cp_parser_simulate_error (parser))
	      {
		location_t loc = type_specifier_seq.locations[ds_type_spec];
		if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
		  {
		    auto_diagnostic_group g;
		    gcc_rich_location richloc (loc);
		    richloc.add_fixit_insert_after ("<>");
		    error_at (&richloc, "missing template arguments after %qE",
			      tmpl);
		    inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
			    tmpl);
		  }
		else if (parser->in_template_argument_list_p)
		  error_at (loc, "%qT not permitted in template argument",
			    auto_node);
		else
		  error_at (loc, "invalid use of %qT", auto_node);
	      }
	    return error_mark_node;
	  }
      }

  return groktypename (&type_specifier_seq, abstract_declarator,
		       is_template_arg);
}

/* Wrapper for cp_parser_type_id_1.  */

static tree
cp_parser_type_id (cp_parser *parser, cp_parser_flags flags,
		   location_t *type_location)
{
  return cp_parser_type_id_1 (parser, flags, false, false, type_location);
}

/* Wrapper for cp_parser_type_id_1.  */

static tree
cp_parser_template_type_arg (cp_parser *parser)
{
  tree r;
  const char *saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in template arguments");
  r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL);
  parser->type_definition_forbidden_message = saved_message;
  if (cxx_dialect >= cxx14 && !flag_concepts && type_uses_auto (r))
    {
      error ("invalid use of %<auto%> in template argument");
      r = error_mark_node;
    }
  return r;
}

/* Wrapper for cp_parser_type_id_1.  */

static tree
cp_parser_trailing_type_id (cp_parser *parser)
{
  return cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
			      false, true, NULL);
}

/* Parse a type-specifier-seq.

   type-specifier-seq:
     type-specifier type-specifier-seq [opt]

   GNU extension:

   type-specifier-seq:
     attributes type-specifier-seq [opt]

   The parser flags FLAGS is used to control type-specifier parsing.

   If IS_DECLARATION is true, we are at the start of a "condition" or
   exception-declaration, so we might be followed by a declarator-id.

   If IS_TRAILING_RETURN is true, we are in a trailing-return-type,
   i.e. we've just seen "->".

   Sets *TYPE_SPECIFIER_SEQ to represent the sequence.  */

static void
cp_parser_type_specifier_seq (cp_parser* parser,
			      cp_parser_flags flags,
			      bool is_declaration,
			      bool is_trailing_return,
			      cp_decl_specifier_seq *type_specifier_seq)
{
  bool seen_type_specifier = false;
  cp_token *start_token = NULL;

  /* Clear the TYPE_SPECIFIER_SEQ.  */
  clear_decl_specs (type_specifier_seq);

  flags |= CP_PARSER_FLAGS_OPTIONAL;
  /* In the context of a trailing return type, enum E { } is an
     elaborated-type-specifier followed by a function-body, not an
     enum-specifier.  */
  if (is_trailing_return)
    flags |= CP_PARSER_FLAGS_NO_TYPE_DEFINITIONS;

  /* Parse the type-specifiers and attributes.  */
  while (true)
    {
      tree type_specifier;
      bool is_cv_qualifier;

      /* Check for attributes first.  */
      if (cp_next_tokens_can_be_attribute_p (parser))
	{
	  /* GNU attributes at the end of a declaration apply to the
	     declaration as a whole, not to the trailing return type.  So look
	     ahead to see if these attributes are at the end.  */
	  if (seen_type_specifier && is_trailing_return
	      && cp_next_tokens_can_be_gnu_attribute_p (parser))
	    {
	      size_t n = cp_parser_skip_attributes_opt (parser, 1);
	      cp_token *tok = cp_lexer_peek_nth_token (parser->lexer, n);
	      if (tok->type == CPP_SEMICOLON || tok->type == CPP_COMMA
		  || tok->type == CPP_EQ || tok->type == CPP_OPEN_BRACE)
		break;
	    }
	  type_specifier_seq->attributes
	    = attr_chainon (type_specifier_seq->attributes,
			    cp_parser_attributes_opt (parser));
	  continue;
	}

      /* record the token of the beginning of the type specifier seq,
         for error reporting purposes*/
     if (!start_token)
       start_token = cp_lexer_peek_token (parser->lexer);

      /* Look for the type-specifier.  */
      type_specifier = cp_parser_type_specifier (parser,
						 flags,
						 type_specifier_seq,
						 /*is_declaration=*/false,
						 NULL,
						 &is_cv_qualifier);
      if (!type_specifier)
	{
	  /* If the first type-specifier could not be found, this is not a
	     type-specifier-seq at all.  */
	  if (!seen_type_specifier)
	    {
	      /* Set in_declarator_p to avoid skipping to the semicolon.  */
	      int in_decl = parser->in_declarator_p;
	      parser->in_declarator_p = true;

	      if (cp_parser_uncommitted_to_tentative_parse_p (parser)
		  || !cp_parser_parse_and_diagnose_invalid_type_name (parser))
		cp_parser_error (parser, "expected type-specifier");

	      parser->in_declarator_p = in_decl;

	      type_specifier_seq->type = error_mark_node;
	      return;
	    }
	  /* If subsequent type-specifiers could not be found, the
	     type-specifier-seq is complete.  */
	  break;
	}

      seen_type_specifier = true;
      /* The standard says that a condition can be:

	    type-specifier-seq declarator = assignment-expression

	 However, given:

	   struct S {};
	   if (int S = ...)

	 we should treat the "S" as a declarator, not as a
	 type-specifier.  The standard doesn't say that explicitly for
	 type-specifier-seq, but it does say that for
	 decl-specifier-seq in an ordinary declaration.  Perhaps it
	 would be clearer just to allow a decl-specifier-seq here, and
	 then add a semantic restriction that if any decl-specifiers
	 that are not type-specifiers appear, the program is invalid.  */
      if (is_declaration && !is_cv_qualifier)
	flags |= CP_PARSER_FLAGS_NO_USER_DEFINED_TYPES;
    }
}

/* Return whether the function currently being declared has an associated
   template parameter list.  */

static bool
function_being_declared_is_template_p (cp_parser* parser)
{
  if (!current_template_parms || processing_template_parmlist)
    return false;

  if (parser->implicit_template_scope)
    return true;

  if (at_class_scope_p ()
      && TYPE_BEING_DEFINED (current_class_type))
    return parser->num_template_parameter_lists != 0;

  return ((int) parser->num_template_parameter_lists > template_class_depth
	  (current_class_type));
}

/* Parse a parameter-declaration-clause.

   parameter-declaration-clause:
     parameter-declaration-list [opt] ... [opt]
     parameter-declaration-list , ...

   The parser flags FLAGS is used to control type-specifier parsing.

   Returns a representation for the parameter declarations.  A return
   value of NULL indicates a parameter-declaration-clause consisting
   only of an ellipsis.  */

static tree
cp_parser_parameter_declaration_clause (cp_parser* parser,
					cp_parser_flags flags)
{
  tree parameters;
  cp_token *token;
  bool ellipsis_p;

  auto cleanup = make_temp_override
    (parser->auto_is_implicit_function_template_parm_p);

  if (!processing_specialization
      && !processing_template_parmlist
      && !processing_explicit_instantiation
      /* default_arg_ok_p tracks whether this is a parameter-clause for an
         actual function or a random abstract declarator.  */
      && parser->default_arg_ok_p)
    if (!current_function_decl
	|| (current_class_type && LAMBDA_TYPE_P (current_class_type)))
      parser->auto_is_implicit_function_template_parm_p = true;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* Check for trivial parameter-declaration-clauses.  */
  if (token->type == CPP_ELLIPSIS)
    {
      /* Consume the `...' token.  */
      cp_lexer_consume_token (parser->lexer);
      return NULL_TREE;
    }
  else if (token->type == CPP_CLOSE_PAREN)
    /* There are no parameters.  */
    return void_list_node;
  /* Check for `(void)', too, which is a special case.  */
  else if (token->keyword == RID_VOID
	   && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
	       == CPP_CLOSE_PAREN))
    {
      /* Consume the `void' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* There are no parameters.  */
      return explicit_void_list_node;
    }

  /* A vector of parameters that haven't been pushed yet.  */
  auto_vec<tree> pending_decls;

  /* Parse the parameter-declaration-list.  */
  parameters = cp_parser_parameter_declaration_list (parser, flags,
						     &pending_decls);
  /* If a parse error occurred while parsing the
     parameter-declaration-list, then the entire
     parameter-declaration-clause is erroneous.  */
  if (parameters == error_mark_node)
    return NULL_TREE;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* If it's a `,', the clause should terminate with an ellipsis.  */
  if (token->type == CPP_COMMA)
    {
      /* Consume the `,'.  */
      cp_lexer_consume_token (parser->lexer);
      /* Expect an ellipsis.  */
      ellipsis_p
	= (cp_parser_require (parser, CPP_ELLIPSIS, RT_ELLIPSIS) != NULL);
    }
  /* It might also be `...' if the optional trailing `,' was
     omitted.  */
  else if (token->type == CPP_ELLIPSIS)
    {
      /* Consume the `...' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* And remember that we saw it.  */
      ellipsis_p = true;
    }
  else
    ellipsis_p = false;

  /* A valid parameter-declaration-clause can only be followed by a ')'.
     So it's time to push all the parameters we have seen now that we
     know we have a valid declaration.  Note that here we may not have
     committed yet, nor should we.  Pushing here will detect the error
     of redefining a parameter.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
    for (tree p : pending_decls)
      pushdecl (p);

  /* Finish the parameter list.  */
  if (!ellipsis_p)
    parameters = chainon (parameters, void_list_node);

  return parameters;
}

/* Parse a parameter-declaration-list.

   parameter-declaration-list:
     parameter-declaration
     parameter-declaration-list , parameter-declaration

   The parser flags FLAGS is used to control type-specifier parsing.
   PENDING_DECLS is a vector of parameters that haven't been pushed yet.

   Returns a representation of the parameter-declaration-list, as for
   cp_parser_parameter_declaration_clause.  However, the
   `void_list_node' is never appended to the list.  */

static tree
cp_parser_parameter_declaration_list (cp_parser* parser,
				      cp_parser_flags flags,
				      auto_vec<tree> *pending_decls)
{
  tree parameters = NULL_TREE;
  tree *tail = &parameters;
  bool saved_in_unbraced_linkage_specification_p;
  int index = 0;

  /* The special considerations that apply to a function within an
     unbraced linkage specifications do not apply to the parameters
     to the function.  */
  saved_in_unbraced_linkage_specification_p
    = parser->in_unbraced_linkage_specification_p;
  parser->in_unbraced_linkage_specification_p = false;

  /* Look for more parameters.  */
  while (true)
    {
      cp_parameter_declarator *parameter;
      tree decl = error_mark_node;
      bool parenthesized_p = false;

      /* Parse the parameter.  */
      parameter
	= cp_parser_parameter_declaration (parser, flags,
					   /*template_parm_p=*/false,
					   &parenthesized_p);

      /* We don't know yet if the enclosing context is unavailable or deprecated,
	 so wait and deal with it in grokparms if appropriate.  */
      deprecated_state = UNAVAILABLE_DEPRECATED_SUPPRESS;

      if (parameter && !cp_parser_error_occurred (parser))
	{
	  decl = grokdeclarator (parameter->declarator,
				 &parameter->decl_specifiers,
				 PARM,
				 parameter->default_argument != NULL_TREE,
				 &parameter->decl_specifiers.attributes);
	  if (decl != error_mark_node && parameter->loc != UNKNOWN_LOCATION)
	    DECL_SOURCE_LOCATION (decl) = parameter->loc;
	}

      deprecated_state = DEPRECATED_NORMAL;

      /* If a parse error occurred parsing the parameter declaration,
	 then the entire parameter-declaration-list is erroneous.  */
      if (decl == error_mark_node)
	{
	  parameters = error_mark_node;
	  break;
	}

      if (parameter->decl_specifiers.attributes)
	cplus_decl_attributes (&decl,
			       parameter->decl_specifiers.attributes,
			       0);
      if (DECL_NAME (decl))
	{
	  /* We cannot always pushdecl while parsing tentatively because
	     it may have side effects and we can't be sure yet if we're
	     parsing a declaration, e.g.:

	       S foo(int(x), int(x), int{x});

	     where it's not clear if we're dealing with a constructor call
	     or a function declaration until we've seen the last argument
	     which breaks it up.
	     It's safe to pushdecl so long as it doesn't result in a clash
	     with an already-pushed parameter.  But we don't delay pushing
	     different parameters to handle

	       S foo(int(i), decltype(i) j = 42);

	     which is valid.  */
	  if (pending_decls
	      && cp_parser_uncommitted_to_tentative_parse_p (parser)
	      /* See if PARAMETERS already contains a parameter with the same
		 DECL_NAME as DECL.  */
	      && [parameters, decl] {
		   for (tree p = parameters; p; p = TREE_CHAIN (p))
		     if (DECL_NAME (decl) == DECL_NAME (TREE_VALUE (p)))
		       return true;
		   return false;
		 }())
	    pending_decls->safe_push (decl);
	  else
	    decl = pushdecl (decl);
	}

      if (decl != error_mark_node)
	{
	  retrofit_lang_decl (decl);
	  DECL_PARM_INDEX (decl) = ++index;
	  DECL_PARM_LEVEL (decl) = function_parm_depth ();
	}

      /* Add the new parameter to the list.  */
      *tail = build_tree_list (parameter->default_argument, decl);
      tail = &TREE_CHAIN (*tail);

      /* If the parameters were parenthesized, it's the case of
	 T foo(X(x)) which looks like a variable definition but
	 is a function declaration.  */
      if (index == 1 || PARENTHESIZED_LIST_P (parameters))
	PARENTHESIZED_LIST_P (parameters) = parenthesized_p;

      /* Peek at the next token.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
	  || cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS)
	  /* These are for Objective-C++ */
	  || cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
	  || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	/* The parameter-declaration-list is complete.  */
	break;
      else if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	{
	  cp_token *token;

	  /* Peek at the next token.  */
	  token = cp_lexer_peek_nth_token (parser->lexer, 2);
	  /* If it's an ellipsis, then the list is complete.  */
	  if (token->type == CPP_ELLIPSIS)
	    break;
	  /* Otherwise, there must be more parameters.  Consume the
	     `,'.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* When parsing something like:

		int i(float f, double d)

	     we can tell after seeing the declaration for "f" that we
	     are not looking at an initialization of a variable "i",
	     but rather at the declaration of a function "i".

	     Due to the fact that the parsing of template arguments
	     (as specified to a template-id) requires backtracking we
	     cannot use this technique when inside a template argument
	     list.  */
	  if (!parser->in_template_argument_list_p
	      && !parser->in_type_id_in_expr_p
	      && cp_parser_uncommitted_to_tentative_parse_p (parser)
	      /* However, a parameter-declaration of the form
		 "float(f)" (which is a valid declaration of a
		 parameter "f") can also be interpreted as an
		 expression (the conversion of "f" to "float").  */
	      && !parenthesized_p)
	    cp_parser_commit_to_tentative_parse (parser);
	}
      else
	{
	  cp_parser_error (parser, "expected %<,%> or %<...%>");
	  if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
	    cp_parser_skip_to_closing_parenthesis (parser,
						   /*recovering=*/true,
						   /*or_comma=*/false,
						   /*consume_paren=*/false);
	  break;
	}
    }

  parser->in_unbraced_linkage_specification_p
    = saved_in_unbraced_linkage_specification_p;

  /* Reset implicit_template_scope if we are about to leave the function
     parameter list that introduced it.  Note that for out-of-line member
     definitions, there will be one or more class scopes before we get to
     the template parameter scope.  */

  if (cp_binding_level *its = parser->implicit_template_scope)
    if (cp_binding_level *maybe_its = current_binding_level->level_chain)
      {
	while (maybe_its->kind == sk_class)
	  maybe_its = maybe_its->level_chain;
	if (maybe_its == its)
	  {
	    parser->implicit_template_parms = 0;
	    parser->implicit_template_scope = 0;
	  }
      }

  return parameters;
}

/* Parse a parameter declaration.

   parameter-declaration:
     decl-specifier-seq ... [opt] declarator
     decl-specifier-seq declarator = assignment-expression
     decl-specifier-seq ... [opt] abstract-declarator [opt]
     decl-specifier-seq abstract-declarator [opt] = assignment-expression

   The parser flags FLAGS is used to control type-specifier parsing.

   If TEMPLATE_PARM_P is TRUE, then this parameter-declaration
   declares a template parameter.  (In that case, a non-nested `>'
   token encountered during the parsing of the assignment-expression
   is not interpreted as a greater-than operator.)

   Returns a representation of the parameter, or NULL if an error
   occurs.  If PARENTHESIZED_P is non-NULL, *PARENTHESIZED_P is set to
   true iff the declarator is of the form "(p)".  */

static cp_parameter_declarator *
cp_parser_parameter_declaration (cp_parser *parser,
				 cp_parser_flags flags,
				 bool template_parm_p,
				 bool *parenthesized_p)
{
  int declares_class_or_enum;
  cp_decl_specifier_seq decl_specifiers;
  cp_declarator *declarator;
  tree default_argument;
  cp_token *token = NULL, *declarator_token_start = NULL;
  const char *saved_message;
  bool template_parameter_pack_p = false;

  /* In a template parameter, `>' is not an operator.

     [temp.param]

     When parsing a default template-argument for a non-type
     template-parameter, the first non-nested `>' is taken as the end
     of the template parameter-list rather than a greater-than
     operator.  */

  /* Type definitions may not appear in parameter types.  */
  saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in parameter types");

  int template_parm_idx = (function_being_declared_is_template_p (parser) ?
			   TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS
					    (current_template_parms)) : 0);

  /* Parse the declaration-specifiers.  */
  cp_token *decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
  cp_parser_decl_specifier_seq (parser,
				flags,
				&decl_specifiers,
				&declares_class_or_enum);

  /* [dcl.spec.auto.general]: "A placeholder-type-specifier of the form
     type-constraint opt auto can be used as a decl-specifier of the
     decl-specifier-seq of a parameter-declaration of a function declaration
     or lambda-expression..." but we must not synthesize an implicit template
     type parameter in its declarator.  That is, in "void f(auto[auto{10}]);"
     we want to synthesize only the first auto.  */
  auto cleanup = make_temp_override
    (parser->auto_is_implicit_function_template_parm_p, false);

  /* Complain about missing 'typename' or other invalid type names.  */
  if (!decl_specifiers.any_type_specifiers_p
      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
    decl_specifiers.type = error_mark_node;

  /* If an error occurred, there's no reason to attempt to parse the
     rest of the declaration.  */
  if (cp_parser_error_occurred (parser))
    {
      parser->type_definition_forbidden_message = saved_message;
      return NULL;
    }

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* If the next token is a `)', `,', `=', `>', or `...', then there
     is no declarator. However, when variadic templates are enabled,
     there may be a declarator following `...'.  */
  if (token->type == CPP_CLOSE_PAREN
      || token->type == CPP_COMMA
      || token->type == CPP_EQ
      || token->type == CPP_GREATER)
    {
      declarator = NULL;
      if (parenthesized_p)
	*parenthesized_p = false;
    }
  /* Otherwise, there should be a declarator.  */
  else
    {
      bool saved_default_arg_ok_p = parser->default_arg_ok_p;
      parser->default_arg_ok_p = false;

      /* After seeing a decl-specifier-seq, if the next token is not a
	 "(" or "{", there is no possibility that the code is a valid
	 expression.  Therefore, if parsing tentatively, we commit at
	 this point.  */
      if (!parser->in_template_argument_list_p
	  /* In an expression context, having seen:

	       (int((char ...

	     we cannot be sure whether we are looking at a
	     function-type (taking a "char" as a parameter) or a cast
	     of some object of type "char" to "int".  */
	  && !parser->in_type_id_in_expr_p
	  && cp_parser_uncommitted_to_tentative_parse_p (parser)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
	{
	  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	    {
	      if (decl_specifiers.type
		  && template_placeholder_p (decl_specifiers.type))
		/* This is a CTAD expression, not a parameter declaration.  */
		cp_parser_simulate_error (parser);
	    }
	  else
	    cp_parser_commit_to_tentative_parse (parser);
	}
      /* Parse the declarator.  */
      declarator_token_start = token;
      declarator = cp_parser_declarator (parser,
					 CP_PARSER_DECLARATOR_EITHER,
					 CP_PARSER_FLAGS_NONE,
					 /*ctor_dtor_or_conv_p=*/NULL,
					 parenthesized_p,
					 /*member_p=*/false,
					 /*friend_p=*/false,
					 /*static_p=*/false);
      parser->default_arg_ok_p = saved_default_arg_ok_p;
      /* After the declarator, allow more attributes.  */
      decl_specifiers.attributes
	= attr_chainon (decl_specifiers.attributes,
			cp_parser_attributes_opt (parser));

      /* If the declarator is a template parameter pack, remember that and
	 clear the flag in the declarator itself so we don't get errors
	 from grokdeclarator.  */
      if (template_parm_p && declarator && declarator->parameter_pack_p)
	{
	  declarator->parameter_pack_p = false;
	  template_parameter_pack_p = true;
	}
    }

  /* If the next token is an ellipsis, and we have not seen a declarator
     name, and if either the type of the declarator contains parameter
     packs but it is not a TYPE_PACK_EXPANSION or is null (this happens
     for, eg, abbreviated integral type names), then we actually have a
     parameter pack expansion expression. Otherwise, leave the ellipsis
     for a C-style variadic function. */
  token = cp_lexer_peek_token (parser->lexer);

  /* If a function parameter pack was specified and an implicit template
     parameter was introduced during cp_parser_parameter_declaration,
     change any implicit parameters introduced into packs.  */
  if (parser->implicit_template_parms
      && ((token->type == CPP_ELLIPSIS
	   && declarator_can_be_parameter_pack (declarator))
	  || (declarator && declarator->parameter_pack_p)))
    {
      int latest_template_parm_idx = TREE_VEC_LENGTH
	(INNERMOST_TEMPLATE_PARMS (current_template_parms));

      if (latest_template_parm_idx != template_parm_idx)
	decl_specifiers.type = convert_generic_types_to_packs
	  (decl_specifiers.type,
	   template_parm_idx, latest_template_parm_idx);
    }

  if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    {
      tree type = decl_specifiers.type;

      if (type && DECL_P (type))
        type = TREE_TYPE (type);

      if (((type
	    && TREE_CODE (type) != TYPE_PACK_EXPANSION
	    && (template_parm_p || uses_parameter_packs (type)))
	   || (!type && template_parm_p))
	  && declarator_can_be_parameter_pack (declarator))
	{
	  /* Consume the `...'. */
	  cp_lexer_consume_token (parser->lexer);
	  maybe_warn_variadic_templates ();

	  /* Build a pack expansion type */
	  if (template_parm_p)
	    template_parameter_pack_p = true;
	  else if (declarator)
	    declarator->parameter_pack_p = true;
	  else
	    decl_specifiers.type = make_pack_expansion (type);
	}
    }

  /* The restriction on defining new types applies only to the type
     of the parameter, not to the default argument.  */
  parser->type_definition_forbidden_message = saved_message;

  /* If the next token is `=', then process a default argument.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
    {
      tree type = decl_specifiers.type;
      token = cp_lexer_peek_token (parser->lexer);
      if (declarator)
	declarator->init_loc = token->location;
      /* If we are defining a class, then the tokens that make up the
	 default argument must be saved and processed later.  */
      if (!template_parm_p && at_class_scope_p ()
	  && TYPE_BEING_DEFINED (current_class_type)
	  && !LAMBDA_TYPE_P (current_class_type))
	default_argument = cp_parser_cache_defarg (parser, /*nsdmi=*/false);

      /* A constrained-type-specifier may declare a type
	 template-parameter.  */
      else if (declares_constrained_type_template_parameter (type))
        default_argument
          = cp_parser_default_type_template_argument (parser);

      /* A constrained-type-specifier may declare a
	 template-template-parameter.  */
      else if (declares_constrained_template_template_parameter (type))
        default_argument
          = cp_parser_default_template_template_argument (parser);

      /* Outside of a class definition, we can just parse the
	 assignment-expression.  */
      else
	default_argument
	  = cp_parser_default_argument (parser, template_parm_p);

      if (!parser->default_arg_ok_p)
	{
	  permerror (token->location,
		     "default arguments are only "
		     "permitted for function parameters");
	}
      else if ((declarator && declarator->parameter_pack_p)
	       || template_parameter_pack_p
	       || (decl_specifiers.type
		   && PACK_EXPANSION_P (decl_specifiers.type)))
	{
	  /* Find the name of the parameter pack.  */
	  cp_declarator *id_declarator = declarator;
	  while (id_declarator && id_declarator->kind != cdk_id)
	    id_declarator = id_declarator->declarator;

	  if (id_declarator && id_declarator->kind == cdk_id)
	    error_at (declarator_token_start->location,
		      template_parm_p
		      ? G_("template parameter pack %qD "
			   "cannot have a default argument")
		      : G_("parameter pack %qD cannot have "
			   "a default argument"),
		      id_declarator->u.id.unqualified_name);
	  else
	    error_at (declarator_token_start->location,
		      template_parm_p
		      ? G_("template parameter pack cannot have "
			   "a default argument")
		      : G_("parameter pack cannot have a "
			   "default argument"));

	  default_argument = NULL_TREE;
	}
    }
  else
    default_argument = NULL_TREE;

  if (default_argument)
    STRIP_ANY_LOCATION_WRAPPER (default_argument);

  /* Generate a location for the parameter, ranging from the start of the
     initial token to the end of the final token (using input_location for
     the latter, set up by cp_lexer_set_source_position_from_token when
     consuming tokens).

     If we have a identifier, then use it for the caret location, e.g.

       extern int callee (int one, int (*two)(int, int), float three);
                                   ~~~~~~^~~~~~~~~~~~~~

     otherwise, reuse the start location for the caret location e.g.:

       extern int callee (int one, int (*)(int, int), float three);
                                   ^~~~~~~~~~~~~~~~~

  */
  location_t caret_loc = (declarator && declarator->id_loc != UNKNOWN_LOCATION
			  ? declarator->id_loc
			  : decl_spec_token_start->location);
  location_t param_loc = make_location (caret_loc,
					decl_spec_token_start->location,
					input_location);

  return make_parameter_declarator (&decl_specifiers,
				    declarator,
				    default_argument,
				    param_loc,
				    template_parameter_pack_p);
}

/* Parse a default argument and return it.

   TEMPLATE_PARM_P is true if this is a default argument for a
   non-type template parameter.  */
static tree
cp_parser_default_argument (cp_parser *parser, bool template_parm_p)
{
  tree default_argument = NULL_TREE;
  bool saved_greater_than_is_operator_p;
  unsigned char saved_local_variables_forbidden_p;
  bool non_constant_p, is_direct_init;

  /* Make sure that PARSER->GREATER_THAN_IS_OPERATOR_P is
     set correctly.  */
  saved_greater_than_is_operator_p = parser->greater_than_is_operator_p;
  parser->greater_than_is_operator_p = !template_parm_p;
  auto odsd = make_temp_override (parser->omp_declare_simd, NULL);
  auto ord = make_temp_override (parser->oacc_routine, NULL);
  auto oafp = make_temp_override (parser->omp_attrs_forbidden_p, false);

  /* Local variable names (and the `this' keyword) may not
     appear in a default argument.  */
  saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
  parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;
  /* Parse the assignment-expression.  */
  if (template_parm_p)
    push_deferring_access_checks (dk_no_deferred);
  tree saved_class_ptr = NULL_TREE;
  tree saved_class_ref = NULL_TREE;
  /* The "this" pointer is not valid in a default argument.  */
  if (cfun)
    {
      saved_class_ptr = current_class_ptr;
      cp_function_chain->x_current_class_ptr = NULL_TREE;
      saved_class_ref = current_class_ref;
      cp_function_chain->x_current_class_ref = NULL_TREE;
    }
  default_argument
    = cp_parser_initializer (parser, &is_direct_init, &non_constant_p);
  /* Restore the "this" pointer.  */
  if (cfun)
    {
      cp_function_chain->x_current_class_ptr = saved_class_ptr;
      cp_function_chain->x_current_class_ref = saved_class_ref;
    }
  if (BRACE_ENCLOSED_INITIALIZER_P (default_argument))
    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
  if (template_parm_p)
    pop_deferring_access_checks ();
  parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
  parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;

  return default_argument;
}

/* Parse a function-body.

   function-body:
     compound_statement  */

static void
cp_parser_function_body (cp_parser *parser, bool in_function_try_block)
{
  cp_parser_compound_statement (parser, NULL, (in_function_try_block
					       ? BCS_TRY_BLOCK : BCS_NORMAL),
				true);
}

/* Parse a ctor-initializer-opt followed by a function-body.  Return
   true if a ctor-initializer was present.  When IN_FUNCTION_TRY_BLOCK
   is true we are parsing a function-try-block.  */

static void
cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
						  bool in_function_try_block)
{
  tree body, list;
  const bool check_body_p
     = (DECL_CONSTRUCTOR_P (current_function_decl)
	&& DECL_DECLARED_CONSTEXPR_P (current_function_decl));
  tree last = NULL;

  if (in_function_try_block
      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
      && cxx_dialect < cxx20)
    {
      if (DECL_CONSTRUCTOR_P (current_function_decl))
	pedwarn (input_location, OPT_Wc__20_extensions,
		 "function-try-block body of %<constexpr%> constructor only "
		 "available with %<-std=c++20%> or %<-std=gnu++20%>");
      else
	pedwarn (input_location, OPT_Wc__20_extensions,
		 "function-try-block body of %<constexpr%> function only "
		 "available with %<-std=c++20%> or %<-std=gnu++20%>");
    }

  /* Begin the function body.  */
  body = begin_function_body ();
  /* Parse the optional ctor-initializer.  */
  cp_parser_ctor_initializer_opt (parser);

  /* If we're parsing a constexpr constructor definition, we need
     to check that the constructor body is indeed empty.  However,
     before we get to cp_parser_function_body lot of junk has been
     generated, so we can't just check that we have an empty block.
     Rather we take a snapshot of the outermost block, and check whether
     cp_parser_function_body changed its state.  */
  if (check_body_p)
    {
      list = cur_stmt_list;
      if (STATEMENT_LIST_TAIL (list))
	last = STATEMENT_LIST_TAIL (list)->stmt;
    }
  /* Parse the function-body.  */
  cp_parser_function_body (parser, in_function_try_block);
  if (check_body_p)
    check_constexpr_ctor_body (last, list, /*complain=*/true);
  /* Finish the function body.  */
  finish_function_body (body);
}

/* Parse an initializer.

   initializer:
     = initializer-clause
     ( expression-list )

   Returns an expression representing the initializer.  If no
   initializer is present, NULL_TREE is returned.

   *IS_DIRECT_INIT is set to FALSE if the `= initializer-clause'
   production is used, and TRUE otherwise.  *IS_DIRECT_INIT is
   set to TRUE if there is no initializer present.  If there is an
   initializer, and it is not a constant-expression, *NON_CONSTANT_P
   is set to true; otherwise it is set to false.  */

static tree
cp_parser_initializer (cp_parser* parser, bool* is_direct_init,
		       bool* non_constant_p, bool subexpression_p)
{
  cp_token *token;
  tree init;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* Let our caller know whether or not this initializer was
     parenthesized.  */
  *is_direct_init = (token->type != CPP_EQ);
  /* Assume that the initializer is constant.  */
  *non_constant_p = false;

  if (token->type == CPP_EQ)
    {
      /* Consume the `='.  */
      cp_lexer_consume_token (parser->lexer);
      /* Parse the initializer-clause.  */
      init = cp_parser_initializer_clause (parser, non_constant_p);
    }
  else if (token->type == CPP_OPEN_PAREN)
    {
      vec<tree, va_gc> *vec;
      vec = cp_parser_parenthesized_expression_list (parser, non_attr,
						     /*cast_p=*/false,
						     /*allow_expansion_p=*/true,
						     non_constant_p);
      if (vec == NULL)
	return error_mark_node;
      init = build_tree_list_vec (vec);
      release_tree_vector (vec);
    }
  else if (token->type == CPP_OPEN_BRACE)
    {
      cp_lexer_set_source_position (parser->lexer);
      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
      init = cp_parser_braced_list (parser, non_constant_p);
      CONSTRUCTOR_IS_DIRECT_INIT (init) = 1;
    }
  else
    {
      /* Anything else is an error.  */
      cp_parser_error (parser, "expected initializer");
      init = error_mark_node;
    }

  if (!subexpression_p && check_for_bare_parameter_packs (init))
    init = error_mark_node;

  return init;
}

/* Parse an initializer-clause.

   initializer-clause:
     assignment-expression
     braced-init-list

   Returns an expression representing the initializer.

   If the `assignment-expression' production is used the value
   returned is simply a representation for the expression.

   Otherwise, calls cp_parser_braced_list.  */

static cp_expr
cp_parser_initializer_clause (cp_parser* parser, bool* non_constant_p)
{
  cp_expr initializer;

  /* Assume the expression is constant.  */
  *non_constant_p = false;

  /* If it is not a `{', then we are looking at an
     assignment-expression.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
    {
      initializer
	= cp_parser_constant_expression (parser,
					/*allow_non_constant_p=*/2,
					non_constant_p);
    }
  else
    initializer = cp_parser_braced_list (parser, non_constant_p);

  return initializer;
}

/* Parse a brace-enclosed initializer list.

   braced-init-list:
     { initializer-list , [opt] }
     { designated-initializer-list , [opt] }
     { }

   Returns a CONSTRUCTOR.  The CONSTRUCTOR_ELTS will be
   the elements of the initializer-list (or NULL, if the last
   production is used).  The TREE_TYPE for the CONSTRUCTOR will be
   NULL_TREE.  There is no way to detect whether or not the optional
   trailing `,' was provided.  NON_CONSTANT_P is as for
   cp_parser_initializer.  */

static cp_expr
cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
{
  tree initializer;
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  /* Consume the `{' token.  */
  matching_braces braces;
  braces.require_open (parser);
  /* Create a CONSTRUCTOR to represent the braced-initializer.  */
  initializer = make_node (CONSTRUCTOR);
  /* If it's not a `}', then there is a non-trivial initializer.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
    {
      bool designated;
      /* Parse the initializer list.  */
      CONSTRUCTOR_ELTS (initializer)
	= cp_parser_initializer_list (parser, non_constant_p, &designated);
      CONSTRUCTOR_IS_DESIGNATED_INIT (initializer) = designated;
      /* A trailing `,' token is allowed.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
    }
  else
    *non_constant_p = false;
  /* Now, there should be a trailing `}'.  */
  location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
  braces.require_close (parser);
  TREE_TYPE (initializer) = init_list_type_node;
  recompute_constructor_flags (initializer);

  cp_expr result (initializer);
  /* Build a location of the form:
       { ... }
       ^~~~~~~
     with caret==start at the open brace, finish at the close brace.  */
  location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
  result.set_location (combined_loc);
  return result;
}

/* Consume tokens up to, but not including, the next non-nested closing `]'.
   Returns true iff we found a closing `]'.  */

static bool
cp_parser_skip_up_to_closing_square_bracket (cp_parser *parser)
{
  unsigned square_depth = 0;

  while (true)
    {
      cp_token * token = cp_lexer_peek_token (parser->lexer);

      switch (token->type)
	{
	case CPP_PRAGMA_EOL:
	  if (!parser->lexer->in_pragma)
	    break;
	  /* FALLTHRU */

	case CPP_EOF:
	  /* If we've run out of tokens, then there is no closing `]'.  */
	  return false;

        case CPP_OPEN_SQUARE:
          ++square_depth;
          break;

        case CPP_CLOSE_SQUARE:
	  if (!square_depth--)
	    return true;
	  break;

	default:
	  break;
	}

      /* Consume the current token, skipping it.  */
      cp_lexer_consume_token (parser->lexer);
    }
}

/* Consume tokens up to, and including, the next non-nested closing `]'.
   Returns true iff we found a closing `]'.  */

static bool
cp_parser_skip_to_closing_square_bracket (cp_parser *parser)
{
  bool found = cp_parser_skip_up_to_closing_square_bracket (parser);
  if (found)
    cp_lexer_consume_token (parser->lexer);
  return found;
}

/* Return true if we are looking at an array-designator, false otherwise.  */

static bool
cp_parser_array_designator_p (cp_parser *parser)
{
  /* Consume the `['.  */
  cp_lexer_consume_token (parser->lexer);

  cp_lexer_save_tokens (parser->lexer);

  /* Skip tokens until the next token is a closing square bracket.
     If we find the closing `]', and the next token is a `=', then
     we are looking at an array designator.  */
  bool array_designator_p
    = (cp_parser_skip_to_closing_square_bracket (parser)
       && cp_lexer_next_token_is (parser->lexer, CPP_EQ));

  /* Roll back the tokens we skipped.  */
  cp_lexer_rollback_tokens (parser->lexer);

  return array_designator_p;
}

/* Parse an initializer-list.

   initializer-list:
     initializer-clause ... [opt]
     initializer-list , initializer-clause ... [opt]

   C++20 Extension:

   designated-initializer-list:
     designated-initializer-clause
     designated-initializer-list , designated-initializer-clause

   designated-initializer-clause:
     designator brace-or-equal-initializer

   designator:
     . identifier

   GNU Extension:

   initializer-list:
     designation initializer-clause ...[opt]
     initializer-list , designation initializer-clause ...[opt]

   designation:
     . identifier =
     identifier :
     [ constant-expression ] =

   Returns a vec of constructor_elt.  The VALUE of each elt is an expression
   for the initializer.  If the INDEX of the elt is non-NULL, it is the
   IDENTIFIER_NODE naming the field to initialize.  NON_CONSTANT_P is
   as for cp_parser_initializer.  Set *DESIGNATED to a boolean whether there
   are any designators.  */

static vec<constructor_elt, va_gc> *
cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
			    bool *designated)
{
  vec<constructor_elt, va_gc> *v = NULL;
  bool first_p = true;
  tree first_designator = NULL_TREE;

  /* Assume all of the expressions are constant.  */
  *non_constant_p = false;

  unsigned nelts = 0;
  int suppress = suppress_location_wrappers;

  /* Parse the rest of the list.  */
  while (true)
    {
      cp_token *token;
      tree designator;
      tree initializer;
      bool clause_non_constant_p;
      location_t loc = cp_lexer_peek_token (parser->lexer)->location;

      /* Handle the C++20 syntax, '. id ='.  */
      if ((cxx_dialect >= cxx20
	   || cp_parser_allow_gnu_extensions_p (parser))
	  && cp_lexer_next_token_is (parser->lexer, CPP_DOT)
	  && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME
	  && (cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_EQ
	      || (cp_lexer_peek_nth_token (parser->lexer, 3)->type
		  == CPP_OPEN_BRACE)))
	{
	  if (pedantic && cxx_dialect < cxx20)
	    pedwarn (loc, OPT_Wc__20_extensions,
		     "C++ designated initializers only available with "
		     "%<-std=c++20%> or %<-std=gnu++20%>");
	  /* Consume the `.'.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Consume the identifier.  */
	  designator = cp_lexer_consume_token (parser->lexer)->u.value;
	  if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	    /* Consume the `='.  */
	    cp_lexer_consume_token (parser->lexer);
	}
      /* Also, if the next token is an identifier and the following one is a
	 colon, we are looking at the GNU designated-initializer
	 syntax.  */
      else if (cp_parser_allow_gnu_extensions_p (parser)
	       && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	       && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
		   == CPP_COLON))
	{
	  /* Warn the user that they are using an extension.  */
	  pedwarn (loc, OPT_Wpedantic,
		   "ISO C++ does not allow GNU designated initializers");
	  /* Consume the identifier.  */
	  designator = cp_lexer_consume_token (parser->lexer)->u.value;
	  /* Consume the `:'.  */
	  cp_lexer_consume_token (parser->lexer);
	}
      /* Also handle C99 array designators, '[ const ] ='.  */
      else if (cp_parser_allow_gnu_extensions_p (parser)
	       && !c_dialect_objc ()
	       && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
	{
	  /* In C++11, [ could start a lambda-introducer.  */
	  bool non_const = false;

	  cp_parser_parse_tentatively (parser);

	  if (!cp_parser_array_designator_p (parser))
	    {
	      cp_parser_simulate_error (parser);
	      designator = NULL_TREE;
	    }
	  else
	    {
	      designator = cp_parser_constant_expression (parser, true,
							  &non_const);
	      cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
	      cp_parser_require (parser, CPP_EQ, RT_EQ);
	    }

	  if (!cp_parser_parse_definitely (parser))
	    designator = NULL_TREE;
	  else if (non_const
		   && (!require_potential_rvalue_constant_expression
		       (designator)))
	    designator = NULL_TREE;
	  if (designator)
	    /* Warn the user that they are using an extension.  */
	    pedwarn (loc, OPT_Wpedantic,
		     "ISO C++ does not allow C99 designated initializers");
	}
      else
	designator = NULL_TREE;

      if (first_p)
	{
	  first_designator = designator;
	  first_p = false;
	}
      else if (cxx_dialect >= cxx20
	       && first_designator != error_mark_node
	       && (!first_designator != !designator))
	{
	  error_at (loc, "either all initializer clauses should be designated "
			 "or none of them should be");
	  first_designator = error_mark_node;
	}
      else if (cxx_dialect < cxx20 && !first_designator)
	first_designator = designator;

      /* Parse the initializer.  */
      initializer = cp_parser_initializer_clause (parser,
						  &clause_non_constant_p);
      /* If any clause is non-constant, so is the entire initializer.  */
      if (clause_non_constant_p)
	*non_constant_p = true;

      /* If we have an ellipsis, this is an initializer pack
	 expansion.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
        {
	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

          /* Consume the `...'.  */
          cp_lexer_consume_token (parser->lexer);

	  if (designator && cxx_dialect >= cxx20)
	    error_at (loc,
		      "%<...%> not allowed in designated initializer list");

	  /* Turn the initializer into an initializer expansion.  */
	  initializer = make_pack_expansion (initializer);
        }

      /* Add it to the vector.  */
      CONSTRUCTOR_APPEND_ELT (v, designator, initializer);

      /* If the next token is not a comma, we have reached the end of
	 the list.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;

      /* Peek at the next token.  */
      token = cp_lexer_peek_nth_token (parser->lexer, 2);
      /* If the next token is a `}', then we're still done.  An
	 initializer-clause can have a trailing `,' after the
	 initializer-list and before the closing `}'.  */
      if (token->type == CPP_CLOSE_BRACE)
	break;

      /* Suppress location wrappers in a long initializer to save memory
	 (14179).  The cutoff is chosen arbitrarily.  */
      const unsigned loc_max = 256;
      unsigned incr = 1;
      if (TREE_CODE (initializer) == CONSTRUCTOR)
	/* Look one level down because it's easy.  Looking deeper would require
	   passing down a nelts pointer, and I don't think multi-level massive
	   initializers are common enough to justify this.  */
	incr = CONSTRUCTOR_NELTS (initializer);
      nelts += incr;
      if (nelts >= loc_max && (nelts - incr) < loc_max)
	++suppress_location_wrappers;

      /* Consume the `,' token.  */
      cp_lexer_consume_token (parser->lexer);
    }

  /* The same identifier shall not appear in multiple designators
     of a designated-initializer-list.  */
  if (first_designator)
    {
      unsigned int i;
      tree designator, val;
      FOR_EACH_CONSTRUCTOR_ELT (v, i, designator, val)
	if (designator && TREE_CODE (designator) == IDENTIFIER_NODE)
	  {
	    if (IDENTIFIER_MARKED (designator))
	      {
		error_at (cp_expr_loc_or_input_loc (val),
			  "%<.%s%> designator used multiple times in "
			  "the same initializer list",
			  IDENTIFIER_POINTER (designator));
		(*v)[i].index = error_mark_node;
	      }
	    else
	      IDENTIFIER_MARKED (designator) = 1;
	  }
      FOR_EACH_CONSTRUCTOR_ELT (v, i, designator, val)
	if (designator && TREE_CODE (designator) == IDENTIFIER_NODE)
	  IDENTIFIER_MARKED (designator) = 0;
    }

  suppress_location_wrappers = suppress;

  *designated = first_designator != NULL_TREE;
  return v;
}

/* Classes [gram.class] */

/* Parse a class-name.

   class-name:
     identifier
     template-id

   TYPENAME_KEYWORD_P is true iff the `typename' keyword has been used
   to indicate that names looked up in dependent types should be
   assumed to be types.  TEMPLATE_KEYWORD_P is true iff the `template'
   keyword has been used to indicate that the name that appears next
   is a template.  TAG_TYPE indicates the explicit tag given before
   the type name, if any.  If CHECK_DEPENDENCY_P is FALSE, names are
   looked up in dependent scopes.  If CLASS_HEAD_P is TRUE, this class
   is the class being defined in a class-head.  If ENUM_OK is TRUE,
   enum-names are also accepted.

   Returns the TYPE_DECL representing the class.  */

static tree
cp_parser_class_name (cp_parser *parser,
		      bool typename_keyword_p,
		      bool template_keyword_p,
		      enum tag_types tag_type,
		      bool check_dependency_p,
		      bool class_head_p,
		      bool is_declaration,
		      bool enum_ok)
{
  tree decl;
  tree identifier = NULL_TREE;

  /* All class-names start with an identifier.  */
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  if (token->type != CPP_NAME && token->type != CPP_TEMPLATE_ID)
    {
      cp_parser_error (parser, "expected class-name");
      return error_mark_node;
    }

  /* PARSER->SCOPE can be cleared when parsing the template-arguments
     to a template-id, so we save it here.  Consider object scope too,
     so that make_typename_type below can use it (cp_parser_template_name
     considers object scope also).  This may happen with code like

       p->template A<T>::a()

      where we first want to look up A<T>::a in the class of the object
      expression, as per [basic.lookup.classref].  */
  tree scope = parser->scope ? parser->scope : parser->context->object_type;
  /* This only checks parser->scope to avoid duplicate errors; if
     ->object_type is erroneous, go on to give a parse error.  */
  if (parser->scope == error_mark_node)
    return error_mark_node;

  /* Any name names a type if we're following the `typename' keyword
     in a qualified name where the enclosing scope is type-dependent.  */
  const bool typename_p = (typename_keyword_p
			   && parser->scope
			   && TYPE_P (parser->scope)
			   && dependent_scope_p (parser->scope));
  /* Handle the common case (an identifier, but not a template-id)
     efficiently.  */
  if (token->type == CPP_NAME
      && !cp_parser_nth_token_starts_template_argument_list_p (parser, 2))
    {
      cp_token *identifier_token;
      bool ambiguous_p;

      /* Look for the identifier.  */
      identifier_token = cp_lexer_peek_token (parser->lexer);
      ambiguous_p = identifier_token->error_reported;
      identifier = cp_parser_identifier (parser);
      /* If the next token isn't an identifier, we are certainly not
	 looking at a class-name.  */
      if (identifier == error_mark_node)
	decl = error_mark_node;
      /* If we know this is a type-name, there's no need to look it
	 up.  */
      else if (typename_p)
	decl = identifier;
      else
	{
	  tree ambiguous_decls;
	  /* If we already know that this lookup is ambiguous, then
	     we've already issued an error message; there's no reason
	     to check again.  */
	  if (ambiguous_p)
	    {
	      cp_parser_simulate_error (parser);
	      return error_mark_node;
	    }
	  /* If the next token is a `::', then the name must be a type
	     name.

	     [basic.lookup.qual]

	     During the lookup for a name preceding the :: scope
	     resolution operator, object, function, and enumerator
	     names are ignored.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
	    tag_type = scope_type;
	  /* Look up the name.  */
	  decl = cp_parser_lookup_name (parser, identifier,
					tag_type,
					/*is_template=*/false,
					/*is_namespace=*/false,
					check_dependency_p,
					&ambiguous_decls,
					identifier_token->location);
	  if (ambiguous_decls)
	    {
	      if (cp_parser_parsing_tentatively (parser))
		cp_parser_simulate_error (parser);
	      return error_mark_node;
	    }
	}
    }
  else
    {
      /* Try a template-id.  */
      decl = cp_parser_template_id (parser, template_keyword_p,
				    check_dependency_p,
				    tag_type,
				    is_declaration);
      if (decl == error_mark_node)
	return error_mark_node;
    }

  decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);

  /* If this is a typename, create a TYPENAME_TYPE.  */
  if (typename_p && decl != error_mark_node)
    {
      decl = make_typename_type (scope, decl, typename_type,
				 /*complain=*/tf_error);
      if (decl != error_mark_node)
	decl = TYPE_NAME (decl);
    }

  decl = strip_using_decl (decl);

  /* Check to see that it is really the name of a class.  */
  if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
      && identifier_p (TREE_OPERAND (decl, 0))
      && cp_lexer_next_token_is (parser->lexer, CPP_SCOPE))
    /* Situations like this:

	 template <typename T> struct A {
	   typename T::template X<int>::I i;
	 };

       are problematic.  Is `T::template X<int>' a class-name?  The
       standard does not seem to be definitive, but there is no other
       valid interpretation of the following `::'.  Therefore, those
       names are considered class-names.  */
    {
      decl = make_typename_type (scope, decl, tag_type, tf_error);
      if (decl != error_mark_node)
	decl = TYPE_NAME (decl);
    }
  else if (TREE_CODE (decl) != TYPE_DECL
	   || TREE_TYPE (decl) == error_mark_node
	   || !(MAYBE_CLASS_TYPE_P (TREE_TYPE (decl))
		|| (enum_ok && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE))
	   /* In Objective-C 2.0, a classname followed by '.' starts a
	      dot-syntax expression, and it's not a type-name.  */
	   || (c_dialect_objc ()
	       && cp_lexer_peek_token (parser->lexer)->type == CPP_DOT
	       && objc_is_class_name (decl)))
    decl = error_mark_node;

  if (decl == error_mark_node)
    cp_parser_error (parser, "expected class-name");
  else if (identifier && !parser->scope)
    maybe_note_name_used_in_class (identifier, decl);

  return decl;
}

/* Make sure that any member-function parameters are in scope.
   For instance, a function's noexcept-specifier can use the function's
   parameters:

   struct S {
     void fn (int p) noexcept(noexcept(p));
   };

   so we need to make sure name lookup can find them.  This is used
   when we delay parsing of the noexcept-specifier.  */

static void
inject_parm_decls (tree decl)
{
  begin_scope (sk_function_parms, decl);
  tree args = DECL_ARGUMENTS (decl);

  do_push_parm_decls (decl, args, /*nonparms=*/NULL);

  if (args && is_this_parameter (args))
    {
      gcc_checking_assert (current_class_ptr == NULL_TREE);
      current_class_ref = cp_build_fold_indirect_ref (args);
      current_class_ptr = args;
    }
}

/* Undo the effects of inject_parm_decls.  */

static void
pop_injected_parms (void)
{
  pop_bindings_and_leave_scope ();
  current_class_ptr = current_class_ref = NULL_TREE;
}

/* Parse a class-specifier.

   class-specifier:
     class-head { member-specification [opt] }

   Returns the TREE_TYPE representing the class.  */

tree
cp_parser_class_specifier (cp_parser* parser)
{
  auto_timevar tv (TV_PARSE_STRUCT);

  tree type;
  tree attributes = NULL_TREE;
  bool nested_name_specifier_p;
  unsigned saved_num_template_parameter_lists;
  bool saved_in_function_body;
  unsigned char in_statement;
  bool in_switch_statement_p;
  bool saved_in_unbraced_linkage_specification_p;
  tree old_scope = NULL_TREE;
  tree scope = NULL_TREE;
  cp_token *closing_brace;

  push_deferring_access_checks (dk_no_deferred);

  /* Parse the class-head.  */
  type = cp_parser_class_head (parser,
			       &nested_name_specifier_p);
  /* If the class-head was a semantic disaster, skip the entire body
     of the class.  */
  if (!type)
    {
      cp_parser_skip_to_end_of_block_or_statement (parser);
      pop_deferring_access_checks ();
      return error_mark_node;
    }

  /* Look for the `{'.  */
  matching_braces braces;
  if (!braces.require_open (parser))
    {
      pop_deferring_access_checks ();
      return error_mark_node;
    }

  cp_ensure_no_omp_declare_simd (parser);
  cp_ensure_no_oacc_routine (parser);

  /* Issue an error message if type-definitions are forbidden here.  */
  bool type_definition_ok_p = cp_parser_check_type_definition (parser);
  /* Remember that we are defining one more class.  */
  ++parser->num_classes_being_defined;
  /* Inside the class, surrounding template-parameter-lists do not
     apply.  */
  saved_num_template_parameter_lists
    = parser->num_template_parameter_lists;
  parser->num_template_parameter_lists = 0;
  /* We are not in a function body.  */
  saved_in_function_body = parser->in_function_body;
  parser->in_function_body = false;
  /* Or in a loop.  */
  in_statement = parser->in_statement;
  parser->in_statement = 0;
  /* Or in a switch.  */
  in_switch_statement_p = parser->in_switch_statement_p;
  parser->in_switch_statement_p = false;
  /* We are not immediately inside an extern "lang" block.  */
  saved_in_unbraced_linkage_specification_p
    = parser->in_unbraced_linkage_specification_p;
  parser->in_unbraced_linkage_specification_p = false;

  /* Start the class.  */
  if (nested_name_specifier_p)
    {
      scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
      /* SCOPE must be a scope nested inside current scope.  */
      if (is_nested_namespace (current_namespace,
			       decl_namespace_context (scope)))
	old_scope = push_inner_scope (scope);
      else
	nested_name_specifier_p = false;
    }
  type = begin_class_definition (type);

  if (type == error_mark_node)
    /* If the type is erroneous, skip the entire body of the class.  */
    cp_parser_skip_to_closing_brace (parser);
  else
    /* Parse the member-specification.  */
    cp_parser_member_specification_opt (parser);

  /* Look for the trailing `}'.  */
  closing_brace = braces.require_close (parser);
  /* Look for trailing attributes to apply to this class.  */
  if (cp_parser_allow_gnu_extensions_p (parser))
    attributes = cp_parser_gnu_attributes_opt (parser);
  if (type != error_mark_node)
    type = finish_struct (type, attributes);
  if (nested_name_specifier_p)
    pop_inner_scope (old_scope, scope);

  /* We've finished a type definition.  Check for the common syntax
     error of forgetting a semicolon after the definition.  We need to
     be careful, as we can't just check for not-a-semicolon and be done
     with it; the user might have typed:

     class X { } c = ...;
     class X { } *p = ...;

     and so forth.  Instead, enumerate all the possible tokens that
     might follow this production; if we don't see one of them, then
     complain and silently insert the semicolon.  */
  {
    cp_token *token = cp_lexer_peek_token (parser->lexer);
    bool want_semicolon = true;

    if (cp_next_tokens_can_be_std_attribute_p (parser))
      /* Don't try to parse c++11 attributes here.  As per the
	 grammar, that should be a task for
	 cp_parser_decl_specifier_seq.  */
      want_semicolon = false;

    switch (token->type)
      {
      case CPP_NAME:
      case CPP_SEMICOLON:
      case CPP_MULT:
      case CPP_AND:
      case CPP_OPEN_PAREN:
      case CPP_CLOSE_PAREN:
      case CPP_COMMA:
      case CPP_SCOPE:
        want_semicolon = false;
        break;

        /* While it's legal for type qualifiers and storage class
           specifiers to follow type definitions in the grammar, only
           compiler testsuites contain code like that.  Assume that if
           we see such code, then what we're really seeing is a case
           like:

           class X { }
           const <type> var = ...;

           or

           class Y { }
           static <type> func (...) ...

           i.e. the qualifier or specifier applies to the next
           declaration.  To do so, however, we need to look ahead one
           more token to see if *that* token is a type specifier.

	   This code could be improved to handle:

	   class Z { }
	   static const <type> var = ...;  */
      case CPP_KEYWORD:
	if (keyword_is_decl_specifier (token->keyword))
	  {
	    cp_token *lookahead = cp_lexer_peek_nth_token (parser->lexer, 2);

	    /* Handling user-defined types here would be nice, but very
	       tricky.  */
	    want_semicolon
	      = (lookahead->type == CPP_KEYWORD
		 && keyword_begins_type_specifier (lookahead->keyword));
	  }
	break;
      default:
	break;
      }

    /* If we don't have a type, then something is very wrong and we
       shouldn't try to do anything clever.  Likewise for not seeing the
       closing brace.  */
    if (closing_brace && TYPE_P (type) && want_semicolon)
      {
	/* Locate the closing brace.  */
	cp_token_position prev
	  = cp_lexer_previous_token_position (parser->lexer);
	cp_token *prev_token = cp_lexer_token_at (parser->lexer, prev);
	location_t loc = prev_token->location;

	/* We want to suggest insertion of a ';' immediately *after* the
	   closing brace, so, if we can, offset the location by 1 column.  */
	location_t next_loc = loc;
	if (!linemap_location_from_macro_expansion_p (line_table, loc))
	  next_loc = linemap_position_for_loc_and_offset (line_table, loc, 1);

	rich_location richloc (line_table, next_loc);

	/* If we successfully offset the location, suggest the fix-it.  */
	if (next_loc != loc)
	  richloc.add_fixit_insert_before (next_loc, ";");

	if (CLASSTYPE_DECLARED_CLASS (type))
	  error_at (&richloc,
		    "expected %<;%> after class definition");
	else if (TREE_CODE (type) == RECORD_TYPE)
	  error_at (&richloc,
		    "expected %<;%> after struct definition");
	else if (TREE_CODE (type) == UNION_TYPE)
	  error_at (&richloc,
		    "expected %<;%> after union definition");
	else
	  gcc_unreachable ();

	/* Unget one token and smash it to look as though we encountered
	   a semicolon in the input stream.  */
	cp_lexer_set_token_position (parser->lexer, prev);
	token = cp_lexer_peek_token (parser->lexer);
	token->type = CPP_SEMICOLON;
	token->keyword = RID_MAX;
      }
  }

  /* If this class is not itself within the scope of another class,
     then we need to parse the bodies of all of the queued function
     definitions.  Note that the queued functions defined in a class
     are not always processed immediately following the
     class-specifier for that class.  Consider:

       struct A {
	 struct B { void f() { sizeof (A); } };
       };

     If `f' were processed before the processing of `A' were
     completed, there would be no way to compute the size of `A'.
     Note that the nesting we are interested in here is lexical --
     not the semantic nesting given by TYPE_CONTEXT.  In particular,
     for:

       struct A { struct B; };
       struct A::B { void f() { } };

     there is no need to delay the parsing of `A::B::f'.  */
  if (--parser->num_classes_being_defined == 0)
    {
      tree decl;
      tree class_type = NULL_TREE;
      tree pushed_scope = NULL_TREE;
      unsigned ix;
      cp_default_arg_entry *e;

      if (!type_definition_ok_p || any_erroneous_template_args_p (type))
	{
	  /* Skip default arguments, NSDMIs, etc, in order to improve
	     error recovery (c++/71169, c++/71832).  */
	  vec_safe_truncate (unparsed_funs_with_default_args, 0);
	  vec_safe_truncate (unparsed_nsdmis, 0);
	  vec_safe_truncate (unparsed_funs_with_definitions, 0);
	}

      /* In a first pass, parse default arguments to the functions.
	 Then, in a second pass, parse the bodies of the functions.
	 This two-phased approach handles cases like:

	    struct S {
	      void f() { g(); }
	      void g(int i = 3);
	    };

	 */
      FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_default_args, ix, e)
	{
	  decl = e->decl;
	  /* If there are default arguments that have not yet been processed,
	     take care of them now.  */
	  if (class_type != e->class_type)
	    {
	      if (pushed_scope)
		pop_scope (pushed_scope);
	      class_type = e->class_type;
	      pushed_scope = push_scope (class_type);
	    }
	  /* Make sure that any template parameters are in scope.  */
	  maybe_begin_member_template_processing (decl);
	  /* Parse the default argument expressions.  */
	  cp_parser_late_parsing_default_args (parser, decl);
	  /* Remove any template parameters from the symbol table.  */
	  maybe_end_member_template_processing ();
	}
      vec_safe_truncate (unparsed_funs_with_default_args, 0);

      /* If there are noexcept-specifiers that have not yet been processed,
	 take care of them now.  Do this before processing NSDMIs as they
	 may depend on noexcept-specifiers already having been processed.  */
      tree save_ccp = current_class_ptr;
      tree save_ccr = current_class_ref;
      FOR_EACH_VEC_SAFE_ELT (unparsed_noexcepts, ix, decl)
	{
	  tree ctx = DECL_CONTEXT (decl);
	  if (class_type != ctx)
	    {
	      if (pushed_scope)
		pop_scope (pushed_scope);
	      class_type = ctx;
	      pushed_scope = push_scope (class_type);
	    }

	  tree def_parse = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
	  def_parse = TREE_PURPOSE (def_parse);

	  /* Make sure that any template parameters are in scope.  */
	  maybe_begin_member_template_processing (decl);

	  /* Make sure that any member-function parameters are in scope.
	     This function doesn't expect ccp to be set.  */
	  current_class_ptr = current_class_ref = NULL_TREE;
	  inject_parm_decls (decl);

	  /* 'this' is not allowed in static member functions.  */
	  unsigned char local_variables_forbidden_p
	    = parser->local_variables_forbidden_p;
	  if (DECL_THIS_STATIC (decl))
	    parser->local_variables_forbidden_p |= THIS_FORBIDDEN;

	  /* Now we can parse the noexcept-specifier.  */
	  tree spec = cp_parser_late_noexcept_specifier (parser, def_parse);

	  if (spec == error_mark_node)
	    spec = NULL_TREE;

	  /* Update the fn's type directly -- it might have escaped
	     beyond this decl :(  */
	  fixup_deferred_exception_variants (TREE_TYPE (decl), spec);
	  /* Update any instantiations we've already created.  We must
	     keep the new noexcept-specifier wrapped in a DEFERRED_NOEXCEPT
	     so that maybe_instantiate_noexcept can tsubst the NOEXCEPT_EXPR
	     in the pattern.  */
	  for (tree i : DEFPARSE_INSTANTIATIONS (def_parse))
	    DEFERRED_NOEXCEPT_PATTERN (TREE_PURPOSE (i))
	      = spec ? TREE_PURPOSE (spec) : error_mark_node;

	  /* Restore the state of local_variables_forbidden_p.  */
	  parser->local_variables_forbidden_p = local_variables_forbidden_p;

	  /* The finish_struct call above performed various override checking,
	     but it skipped unparsed noexcept-specifier operands.  Now that we
	     have resolved them, check again.  */
	  noexcept_override_late_checks (type, decl);

	  /* Remove any member-function parameters from the symbol table.  */
	  pop_injected_parms ();

	  /* Remove any template parameters from the symbol table.  */
	  maybe_end_member_template_processing ();
	}
      vec_safe_truncate (unparsed_noexcepts, 0);

      /* Now parse any NSDMIs.  */
      FOR_EACH_VEC_SAFE_ELT (unparsed_nsdmis, ix, decl)
	{
	  if (class_type != DECL_CONTEXT (decl))
	    {
	      if (pushed_scope)
		pop_scope (pushed_scope);
	      class_type = DECL_CONTEXT (decl);
	      pushed_scope = push_scope (class_type);
	    }
	  inject_this_parameter (class_type, TYPE_UNQUALIFIED);
	  cp_parser_late_parsing_nsdmi (parser, decl);
	}
      vec_safe_truncate (unparsed_nsdmis, 0);

      /* Now contract attributes.  */
      FOR_EACH_VEC_SAFE_ELT (unparsed_contracts, ix, decl)
	{
	  tree ctx = DECL_CONTEXT (decl);
	  if (class_type != ctx)
	    {
	      if (pushed_scope)
		pop_scope (pushed_scope);
	      class_type = ctx;
	      pushed_scope = push_scope (class_type);
	    }

	  temp_override<tree> cfd(current_function_decl, decl);

	  /* Make sure that any template parameters are in scope.  */
	  maybe_begin_member_template_processing (decl);

	  /* Make sure that any member-function parameters are in scope.
	     This function doesn't expect ccp to be set.  */
	  current_class_ptr = current_class_ref = NULL_TREE;
	  inject_parm_decls (decl);

	  /* 'this' is not allowed in static member functions.  */
	  unsigned char local_variables_forbidden_p
	    = parser->local_variables_forbidden_p;
	  if (DECL_THIS_STATIC (decl))
	    parser->local_variables_forbidden_p |= THIS_FORBIDDEN;

	  /* Now we can parse contract conditions.  */
	  for (tree a = DECL_ATTRIBUTES (decl); a; a = TREE_CHAIN (a))
	    {
	      if (cxx_contract_attribute_p (a))
		cp_parser_late_contract_condition (parser, decl, a);
	    }

	  /* Restore the state of local_variables_forbidden_p.  */
	  parser->local_variables_forbidden_p = local_variables_forbidden_p;

	  /* Remove any member-function parameters from the symbol table.  */
	  pop_injected_parms ();

	  /* Remove any template parameters from the symbol table.  */
	  maybe_end_member_template_processing ();

	  /* Perform any deferred contract matching.  */
	  match_deferred_contracts (decl);
	}
      vec_safe_truncate (unparsed_contracts, 0);

      current_class_ptr = save_ccp;
      current_class_ref = save_ccr;
      if (pushed_scope)
	pop_scope (pushed_scope);

      /* Now parse the body of the functions.  */
      if (flag_openmp)
	{
	  /* OpenMP UDRs need to be parsed before all other functions.  */
	  FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
	    if (DECL_OMP_DECLARE_REDUCTION_P (decl))
	      cp_parser_late_parsing_for_member (parser, decl);
	  FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
	    if (!DECL_OMP_DECLARE_REDUCTION_P (decl))
	      cp_parser_late_parsing_for_member (parser, decl);
	}
      else
	FOR_EACH_VEC_SAFE_ELT (unparsed_funs_with_definitions, ix, decl)
	  cp_parser_late_parsing_for_member (parser, decl);
      vec_safe_truncate (unparsed_funs_with_definitions, 0);
    }

  /* Put back any saved access checks.  */
  pop_deferring_access_checks ();

  /* Restore saved state.  */
  parser->in_switch_statement_p = in_switch_statement_p;
  parser->in_statement = in_statement;
  parser->in_function_body = saved_in_function_body;
  parser->num_template_parameter_lists
    = saved_num_template_parameter_lists;
  parser->in_unbraced_linkage_specification_p
    = saved_in_unbraced_linkage_specification_p;

  return type;
}

/* Parse a class-head.

   class-head:
     class-key identifier [opt] base-clause [opt]
     class-key nested-name-specifier identifier class-virt-specifier [opt] base-clause [opt]
     class-key nested-name-specifier [opt] template-id
       base-clause [opt]

   class-virt-specifier:
     final

   GNU Extensions:
     class-key attributes identifier [opt] base-clause [opt]
     class-key attributes nested-name-specifier identifier base-clause [opt]
     class-key attributes nested-name-specifier [opt] template-id
       base-clause [opt]

   Upon return BASES is initialized to the list of base classes (or
   NULL, if there are none) in the same form returned by
   cp_parser_base_clause.

   Returns the TYPE of the indicated class.  Sets
   *NESTED_NAME_SPECIFIER_P to TRUE iff one of the productions
   involving a nested-name-specifier was used, and FALSE otherwise.

   Returns error_mark_node if this is not a class-head.

   Returns NULL_TREE if the class-head is syntactically valid, but
   semantically invalid in a way that means we should skip the entire
   body of the class.  */

static tree
cp_parser_class_head (cp_parser* parser,
		      bool* nested_name_specifier_p)
{
  tree nested_name_specifier;
  enum tag_types class_key;
  tree id = NULL_TREE;
  tree type = NULL_TREE;
  tree attributes;
  tree bases;
  cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
  bool template_id_p = false;
  bool qualified_p = false;
  bool invalid_nested_name_p = false;
  bool invalid_explicit_specialization_p = false;
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
  tree pushed_scope = NULL_TREE;
  unsigned num_templates;
  cp_token *type_start_token = NULL, *nested_name_specifier_token_start = NULL;
  /* Assume no nested-name-specifier will be present.  */
  *nested_name_specifier_p = false;
  /* Assume no template parameter lists will be used in defining the
     type.  */
  num_templates = 0;
  parser->colon_corrects_to_scope_p = false;

  /* Look for the class-key.  */
  class_key = cp_parser_class_key (parser);
  if (class_key == none_type)
    return error_mark_node;

  location_t class_head_start_location = input_location;

  /* Parse the attributes.  */
  attributes = cp_parser_attributes_opt (parser);
  if (find_contract (attributes))
    diagnose_misapplied_contracts (attributes);

  /* If the next token is `::', that is invalid -- but sometimes
     people do try to write:

       struct ::S {};

     Handle this gracefully by accepting the extra qualifier, and then
     issuing an error about it later if this really is a
     class-head.  If it turns out just to be an elaborated type
     specifier, remain silent.  */
  if (cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false))
    qualified_p = true;

  /* It is OK to define an inaccessible class; for example:

       class A { class B; };
       class A::B {};

     So we want to ignore access when parsing the class name.
     However, we might be tentatively parsing what is really an
     elaborated-type-specifier naming a template-id, e.g.

       struct C<&D::m> c;

     In this case the tentative parse as a class-head will fail, but not
     before cp_parser_template_id splices in a CPP_TEMPLATE_ID token.
     Since dk_no_check is sticky, we must instead use dk_deferred so that
     any such CPP_TEMPLATE_ID token created during this tentative parse
     will correctly capture the access checks imposed by the template-id . */
  push_deferring_access_checks (dk_deferred);

  /* Determine the name of the class.  Begin by looking for an
     optional nested-name-specifier.  */
  nested_name_specifier_token_start = cp_lexer_peek_token (parser->lexer);
  nested_name_specifier
    = cp_parser_nested_name_specifier_opt (parser,
					   /*typename_keyword_p=*/false,
					   /*check_dependency_p=*/false,
					   /*type_p=*/true,
					   /*is_declaration=*/false);
  /* If there was a nested-name-specifier, then there *must* be an
     identifier.  */

  cp_token *bad_template_keyword = NULL;

  if (nested_name_specifier)
    {
      type_start_token = cp_lexer_peek_token (parser->lexer);
      /* Although the grammar says `identifier', it really means
	 `class-name' or `template-name'.  You are only allowed to
	 define a class that has already been declared with this
	 syntax.

	 The proposed resolution for Core Issue 180 says that wherever
	 you see `class T::X' you should treat `X' as a type-name.

	 We do not know if we will see a class-name, or a
	 template-name.  We look for a class-name first, in case the
	 class-name is a template-id; if we looked for the
	 template-name first we would stop after the template-name.  */
      cp_parser_parse_tentatively (parser);
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
	bad_template_keyword = cp_lexer_consume_token (parser->lexer);
      type = cp_parser_class_name (parser,
				   /*typename_keyword_p=*/false,
				   /*template_keyword_p=*/false,
				   class_type,
				   /*check_dependency_p=*/false,
				   /*class_head_p=*/true,
				   /*is_declaration=*/false);
      /* If that didn't work, ignore the nested-name-specifier.  */
      if (!cp_parser_parse_definitely (parser))
	{
	  invalid_nested_name_p = true;
	  type_start_token = cp_lexer_peek_token (parser->lexer);
	  id = cp_parser_identifier (parser);
	  if (id == error_mark_node)
	    id = NULL_TREE;
	}
      /* If we could not find a corresponding TYPE, treat this
	 declaration like an unqualified declaration.  */
      if (type == error_mark_node)
	nested_name_specifier = NULL_TREE;
      /* Otherwise, count the number of templates used in TYPE and its
	 containing scopes.  */
      else
	num_templates = num_template_headers_for_class (TREE_TYPE (type));
    }
  /* Otherwise, the identifier is optional.  */
  else
    {
      /* We don't know whether what comes next is a template-id,
	 an identifier, or nothing at all.  */
      cp_parser_parse_tentatively (parser);
      /* Check for a template-id.  */
      type_start_token = cp_lexer_peek_token (parser->lexer);
      id = cp_parser_template_id (parser,
				  /*template_keyword_p=*/false,
				  /*check_dependency_p=*/true,
				  class_key,
				  /*is_declaration=*/true);
      /* If that didn't work, it could still be an identifier.  */
      if (!cp_parser_parse_definitely (parser))
	{
	  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	    {
	      type_start_token = cp_lexer_peek_token (parser->lexer);
	      id = cp_parser_identifier (parser);
	    }
	  else
	    id = NULL_TREE;
	}
      else
	{
	  template_id_p = true;
	  ++num_templates;
	}
    }

  pop_deferring_access_checks ();

  if (id)
    {
      cp_parser_check_for_invalid_template_id (parser, id,
					       class_key,
                                               type_start_token->location);
    }
  virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);

  /* If it's not a `:' or a `{' then we can't really be looking at a
     class-head, since a class-head only appears as part of a
     class-specifier.  We have to detect this situation before calling
     xref_tag, since that has irreversible side-effects.  */
  if (!cp_parser_next_token_starts_class_definition_p (parser))
    {
      cp_parser_error (parser, "expected %<{%> or %<:%>");
      type = error_mark_node;
      goto out;
    }

  /* At this point, we're going ahead with the class-specifier, even
     if some other problem occurs.  */
  cp_parser_commit_to_tentative_parse (parser);
  if (virt_specifiers & VIRT_SPEC_OVERRIDE)
    {
      cp_parser_error (parser,
                       "cannot specify %<override%> for a class");
      type = error_mark_node;
      goto out;
    }
  /* Issue the error about the overly-qualified name now.  */
  if (qualified_p)
    {
      cp_parser_error (parser,
		       "global qualification of class name is invalid");
      type = error_mark_node;
      goto out;
    }
  else if (invalid_nested_name_p)
    {
      cp_parser_error (parser,
		       "qualified name does not name a class");
      type = error_mark_node;
      goto out;
    }
  else if (nested_name_specifier)
    {
      tree scope;

      if (bad_template_keyword)
	/* [temp.names]: in a qualified-id formed by a class-head-name, the
	   keyword template shall not appear at the top level.  */
	pedwarn (bad_template_keyword->location, OPT_Wpedantic,
		 "keyword %<template%> not allowed in class-head-name");

      /* Reject typedef-names in class heads.  */
      if (!DECL_IMPLICIT_TYPEDEF_P (type))
	{
	  error_at (type_start_token->location,
		    "invalid class name in declaration of %qD",
		    type);
	  type = NULL_TREE;
	  goto done;
	}

      /* Figure out in what scope the declaration is being placed.  */
      scope = current_scope ();
      /* If that scope does not contain the scope in which the
	 class was originally declared, the program is invalid.  */
      if (scope && !is_ancestor (scope, nested_name_specifier))
	{
	  if (at_namespace_scope_p ())
	    error_at (type_start_token->location,
		      "declaration of %qD in namespace %qD which does not "
		      "enclose %qD",
		      type, scope, nested_name_specifier);
	  else
	    error_at (type_start_token->location,
		      "declaration of %qD in %qD which does not enclose %qD",
		      type, scope, nested_name_specifier);
	  type = NULL_TREE;
	  goto done;
	}
      /* [dcl.meaning]

	 A declarator-id shall not be qualified except for the
	 definition of a ... nested class outside of its class
	 ... [or] the definition or explicit instantiation of a
	 class member of a namespace outside of its namespace.  */
      if (scope == nested_name_specifier)
	permerror (nested_name_specifier_token_start->location,
		   "extra qualification not allowed");
    }
  /* An explicit-specialization must be preceded by "template <>".  If
     it is not, try to recover gracefully.  */
  if (at_namespace_scope_p ()
      && parser->num_template_parameter_lists == 0
      && !processing_template_parmlist
      && template_id_p)
    {
      /* Build a location of this form:
           struct typename <ARGS>
           ^~~~~~~~~~~~~~~~~~~~~~
         with caret==start at the start token, and
         finishing at the end of the type.  */
      location_t reported_loc
        = make_location (class_head_start_location,
                         class_head_start_location,
                         get_finish (type_start_token->location));
      rich_location richloc (line_table, reported_loc);
      richloc.add_fixit_insert_before (class_head_start_location,
                                       "template <> ");
      error_at (&richloc,
		"an explicit specialization must be preceded by"
		" %<template <>%>");
      invalid_explicit_specialization_p = true;
      /* Take the same action that would have been taken by
	 cp_parser_explicit_specialization.  */
      ++parser->num_template_parameter_lists;
      begin_specialization ();
    }
  /* There must be no "return" statements between this point and the
     end of this function; set "type "to the correct return value and
     use "goto done;" to return.  */
  /* Make sure that the right number of template parameters were
     present.  */
  if (!cp_parser_check_template_parameters (parser, num_templates,
					    template_id_p,
					    type_start_token->location,
					    /*declarator=*/NULL))
    {
      /* If something went wrong, there is no point in even trying to
	 process the class-definition.  */
      type = NULL_TREE;
      goto done;
    }

  /* Look up the type.  */
  if (template_id_p)
    {
      if (TREE_CODE (id) == TEMPLATE_ID_EXPR
	  && (DECL_FUNCTION_TEMPLATE_P (TREE_OPERAND (id, 0))
	      || TREE_CODE (TREE_OPERAND (id, 0)) == OVERLOAD))
	{
	  error_at (type_start_token->location,
		    "function template %qD redeclared as a class template", id);
	  type = error_mark_node;
	}
      else
	{
	  type = TREE_TYPE (id);
	  type = maybe_process_partial_specialization (type);

	  /* Check the scope while we still know whether or not we had a
	     nested-name-specifier.  */
	  if (type != error_mark_node)
	    check_unqualified_spec_or_inst (type, type_start_token->location);
	}
      if (nested_name_specifier)
	pushed_scope = push_scope (nested_name_specifier);
    }
  else if (nested_name_specifier)
    {
      type = TREE_TYPE (type);

      /* Given:

	    template <typename T> struct S { struct T };
	    template <typename T> struct S<T>::T { };

	 we will get a TYPENAME_TYPE when processing the definition of
	 `S::T'.  We need to resolve it to the actual type before we
	 try to define it.  */
      if (TREE_CODE (type) == TYPENAME_TYPE)
	{
	  type = resolve_typename_type (type, /*only_current_p=*/false);
	  if (TREE_CODE (type) == TYPENAME_TYPE)
	    {
	      cp_parser_error (parser, "could not resolve typename type");
	      type = error_mark_node;
	    }
	}

      type = maybe_process_partial_specialization (type);
      if (type == error_mark_node)
	{
	  type = NULL_TREE;
	  goto done;
	}

      /* Enter the scope indicated by the nested-name-specifier.  */
      pushed_scope = push_scope (nested_name_specifier);
      /* Get the canonical version of this type.  */
      type = TYPE_MAIN_DECL (type);
      /* Call push_template_decl if it seems like we should be defining a
	 template either from the template headers or the type we're
	 defining, so that we diagnose both extra and missing headers.  */
      if ((PROCESSING_REAL_TEMPLATE_DECL_P ()
	   || CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (type)))
	  && !CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (type)))
	{
	  type = push_template_decl (type);
	  if (type == error_mark_node)
	    {
	      type = NULL_TREE;
	      goto done;
	    }
	}

      type = TREE_TYPE (type);
      *nested_name_specifier_p = true;
    }
  else      /* The name is not a nested name.  */
    {
      /* If the class was unnamed, create a dummy name.  */
      if (!id)
	id = make_anon_name ();
      TAG_how how = (parser->in_type_id_in_expr_p
		     ? TAG_how::INNERMOST_NON_CLASS
		     : TAG_how::CURRENT_ONLY);
      type = xref_tag (class_key, id, how,
		       parser->num_template_parameter_lists);
    }

  /* Diagnose class/struct/union mismatches.  */
  cp_parser_check_class_key (parser, UNKNOWN_LOCATION, class_key, type,
			     true, true);

  /* Indicate whether this class was declared as a `class' or as a
     `struct'.  */
  if (TREE_CODE (type) == RECORD_TYPE)
    CLASSTYPE_DECLARED_CLASS (type) = class_key == class_type;

  /* If this type was already complete, and we see another definition,
     that's an error.  Likewise if the type is already being defined:
     this can happen, eg, when it's defined from within an expression 
     (c++/84605).  */
  if (type != error_mark_node
      && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type)))
    {
      error_at (type_start_token->location, "redefinition of %q#T",
		type);
      inform (location_of (type), "previous definition of %q#T",
	      type);
      type = NULL_TREE;
      goto done;
    }
  else if (type == error_mark_node)
    type = NULL_TREE;

  if (type)
    {
      if (current_lambda_expr ()
	  && uses_parameter_packs (attributes))
	{
	  /* In a lambda this should work, but doesn't currently.  */
	  sorry ("unexpanded parameter pack in local class in lambda");
	  attributes = NULL_TREE;
	}

      /* Apply attributes now, before any use of the class as a template
	 argument in its base list.  */
      cplus_decl_attributes (&type, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);
      fixup_attribute_variants (type);
    }

  /* Associate constraints with the type.  */
  if (flag_concepts)
    type = associate_classtype_constraints (type);

  /* We will have entered the scope containing the class; the names of
     base classes should be looked up in that context.  For example:

       struct A { struct B {}; struct C; };
       struct A::C : B {};

     is valid.  */

  /* Get the list of base-classes, if there is one.  Defer access checking
     until the entire list has been seen, as per [class.access.general].  */
  push_deferring_access_checks (dk_deferred);
  if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      if (type)
	pushclass (type);
      bases = cp_parser_base_clause (parser);
      if (type)
	popclass ();
    }
  else
    bases = NULL_TREE;

  /* If we're really defining a class, process the base classes.
     If they're invalid, fail.  */
  if (type && cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    xref_basetypes (type, bases);

  /* Now that all bases have been seen and attached to the class, check
     accessibility of the types named in the base-clause.  This must be
     done relative to the class scope, so that we accept e.g.

       struct A { protected: struct B {}; };
       struct C : A::B, A {}; // OK: A::B is accessible via base A

     as per [class.access.general].  */
  if (type)
    pushclass (type);
  pop_to_parent_deferring_access_checks ();
  if (type)
    popclass ();

 done:
  /* Leave the scope given by the nested-name-specifier.  We will
     enter the class scope itself while processing the members.  */
  if (pushed_scope)
    pop_scope (pushed_scope);

  if (invalid_explicit_specialization_p)
    {
      end_specialization ();
      --parser->num_template_parameter_lists;
    }

  if (type)
    DECL_SOURCE_LOCATION (TYPE_NAME (type)) = type_start_token->location;
  if (type && (virt_specifiers & VIRT_SPEC_FINAL))
    CLASSTYPE_FINAL (type) = 1;
 out:
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
  return type;
}

/* Parse a class-key.

   class-key:
     class
     struct
     union

   Returns the kind of class-key specified, or none_type to indicate
   error.  */

static enum tag_types
cp_parser_class_key (cp_parser* parser)
{
  cp_token *token;
  enum tag_types tag_type;

  /* Look for the class-key.  */
  token = cp_parser_require (parser, CPP_KEYWORD, RT_CLASS_KEY);
  if (!token)
    return none_type;

  /* Check to see if the TOKEN is a class-key.  */
  tag_type = cp_parser_token_is_class_key (token);
  if (!tag_type)
    cp_parser_error (parser, "expected class-key");
  return tag_type;
}

/* Parse a type-parameter-key.

   type-parameter-key:
     class
     typename
 */

static void
cp_parser_type_parameter_key (cp_parser* parser)
{
  /* Look for the type-parameter-key.  */
  enum tag_types tag_type = none_type;
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  if ((tag_type = cp_parser_token_is_type_parameter_key (token)) != none_type)
    {
      cp_lexer_consume_token (parser->lexer);
      if (pedantic && tag_type == typename_type
	  && cxx_dialect < cxx17)
	/* typename is not allowed in a template template parameter
	   by the standard until C++17.  */
	pedwarn (token->location, OPT_Wc__17_extensions,
		 "ISO C++ forbids typename key in template template parameter;"
		 " use %<-std=c++17%> or %<-std=gnu++17%>");
    }
  else
    cp_parser_error (parser, "expected %<class%> or %<typename%>");

  return;
}

/* Parse an (optional) member-specification.

   member-specification:
     member-declaration member-specification [opt]
     access-specifier : member-specification [opt]  */

static void
cp_parser_member_specification_opt (cp_parser* parser)
{
  while (true)
    {
      cp_token *token;
      enum rid keyword;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* If it's a `}', or EOF then we've seen all the members.  */
      if (token->type == CPP_CLOSE_BRACE
	  || token->type == CPP_EOF
	  || token->type == CPP_PRAGMA_EOL)
	break;

      /* See if this token is a keyword.  */
      keyword = token->keyword;
      switch (keyword)
	{
	case RID_PUBLIC:
	case RID_PROTECTED:
	case RID_PRIVATE:
	  /* Consume the access-specifier.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Remember which access-specifier is active.  */
	  current_access_specifier = token->u.value;
	  /* Look for the `:'.  */
	  cp_parser_require (parser, CPP_COLON, RT_COLON);
	  break;

	default:
	  /* Accept #pragmas at class scope.  */
	  if (token->type == CPP_PRAGMA)
	    {
	      cp_parser_pragma (parser, pragma_member, NULL);
	      break;
	    }

	  /* Otherwise, the next construction must be a
	     member-declaration.  */
	  cp_parser_member_declaration (parser);
	}
    }
}

/* Parse a member-declaration.

   member-declaration:
     decl-specifier-seq [opt] member-declarator-list [opt] ;
     function-definition ; [opt]
     :: [opt] nested-name-specifier template [opt] unqualified-id ;
     using-declaration
     template-declaration
     alias-declaration

   member-declarator-list:
     member-declarator
     member-declarator-list , member-declarator

   member-declarator:
     declarator pure-specifier [opt]
     declarator constant-initializer [opt]
     identifier [opt] : constant-expression

   GNU Extensions:

   member-declaration:
     __extension__ member-declaration

   member-declarator:
     declarator attributes [opt] pure-specifier [opt]
     declarator attributes [opt] constant-initializer [opt]
     identifier [opt] attributes [opt] : constant-expression

   C++0x Extensions:

   member-declaration:
     static_assert-declaration  */

static void
cp_parser_member_declaration (cp_parser* parser)
{
  cp_decl_specifier_seq decl_specifiers;
  tree prefix_attributes;
  tree decl;
  int declares_class_or_enum;
  bool friend_p;
  cp_token *token = NULL;
  cp_token *decl_spec_token_start = NULL;
  cp_token *initializer_token_start = NULL;
  int saved_pedantic;
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;

  /* Check for the `__extension__' keyword.  */
  if (cp_parser_extension_opt (parser, &saved_pedantic))
    {
      /* Recurse.  */
      cp_parser_member_declaration (parser);
      /* Restore the old value of the PEDANTIC flag.  */
      pedantic = saved_pedantic;

      return;
    }

  /* Check for a template-declaration.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
    {
      /* An explicit specialization here is an error condition, and we
	 expect the specialization handler to detect and report this.  */
      if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_LESS
	  && cp_lexer_peek_nth_token (parser->lexer, 3)->type == CPP_GREATER)
	cp_parser_explicit_specialization (parser);
      else
	cp_parser_template_declaration (parser, /*member_p=*/true);

      return;
    }
  /* Check for a template introduction.  */
  else if (cp_parser_template_declaration_after_export (parser, true))
    return;

  /* Check for a using-declaration.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
    {
      if (cxx_dialect < cxx11)
	/* Parse the using-declaration.  */
	cp_parser_using_declaration (parser, /*access_declaration_p=*/false);
      else if (cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_ENUM))
	cp_parser_using_enum (parser);
      else
	{
	  tree decl;
	  bool alias_decl_expected;
	  cp_parser_parse_tentatively (parser);
	  decl = cp_parser_alias_declaration (parser);
	  /* Note that if we actually see the '=' token after the
	     identifier, cp_parser_alias_declaration commits the
	     tentative parse.  In that case, we really expect an
	     alias-declaration.  Otherwise, we expect a using
	     declaration.  */
	  alias_decl_expected =
	    !cp_parser_uncommitted_to_tentative_parse_p (parser);
	  cp_parser_parse_definitely (parser);

	  if (alias_decl_expected)
	    finish_member_declaration (decl);
	  else
	    cp_parser_using_declaration (parser,
					 /*access_declaration_p=*/false);
	}
      return;
    }

  /* Check for @defs.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_DEFS))
    {
      tree ivar, member;
      tree ivar_chains = cp_parser_objc_defs_expression (parser);
      ivar = ivar_chains;
      while (ivar)
	{
	  member = ivar;
	  ivar = TREE_CHAIN (member);
	  TREE_CHAIN (member) = NULL_TREE;
	  finish_member_declaration (member);
	}
      return;
    }

  /* If the next token is `static_assert' we have a static assertion.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC_ASSERT))
    {
      cp_parser_static_assert (parser, /*member_p=*/true);
      return;
    }

  parser->colon_corrects_to_scope_p = false;

  cp_omp_declare_simd_data odsd;
  if (cp_parser_using_declaration (parser, /*access_declaration=*/true))
    goto out;

  /* Parse the decl-specifier-seq.  */
  decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
  cp_parser_decl_specifier_seq (parser,
				(CP_PARSER_FLAGS_OPTIONAL
				 | CP_PARSER_FLAGS_TYPENAME_OPTIONAL),
				&decl_specifiers,
				&declares_class_or_enum);

  if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
    cp_parser_handle_directive_omp_attributes (parser,
					       &decl_specifiers.attributes,
					       &odsd, true);

  /* Check for an invalid type-name.  */
  if (!decl_specifiers.any_type_specifiers_p
      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
    goto out;
  /* If there is no declarator, then the decl-specifier-seq should
     specify a type.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    {
      /* If there was no decl-specifier-seq, and the next token is a
	 `;', then we have something like:

	   struct S { ; };

	 [class.mem]

	 Each member-declaration shall declare at least one member
	 name of the class.  */
      if (!decl_specifiers.any_specifiers_p)
	{
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  if (!in_system_header_at (token->location))
	    {
	      gcc_rich_location richloc (token->location);
	      richloc.add_fixit_remove ();
	      pedwarn (&richloc, OPT_Wpedantic, "extra %<;%>");
	    }
	}
      else
	{
	  /* See if this declaration is a friend.  */
	  friend_p = cp_parser_friend_p (&decl_specifiers);
	  /* If there were decl-specifiers, check to see if there was
	     a class-declaration.  */
	  tree type = check_tag_decl (&decl_specifiers,
				      /*explicit_type_instantiation_p=*/false);
	  /* Nested classes have already been added to the class, but
	     a `friend' needs to be explicitly registered.  */
	  if (friend_p)
	    {
	      /* If the `friend' keyword was present, the friend must
		 be introduced with a class-key.  */
	       if (!declares_class_or_enum && cxx_dialect < cxx11)
		 pedwarn (decl_spec_token_start->location, OPT_Wpedantic,
			  "in C++03 a class-key must be used "
			  "when declaring a friend");
	       /* In this case:

		    template <typename T> struct A {
		      friend struct A<T>::B;
		    };

		  A<T>::B will be represented by a TYPENAME_TYPE, and
		  therefore not recognized by check_tag_decl.  */
	       if (!type)
		 {
		   type = decl_specifiers.type;
		   if (type && TREE_CODE (type) == TYPE_DECL)
		     type = TREE_TYPE (type);
		 }
	       /* Warn if an attribute cannot appear here, as per
		  [dcl.attr.grammar]/5.  But not when declares_class_or_enum:
		  we ignore attributes in elaborated-type-specifiers.  */
	       if (!declares_class_or_enum
		   && cxx11_attribute_p (decl_specifiers.attributes))
		 {
		   decl_specifiers.attributes = NULL_TREE;
		   if (warning_at (decl_spec_token_start->location,
				   OPT_Wattributes, "attribute ignored"))
		     inform (decl_spec_token_start->location, "an attribute "
			     "that appertains to a friend declaration that "
			     "is not a definition is ignored");
		 }
	       if (!type || !TYPE_P (type))
		 error_at (decl_spec_token_start->location,
			   "friend declaration does not name a class or "
			   "function");
	       else
		 make_friend_class (current_class_type, type,
				    /*complain=*/true);
	    }
	  /* If there is no TYPE, an error message will already have
	     been issued.  */
	  else if (!type || type == error_mark_node)
	    ;
	  /* An anonymous aggregate has to be handled specially; such
	     a declaration really declares a data member (with a
	     particular type), as opposed to a nested class.  */
	  else if (ANON_AGGR_TYPE_P (type))
	    {
	      /* C++11 9.5/6.  */
	      if (decl_specifiers.storage_class != sc_none)
		error_at (decl_spec_token_start->location,
			  "a storage class on an anonymous aggregate "
			  "in class scope is not allowed");

	      /* Remove constructors and such from TYPE, now that we
		 know it is an anonymous aggregate.  */
	      fixup_anonymous_aggr (type);
	      /* And make the corresponding data member.  */
	      decl = build_decl (decl_spec_token_start->location,
				 FIELD_DECL, NULL_TREE, type);
	      /* Add it to the class.  */
	      finish_member_declaration (decl);
	    }
	  else
	    cp_parser_check_access_in_redeclaration
					      (TYPE_NAME (type),
					       decl_spec_token_start->location);
	}
    }
  else
    {
      bool assume_semicolon = false;

      /* Clear attributes from the decl_specifiers but keep them
	 around as prefix attributes that apply them to the entity
	 being declared.  */
      prefix_attributes = decl_specifiers.attributes;
      decl_specifiers.attributes = NULL_TREE;
      if (parser->omp_declare_simd
	  && (parser->omp_declare_simd->attribs[0]
	      == &decl_specifiers.attributes))
	parser->omp_declare_simd->attribs[0] = &prefix_attributes;

      /* See if these declarations will be friends.  */
      friend_p = cp_parser_friend_p (&decl_specifiers);

      /* Keep going until we hit the `;' at the end of the
	 declaration.  */
      while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	{
	  tree attributes = NULL_TREE;
	  tree first_attribute;
	  tree initializer;
	  bool named_bitfld = false;

	  /* Peek at the next token.  */
	  token = cp_lexer_peek_token (parser->lexer);

	  /* The following code wants to know early if it is a bit-field
	     or some other declaration.  Attributes can appear before
	     the `:' token.  Skip over them without consuming any tokens
	     to peek if they are followed by `:'.  */
	  if (cp_next_tokens_can_be_attribute_p (parser)
	      || (token->type == CPP_NAME
		  && cp_nth_tokens_can_be_attribute_p (parser, 2)
		  && (named_bitfld = true)))
	    {
	      size_t n
		= cp_parser_skip_attributes_opt (parser, 1 + named_bitfld);
	      token = cp_lexer_peek_nth_token (parser->lexer, n);
	    }

	  /* Check for a bitfield declaration.  */
	  if (token->type == CPP_COLON
	      || (token->type == CPP_NAME
		  && token == cp_lexer_peek_token (parser->lexer)
		  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON)
		  && (named_bitfld = true)))
	    {
	      tree identifier;
	      tree width;
	      tree late_attributes = NULL_TREE;
	      location_t id_location
		= cp_lexer_peek_token (parser->lexer)->location;

	      if (named_bitfld)
		identifier = cp_parser_identifier (parser);
	      else
		identifier = NULL_TREE;

	      /* Look for attributes that apply to the bitfield.  */
	      attributes = cp_parser_attributes_opt (parser);

	      /* Consume the `:' token.  */
	      cp_lexer_consume_token (parser->lexer);

	      /* Get the width of the bitfield.  */
	      width = cp_parser_constant_expression (parser, false, NULL,
						     cxx_dialect >= cxx11);

	      /* In C++20 and as extension for C++11 and above we allow
		 default member initializers for bit-fields.  */
	      initializer = NULL_TREE;
	      if (cxx_dialect >= cxx11
		  && (cp_lexer_next_token_is (parser->lexer, CPP_EQ)
		      || cp_lexer_next_token_is (parser->lexer,
						 CPP_OPEN_BRACE)))
		{
		  location_t loc
		    = cp_lexer_peek_token (parser->lexer)->location;
		  if (cxx_dialect < cxx20
		      && identifier != NULL_TREE)
		    pedwarn (loc, OPT_Wc__20_extensions,
			     "default member initializers for bit-fields "
			     "only available with %<-std=c++20%> or "
			     "%<-std=gnu++20%>");

		  initializer = cp_parser_save_nsdmi (parser);
		  if (identifier == NULL_TREE)
		    {
		      error_at (loc, "default member initializer for "
				     "unnamed bit-field");
		      initializer = NULL_TREE;
		    }
		}
	      else
		{
		  /* Look for attributes that apply to the bitfield after
		     the `:' token and width.  This is where GCC used to
		     parse attributes in the past, pedwarn if there is
		     a std attribute.  */
		  if (cp_next_tokens_can_be_std_attribute_p (parser))
		    pedwarn (input_location, OPT_Wpedantic,
			     "ISO C++ allows bit-field attributes only "
			     "before the %<:%> token");

		  late_attributes = cp_parser_attributes_opt (parser);
		}

	      attributes = attr_chainon (attributes, late_attributes);

	      /* Remember which attributes are prefix attributes and
		 which are not.  */
	      first_attribute = attributes;
	      /* Combine the attributes.  */
	      attributes = attr_chainon (prefix_attributes, attributes);

	      /* Create the bitfield declaration.  */
	      decl = grokbitfield (identifier
				   ? make_id_declarator (NULL_TREE,
							 identifier,
							 sfk_none,
							 id_location)
				   : NULL,
				   &decl_specifiers,
				   width, initializer,
				   attributes);
	    }
	  else
	    {
	      cp_declarator *declarator;
	      tree asm_specification;
	      int ctor_dtor_or_conv_p;
	      bool static_p = (decl_specifiers.storage_class == sc_static);
	      cp_parser_flags flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
	      /* We can't delay parsing for friends,
		 alias-declarations, and typedefs, even though the
		 standard seems to require it.  */
	      if (!friend_p
		  && !decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
		flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;

	      /* Parse the declarator.  */
	      declarator
		= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
					flags,
					&ctor_dtor_or_conv_p,
					/*parenthesized_p=*/NULL,
					/*member_p=*/true,
					friend_p, static_p);

	      /* If something went wrong parsing the declarator, make sure
		 that we at least consume some tokens.  */
	      if (declarator == cp_error_declarator)
		{
		  /* Skip to the end of the statement.  */
		  cp_parser_skip_to_end_of_statement (parser);
		  /* If the next token is not a semicolon, that is
		     probably because we just skipped over the body of
		     a function.  So, we consume a semicolon if
		     present, but do not issue an error message if it
		     is not present.  */
		  if (cp_lexer_next_token_is (parser->lexer,
					      CPP_SEMICOLON))
		    cp_lexer_consume_token (parser->lexer);
		  goto out;
		}

	      /* Handle class-scope non-template C++17 deduction guides.  */
	      cp_parser_maybe_adjust_declarator_for_dguide (parser,
							    &decl_specifiers,
							    declarator,
							    &ctor_dtor_or_conv_p);

	      if (declares_class_or_enum & 2)
		cp_parser_check_for_definition_in_return_type
					    (declarator, decl_specifiers.type,
					     decl_specifiers.locations[ds_type_spec]);

	      /* Look for an asm-specification.  */
	      asm_specification = cp_parser_asm_specification_opt (parser);
	      /* Look for attributes that apply to the declaration.  */
	      attributes = cp_parser_attributes_opt (parser);
	      /* Remember which attributes are prefix attributes and
		 which are not.  */
	      first_attribute = attributes;
	      /* Combine the attributes.  */
	      attributes = attr_chainon (prefix_attributes, attributes);

	      /* If it's an `=', then we have a constant-initializer or a
		 pure-specifier.  It is not correct to parse the
		 initializer before registering the member declaration
		 since the member declaration should be in scope while
		 its initializer is processed.  However, the rest of the
		 front end does not yet provide an interface that allows
		 us to handle this correctly.  */
	      if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
		{
		  /* In [class.mem]:

		     A pure-specifier shall be used only in the declaration of
		     a virtual function.

		     A member-declarator can contain a constant-initializer
		     only if it declares a static member of integral or
		     enumeration type.

		     Therefore, if the DECLARATOR is for a function, we look
		     for a pure-specifier; otherwise, we look for a
		     constant-initializer.  When we call `grokfield', it will
		     perform more stringent semantics checks.  */
		  initializer_token_start = cp_lexer_peek_token (parser->lexer);
		  declarator->init_loc = initializer_token_start->location;
		  if (function_declarator_p (declarator)
		      || (decl_specifiers.type
			  && TREE_CODE (decl_specifiers.type) == TYPE_DECL
			  && declarator->kind == cdk_id
			  && (TREE_CODE (TREE_TYPE (decl_specifiers.type))
			      == FUNCTION_TYPE)))
		    initializer = cp_parser_pure_specifier (parser);
		  else if (decl_specifiers.storage_class != sc_static)
		    initializer = cp_parser_save_nsdmi (parser);
		  else if (cxx_dialect >= cxx11)
		    {
		      bool nonconst;
		      /* Don't require a constant rvalue in C++11, since we
			 might want a reference constant.  We'll enforce
		         constancy later.  */
		      cp_lexer_consume_token (parser->lexer);
		      /* Parse the initializer.  */
		      initializer = cp_parser_initializer_clause (parser,
								  &nonconst);
		    }
		  else
		    /* Parse the initializer.  */
		    initializer = cp_parser_constant_initializer (parser);
		}
	      else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)
		       && !function_declarator_p (declarator))
		{
		  bool x;
		  declarator->init_loc
		    = cp_lexer_peek_token (parser->lexer)->location;
		  if (decl_specifiers.storage_class != sc_static)
		    initializer = cp_parser_save_nsdmi (parser);
		  else
		    initializer = cp_parser_initializer (parser, &x, &x);
		}
	      /* Detect invalid bit-field cases such as

		   int *p : 4;
		   int &&r : 3;

		 and similar.  */
	      else if (cp_lexer_next_token_is (parser->lexer, CPP_COLON)
		       /* If there were no type specifiers, it was a
			  constructor.  */
		       && decl_specifiers.any_type_specifiers_p)
		{
		  /* This is called for a decent diagnostic only.  */
		  tree d = grokdeclarator (declarator, &decl_specifiers,
					   BITFIELD, /*initialized=*/false,
					   &attributes);
		  if (!error_operand_p (d))
		    error_at (DECL_SOURCE_LOCATION (d),
			      "bit-field %qD has non-integral type %qT",
			      d, TREE_TYPE (d));
		  cp_parser_skip_to_end_of_statement (parser);
		  /* Avoid "extra ;" pedwarns.  */
		  if (cp_lexer_next_token_is (parser->lexer,
					      CPP_SEMICOLON))
		    cp_lexer_consume_token (parser->lexer);
		  goto out;
		}
	      /* Otherwise, there is no initializer.  */
	      else
		initializer = NULL_TREE;

	      /* See if we are probably looking at a function
		 definition.  We are certainly not looking at a
		 member-declarator.  Calling `grokfield' has
		 side-effects, so we must not do it unless we are sure
		 that we are looking at a member-declarator.  */
	      if (cp_parser_token_starts_function_definition_p
		  (cp_lexer_peek_token (parser->lexer)))
		{
		  /* The grammar does not allow a pure-specifier to be
		     used when a member function is defined.  (It is
		     possible that this fact is an oversight in the
		     standard, since a pure function may be defined
		     outside of the class-specifier.  */
		  if (initializer && initializer_token_start)
		    error_at (initializer_token_start->location,
			      "pure-specifier on function-definition");
		  decl = cp_parser_save_member_function_body (parser,
							      &decl_specifiers,
							      declarator,
							      attributes);

		  if (parser->fully_implicit_function_template_p)
		    decl = finish_fully_implicit_template (parser, decl);
		  /* If the member was not a friend, declare it here.  */
		  if (!friend_p)
		    finish_member_declaration (decl);
		  /* Peek at the next token.  */
		  token = cp_lexer_peek_token (parser->lexer);
		  /* If the next token is a semicolon, consume it.  */
		  if (token->type == CPP_SEMICOLON)
		    {
		      location_t semicolon_loc
			= cp_lexer_consume_token (parser->lexer)->location;
		      gcc_rich_location richloc (semicolon_loc);
		      richloc.add_fixit_remove ();
		      warning_at (&richloc, OPT_Wextra_semi,
				  "extra %<;%> after in-class "
				  "function definition");
		    }
		  goto out;
		}
	      else
		if (declarator->kind == cdk_function)
		  declarator->id_loc = token->location;

	      /* Create the declaration.  */
	      decl = grokfield (declarator, &decl_specifiers,
				initializer, /*init_const_expr_p=*/true,
				asm_specification, attributes);

	      if (parser->fully_implicit_function_template_p)
		{
		  if (friend_p)
		    finish_fully_implicit_template (parser, 0);
		  else
		    decl = finish_fully_implicit_template (parser, decl);
		}
	    }

	  cp_finalize_omp_declare_simd (parser, decl);
	  cp_finalize_oacc_routine (parser, decl, false);

	  /* Reset PREFIX_ATTRIBUTES.  */
	  if (attributes != error_mark_node)
	    {
	      while (attributes && TREE_CHAIN (attributes) != first_attribute)
		attributes = TREE_CHAIN (attributes);
	      if (attributes)
		TREE_CHAIN (attributes) = NULL_TREE;
	    }

	  /* If there is any qualification still in effect, clear it
	     now; we will be starting fresh with the next declarator.  */
	  parser->scope = NULL_TREE;
	  parser->qualifying_scope = NULL_TREE;
	  parser->object_scope = NULL_TREE;
	  /* If it's a `,', then there are more declarators.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
		{
		  cp_token *token = cp_lexer_previous_token (parser->lexer);
		  gcc_rich_location richloc (token->location);
		  richloc.add_fixit_remove ();
		  error_at (&richloc, "stray %<,%> at end of "
			    "member declaration");
		}
	    }
	  /* If the next token isn't a `;', then we have a parse error.  */
	  else if (cp_lexer_next_token_is_not (parser->lexer,
					       CPP_SEMICOLON))
	    {
	      /* The next token might be a ways away from where the
		 actual semicolon is missing.  Find the previous token
		 and use that for our error position.  */
	      cp_token *token = cp_lexer_previous_token (parser->lexer);
	      gcc_rich_location richloc (token->location);
	      richloc.add_fixit_insert_after (";");
	      error_at (&richloc, "expected %<;%> at end of "
			"member declaration");

	      /* Assume that the user meant to provide a semicolon.  If
		 we were to cp_parser_skip_to_end_of_statement, we might
		 skip to a semicolon inside a member function definition
		 and issue nonsensical error messages.  */
	      assume_semicolon = true;
	    }

	  if (decl)
	    {
	      /* Add DECL to the list of members.  */
	      if (!friend_p
		  /* Explicitly include, eg, NSDMIs, for better error
		     recovery (c++/58650).  */
		  || !DECL_DECLARES_FUNCTION_P (decl))
		finish_member_declaration (decl);

	      if (DECL_DECLARES_FUNCTION_P (decl))
		cp_parser_save_default_args (parser, STRIP_TEMPLATE (decl));
	      else if (TREE_CODE (decl) == FIELD_DECL
		       && DECL_INITIAL (decl))
		/* Add DECL to the queue of NSDMI to be parsed later.  */
		vec_safe_push (unparsed_nsdmis, decl);
	    }

	  if (assume_semicolon)
	    goto out;
	}
    }

  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
 out:
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
  cp_finalize_omp_declare_simd (parser, &odsd);
}

/* Parse a pure-specifier.

   pure-specifier:
     = 0

   Returns INTEGER_ZERO_NODE if a pure specifier is found.
   Otherwise, ERROR_MARK_NODE is returned.  */

static tree
cp_parser_pure_specifier (cp_parser* parser)
{
  cp_token *token;

  /* Look for the `=' token.  */
  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
    return error_mark_node;
  /* Look for the `0' token.  */
  token = cp_lexer_peek_token (parser->lexer);

  if (token->type == CPP_EOF
      || token->type == CPP_PRAGMA_EOL)
    return error_mark_node;

  cp_lexer_consume_token (parser->lexer);

  /* Accept = default or = delete in c++0x mode.  */
  if (token->keyword == RID_DEFAULT
      || token->keyword == RID_DELETE)
    {
      maybe_warn_cpp0x (CPP0X_DEFAULTED_DELETED);
      return token->u.value;
    }

  /* c_lex_with_flags marks a single digit '0' with PURE_ZERO.  */
  if (token->type != CPP_NUMBER || !(token->flags & PURE_ZERO))
    {
      cp_parser_error (parser,
		       "invalid pure specifier (only %<= 0%> is allowed)");
      cp_parser_skip_to_end_of_statement (parser);
      return error_mark_node;
    }
  if (PROCESSING_REAL_TEMPLATE_DECL_P ())
    {
      error_at (token->location, "templates may not be %<virtual%>");
      return error_mark_node;
    }

  return integer_zero_node;
}

/* Parse a constant-initializer.

   constant-initializer:
     = constant-expression

   Returns a representation of the constant-expression.  */

static tree
cp_parser_constant_initializer (cp_parser* parser)
{
  /* Look for the `=' token.  */
  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
    return error_mark_node;

  /* It is invalid to write:

       struct S { static const int i = { 7 }; };

     */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      cp_parser_error (parser,
		       "a brace-enclosed initializer is not allowed here");
      /* Consume the opening brace.  */
      matching_braces braces;
      braces.consume_open (parser);
      /* Skip the initializer.  */
      cp_parser_skip_to_closing_brace (parser);
      /* Look for the trailing `}'.  */
      braces.require_close (parser);

      return error_mark_node;
    }

  return cp_parser_constant_expression (parser);
}

/* Derived classes [gram.class.derived] */

/* Parse a base-clause.

   base-clause:
     : base-specifier-list

   base-specifier-list:
     base-specifier ... [opt]
     base-specifier-list , base-specifier ... [opt]

   Returns a TREE_LIST representing the base-classes, in the order in
   which they were declared.  The representation of each node is as
   described by cp_parser_base_specifier.

   In the case that no bases are specified, this function will return
   NULL_TREE, not ERROR_MARK_NODE.  */

static tree
cp_parser_base_clause (cp_parser* parser)
{
  tree bases = NULL_TREE;

  /* Look for the `:' that begins the list.  */
  cp_parser_require (parser, CPP_COLON, RT_COLON);

  /* Scan the base-specifier-list.  */
  while (true)
    {
      cp_token *token;
      tree base;
      bool pack_expansion_p = false;

      /* Look for the base-specifier.  */
      base = cp_parser_base_specifier (parser);
      /* Look for the (optional) ellipsis. */
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
        {
          /* Consume the `...'. */
          cp_lexer_consume_token (parser->lexer);

          pack_expansion_p = true;
        }

      /* Add BASE to the front of the list.  */
      if (base && base != error_mark_node)
	{
          if (pack_expansion_p)
            /* Make this a pack expansion type. */
            TREE_VALUE (base) = make_pack_expansion (TREE_VALUE (base));

          if (!check_for_bare_parameter_packs (TREE_VALUE (base)))
            {
              TREE_CHAIN (base) = bases;
              bases = base;
            }
	}
      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* If it's not a comma, then the list is complete.  */
      if (token->type != CPP_COMMA)
	break;
      /* Consume the `,'.  */
      cp_lexer_consume_token (parser->lexer);
    }

  /* PARSER->SCOPE may still be non-NULL at this point, if the last
     base class had a qualified name.  However, the next name that
     appears is certainly not qualified.  */
  parser->scope = NULL_TREE;
  parser->qualifying_scope = NULL_TREE;
  parser->object_scope = NULL_TREE;

  return nreverse (bases);
}

/* Parse a base-specifier.

   base-specifier:
     :: [opt] nested-name-specifier [opt] class-name
     virtual access-specifier [opt] :: [opt] nested-name-specifier
       [opt] class-name
     access-specifier virtual [opt] :: [opt] nested-name-specifier
       [opt] class-name

   Returns a TREE_LIST.  The TREE_PURPOSE will be one of
   ACCESS_{DEFAULT,PUBLIC,PROTECTED,PRIVATE}_[VIRTUAL]_NODE to
   indicate the specifiers provided.  The TREE_VALUE will be a TYPE
   (or the ERROR_MARK_NODE) indicating the type that was specified.  */

static tree
cp_parser_base_specifier (cp_parser* parser)
{
  cp_token *token;
  bool done = false;
  bool virtual_p = false;
  bool duplicate_virtual_error_issued_p = false;
  bool duplicate_access_error_issued_p = false;
  bool class_scope_p, template_p;
  tree access = access_default_node;
  tree type;

  /* Process the optional `virtual' and `access-specifier'.  */
  while (!done)
    {
      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* Process `virtual'.  */
      switch (token->keyword)
	{
	case RID_VIRTUAL:
	  /* If `virtual' appears more than once, issue an error.  */
	  if (virtual_p && !duplicate_virtual_error_issued_p)
	    {
	      cp_parser_error (parser,
			       "%<virtual%> specified more than once in base-specifier");
	      duplicate_virtual_error_issued_p = true;
	    }

	  virtual_p = true;

	  /* Consume the `virtual' token.  */
	  cp_lexer_consume_token (parser->lexer);

	  break;

	case RID_PUBLIC:
	case RID_PROTECTED:
	case RID_PRIVATE:
	  /* If more than one access specifier appears, issue an
	     error.  */
	  if (access != access_default_node
	      && !duplicate_access_error_issued_p)
	    {
	      cp_parser_error (parser,
			       "more than one access specifier in base-specifier");
	      duplicate_access_error_issued_p = true;
	    }

	  access = ridpointers[(int) token->keyword];

	  /* Consume the access-specifier.  */
	  cp_lexer_consume_token (parser->lexer);

	  break;

	default:
	  done = true;
	  break;
	}
    }
  /* It is not uncommon to see programs mechanically, erroneously, use
     the 'typename' keyword to denote (dependent) qualified types
     as base classes.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
    {
      token = cp_lexer_peek_token (parser->lexer);
      if (!processing_template_decl)
	error_at (token->location,
		  "keyword %<typename%> not allowed outside of templates");
      else
	error_at (token->location,
		  "keyword %<typename%> not allowed in this context "
		  "(the base class is implicitly a type)");
      cp_lexer_consume_token (parser->lexer);
    }

  /* Look for the optional `::' operator.  */
  cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
  /* Look for the nested-name-specifier.  The simplest way to
     implement:

       [temp.res]

       The keyword `typename' is not permitted in a base-specifier or
       mem-initializer; in these contexts a qualified name that
       depends on a template-parameter is implicitly assumed to be a
       type name.

     is to pretend that we have seen the `typename' keyword at this
     point.  */
  cp_parser_nested_name_specifier_opt (parser,
				       /*typename_keyword_p=*/true,
				       /*check_dependency_p=*/true,
				       /*type_p=*/true,
				       /*is_declaration=*/true);
  /* If the base class is given by a qualified name, assume that names
     we see are type names or templates, as appropriate.  */
  class_scope_p = (parser->scope && TYPE_P (parser->scope));
  template_p = class_scope_p && cp_parser_optional_template_keyword (parser);

  if (!parser->scope
      && cp_lexer_next_token_is_decltype (parser->lexer))
    /* DR 950 allows decltype as a base-specifier.  */
    type = cp_parser_decltype (parser);
  else
    {
      /* Otherwise, look for the class-name.  */
      type = cp_parser_class_name (parser,
				   class_scope_p,
				   template_p,
				   typename_type,
				   /*check_dependency_p=*/true,
				   /*class_head_p=*/false,
				   /*is_declaration=*/true);
      type = TREE_TYPE (type);
    }

  if (type == error_mark_node)
    return error_mark_node;

  return finish_base_specifier (type, access, virtual_p);
}

/* Exception handling [gram.exception] */

/* Save the tokens that make up the noexcept-specifier for a member-function.
   Returns a DEFERRED_PARSE.  */

static tree
cp_parser_save_noexcept (cp_parser *parser)
{
  cp_token *first = parser->lexer->next_token;
  /* We want everything up to, including, the final ')'.  */
  cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0);
  cp_token *last = parser->lexer->next_token;

  /* As with default arguments and NSDMIs, make use of DEFERRED_PARSE
     to carry the information we will need.  */
  tree expr = make_node (DEFERRED_PARSE);
  /* Save away the noexcept-specifier; we will process it when the
     class is complete.  */
  DEFPARSE_TOKENS (expr) = cp_token_cache_new (first, last);
  DEFPARSE_INSTANTIATIONS (expr) = nullptr;
  expr = build_tree_list (expr, NULL_TREE);
  return expr;
}

/* Used for late processing of noexcept-specifiers of member-functions.
   DEFAULT_ARG is the unparsed operand of a noexcept-specifier which
   we saved for later; parse it now.  DECL is the declaration of the
   member function.  */

static tree
cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg)
{
  /* Make sure we've gotten something that hasn't been parsed yet.  */
  gcc_assert (TREE_CODE (default_arg) == DEFERRED_PARSE);

  push_unparsed_function_queues (parser);

  /* Push the saved tokens for the noexcept-specifier onto the parser's
     lexer stack.  */
  cp_token_cache *tokens = DEFPARSE_TOKENS (default_arg);
  cp_parser_push_lexer_for_tokens (parser, tokens);

  /* Parse the cached noexcept-specifier.  */
  tree parsed_arg
    = cp_parser_noexcept_specification_opt (parser,
					    CP_PARSER_FLAGS_NONE,
					    /*require_constexpr=*/true,
					    /*consumed_expr=*/NULL,
					    /*return_cond=*/false);

  /* Revert to the main lexer.  */
  cp_parser_pop_lexer (parser);

  /* Restore the queue.  */
  pop_unparsed_function_queues (parser);

  /* And we're done.  */
  return parsed_arg;
}

/* Perform late checking of overriding function with respect to their
   noexcept-specifiers.  TYPE is the class and FNDECL is the function
   that potentially overrides some virtual function with the same
   signature.  */

static void
noexcept_override_late_checks (tree type, tree fndecl)
{
  tree binfo = TYPE_BINFO (type);
  tree base_binfo;

  if (DECL_STATIC_FUNCTION_P (fndecl))
    return;

  for (int i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
    {
      tree basetype = BINFO_TYPE (base_binfo);

      if (!TYPE_POLYMORPHIC_P (basetype))
	continue;

      tree fn = look_for_overrides_here (basetype, fndecl);
      if (fn)
	maybe_check_overriding_exception_spec (fndecl, fn);
    }
}

/* Parse an (optional) noexcept-specification.

   noexcept-specification:
     noexcept ( constant-expression ) [opt]

   If no noexcept-specification is present, returns NULL_TREE.
   Otherwise, if REQUIRE_CONSTEXPR is false, then either parse and return any
   expression if parentheses follow noexcept, or return BOOLEAN_TRUE_NODE if
   there are no parentheses.  CONSUMED_EXPR will be set accordingly.
   Otherwise, returns a noexcept specification unless RETURN_COND is true,
   in which case a boolean condition is returned instead.  The parser flags
   FLAGS is used to control parsing.  QUALS are qualifiers indicating whether
   the (member) function is `const'.  */

static tree
cp_parser_noexcept_specification_opt (cp_parser* parser,
				      cp_parser_flags flags,
				      bool require_constexpr,
				      bool* consumed_expr,
				      bool return_cond)
{
  cp_token *token;
  const char *saved_message;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* Is it a noexcept-specification?  */
  if (cp_parser_is_keyword (token, RID_NOEXCEPT))
    {
      tree expr;

      /* [class.mem]/6 says that a noexcept-specifer (within the
	 member-specification of the class) is a complete-class context of
	 a class.  So, if the noexcept-specifier has the optional expression,
	 just save the tokens, and reparse this after we're done with the
	 class.  */

      if ((flags & CP_PARSER_FLAGS_DELAY_NOEXCEPT)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN)
	  /* No need to delay parsing for a number literal or true/false.  */
	  && !((cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
		|| cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
	       && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN))
	  && at_class_scope_p ()
	  && TYPE_BEING_DEFINED (current_class_type)
	  && !LAMBDA_TYPE_P (current_class_type))
	return cp_parser_save_noexcept (parser);

      cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
	{
	  matching_parens parens;
	  parens.consume_open (parser);

	  if (require_constexpr)
	    {
	      /* Types may not be defined in an exception-specification.  */
	      saved_message = parser->type_definition_forbidden_message;
	      parser->type_definition_forbidden_message
	      = G_("types may not be defined in an exception-specification");

	      bool non_constant_p;
	      expr
		= cp_parser_constant_expression (parser,
						 /*allow_non_constant=*/true,
						 &non_constant_p);
	      if (non_constant_p
		  && !require_potential_rvalue_constant_expression (expr))
		{
		  expr = NULL_TREE;
		  return_cond = true;
		}

	      /* Restore the saved message.  */
	      parser->type_definition_forbidden_message = saved_message;
	    }
	  else
	    {
	      expr = cp_parser_expression (parser);
	      *consumed_expr = true;
	    }

	  parens.require_close (parser);
	}
      else
	{
	  expr = boolean_true_node;
	  if (!require_constexpr)
	    *consumed_expr = false;
	}

      /* We cannot build a noexcept-spec right away because this will check
	 that expr is a constexpr.  */
      if (!return_cond)
	return build_noexcept_spec (expr, tf_warning_or_error);
      else
	return expr;
    }
  else
    return NULL_TREE;
}

/* Parse an (optional) exception-specification.

   exception-specification:
     throw ( type-id-list [opt] )

   Returns a TREE_LIST representing the exception-specification.  The
   TREE_VALUE of each node is a type.  The parser flags FLAGS is used to
   control parsing.  QUALS are qualifiers indicating whether the (member)
   function is `const'.  */

static tree
cp_parser_exception_specification_opt (cp_parser* parser,
				       cp_parser_flags flags)
{
  cp_token *token;
  tree type_id_list;
  const char *saved_message;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);

  /* Is it a noexcept-specification?  */
  type_id_list
    = cp_parser_noexcept_specification_opt (parser, flags,
					    /*require_constexpr=*/true,
					    /*consumed_expr=*/NULL,
					    /*return_cond=*/false);
  if (type_id_list != NULL_TREE)
    return type_id_list;

  /* If it's not `throw', then there's no exception-specification.  */
  if (!cp_parser_is_keyword (token, RID_THROW))
    return NULL_TREE;

  location_t loc = token->location;

  /* Consume the `throw'.  */
  cp_lexer_consume_token (parser->lexer);

  /* Look for the `('.  */
  matching_parens parens;
  parens.require_open (parser);

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* If it's not a `)', then there is a type-id-list.  */
  if (token->type != CPP_CLOSE_PAREN)
    {
      /* Types may not be defined in an exception-specification.  */
      saved_message = parser->type_definition_forbidden_message;
      parser->type_definition_forbidden_message
	= G_("types may not be defined in an exception-specification");
      /* Parse the type-id-list.  */
      type_id_list = cp_parser_type_id_list (parser);
      /* Restore the saved message.  */
      parser->type_definition_forbidden_message = saved_message;

      if (cxx_dialect >= cxx17)
	{
	  error_at (loc, "ISO C++17 does not allow dynamic exception "
			 "specifications");
	  type_id_list = NULL_TREE;
	}
      else if (cxx_dialect >= cxx11)
	warning_at (loc, OPT_Wdeprecated,
		    "dynamic exception specifications are deprecated in "
		    "C++11");
    }
  /* In C++17, throw() is equivalent to noexcept (true).  throw()
     is deprecated in C++11 and above as well, but is still widely used,
     so don't warn about it yet.  */
  else if (cxx_dialect >= cxx17)
    type_id_list = noexcept_true_spec;
  else
    type_id_list = empty_except_spec;

  /* Look for the `)'.  */
  parens.require_close (parser);

  return type_id_list;
}

/* Parse an (optional) type-id-list.

   type-id-list:
     type-id ... [opt]
     type-id-list , type-id ... [opt]

   Returns a TREE_LIST.  The TREE_VALUE of each node is a TYPE,
   in the order that the types were presented.  */

static tree
cp_parser_type_id_list (cp_parser* parser)
{
  tree types = NULL_TREE;

  while (true)
    {
      cp_token *token;
      tree type;

      token = cp_lexer_peek_token (parser->lexer);

      /* Get the next type-id.  */
      type = cp_parser_type_id (parser);
      /* Check for invalid 'auto'.  */
      if (flag_concepts && type_uses_auto (type))
	{
	  error_at (token->location,
		    "invalid use of %<auto%> in exception-specification");
	  type = error_mark_node;
	}
      /* Parse the optional ellipsis. */
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
        {
          /* Consume the `...'. */
          cp_lexer_consume_token (parser->lexer);

          /* Turn the type into a pack expansion expression. */
          type = make_pack_expansion (type);
        }
      /* Add it to the list.  */
      types = add_exception_specifier (types, type, /*complain=*/1);
      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* If it is not a `,', we are done.  */
      if (token->type != CPP_COMMA)
	break;
      /* Consume the `,'.  */
      cp_lexer_consume_token (parser->lexer);
    }

  return nreverse (types);
}

/* Parse a try-block.

   try-block:
     try compound-statement handler-seq  */

static tree
cp_parser_try_block (cp_parser* parser)
{
  tree try_block;

  cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
  if (parser->in_function_body
      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
      && cxx_dialect < cxx20)
    pedwarn (input_location, OPT_Wc__20_extensions,
	     "%<try%> in %<constexpr%> function only "
	     "available with %<-std=c++20%> or %<-std=gnu++20%>");

  try_block = begin_try_block ();
  cp_parser_compound_statement (parser, NULL, BCS_TRY_BLOCK, false);
  finish_try_block (try_block);
  cp_parser_handler_seq (parser);
  finish_handler_sequence (try_block);

  return try_block;
}

/* Parse a function-try-block.

   function-try-block:
     try ctor-initializer [opt] function-body handler-seq  */

static void
cp_parser_function_try_block (cp_parser* parser)
{
  tree compound_stmt;
  tree try_block;

  /* Look for the `try' keyword.  */
  if (!cp_parser_require_keyword (parser, RID_TRY, RT_TRY))
    return;
  /* Let the rest of the front end know where we are.  */
  try_block = begin_function_try_block (&compound_stmt);
  /* Parse the function-body.  */
  cp_parser_ctor_initializer_opt_and_function_body
    (parser, /*in_function_try_block=*/true);
  /* We're done with the `try' part.  */
  finish_function_try_block (try_block);
  /* Parse the handlers.  */
  cp_parser_handler_seq (parser);
  /* We're done with the handlers.  */
  finish_function_handler_sequence (try_block, compound_stmt);
}

/* Parse a handler-seq.

   handler-seq:
     handler handler-seq [opt]  */

static void
cp_parser_handler_seq (cp_parser* parser)
{
  while (true)
    {
      cp_token *token;

      /* Parse the handler.  */
      cp_parser_handler (parser);
      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* If it's not `catch' then there are no more handlers.  */
      if (!cp_parser_is_keyword (token, RID_CATCH))
	break;
    }
}

/* Parse a handler.

   handler:
     catch ( exception-declaration ) compound-statement  */

static void
cp_parser_handler (cp_parser* parser)
{
  tree handler;
  tree declaration;

  cp_parser_require_keyword (parser, RID_CATCH, RT_CATCH);
  handler = begin_handler ();
  matching_parens parens;
  parens.require_open (parser);
  declaration = cp_parser_exception_declaration (parser);
  finish_handler_parms (declaration, handler);
  parens.require_close (parser);
  cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
  finish_handler (handler);
}

/* Parse an exception-declaration.

   exception-declaration:
     type-specifier-seq declarator
     type-specifier-seq abstract-declarator
     type-specifier-seq
     ...

   Returns a VAR_DECL for the declaration, or NULL_TREE if the
   ellipsis variant is used.  */

static tree
cp_parser_exception_declaration (cp_parser* parser)
{
  cp_decl_specifier_seq type_specifiers;
  cp_declarator *declarator;
  const char *saved_message;

  /* If it's an ellipsis, it's easy to handle.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    {
      /* Consume the `...' token.  */
      cp_lexer_consume_token (parser->lexer);
      return NULL_TREE;
    }

  /* Types may not be defined in exception-declarations.  */
  saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in exception-declarations");

  /* Parse the type-specifier-seq.  */
  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
				/*is_declaration=*/true,
				/*is_trailing_return=*/false,
				&type_specifiers);
  /* If it's a `)', then there is no declarator.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
    declarator = NULL;
  else
    declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_EITHER,
				       CP_PARSER_FLAGS_NONE,
				       /*ctor_dtor_or_conv_p=*/NULL,
				       /*parenthesized_p=*/NULL,
				       /*member_p=*/false,
				       /*friend_p=*/false,
				       /*static_p=*/false);

  /* Restore the saved message.  */
  parser->type_definition_forbidden_message = saved_message;

  if (!type_specifiers.any_specifiers_p)
    return error_mark_node;

  return grokdeclarator (declarator, &type_specifiers, CATCHPARM, 1, NULL);
}

/* Parse a throw-expression.

   throw-expression:
     throw assignment-expression [opt]

   Returns a THROW_EXPR representing the throw-expression.  */

static tree
cp_parser_throw_expression (cp_parser* parser)
{
  tree expression;
  cp_token* token;
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_parser_require_keyword (parser, RID_THROW, RT_THROW);
  token = cp_lexer_peek_token (parser->lexer);
  /* Figure out whether or not there is an assignment-expression
     following the "throw" keyword.  */
  if (token->type == CPP_COMMA
      || token->type == CPP_SEMICOLON
      || token->type == CPP_CLOSE_PAREN
      || token->type == CPP_CLOSE_SQUARE
      || token->type == CPP_CLOSE_BRACE
      || token->type == CPP_COLON)
    expression = NULL_TREE;
  else
    expression = cp_parser_assignment_expression (parser);

  /* Construct a location e.g.:
       throw x
       ^~~~~~~
     with caret == start at the start of the "throw" token, and
     the end at the end of the final token we consumed.  */
  location_t combined_loc = make_location (start_loc, start_loc,
					   parser->lexer);
  expression = build_throw (combined_loc, expression);

  return expression;
}

/* Parse a yield-expression.

   yield-expression:
     co_yield assignment-expression
     co_yield braced-init-list

   Returns a CO_YIELD_EXPR representing the yield-expression.  */

static tree
cp_parser_yield_expression (cp_parser* parser)
{
  tree expr;

  cp_token *token = cp_lexer_peek_token (parser->lexer);
  location_t kw_loc = token->location; /* Save for later.  */

  cp_parser_require_keyword (parser, RID_CO_YIELD, RT_CO_YIELD);

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      bool expr_non_constant_p;
      cp_lexer_set_source_position (parser->lexer);
      /* ??? : probably a moot point?  */
      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
      expr = cp_parser_braced_list (parser, &expr_non_constant_p);
    }
  else
    expr = cp_parser_assignment_expression (parser);

  if (expr == error_mark_node)
    return expr;

  return finish_co_yield_expr (kw_loc, expr);
}

/* GNU Extensions */

/* Parse an (optional) asm-specification.

   asm-specification:
     asm ( string-literal )

   If the asm-specification is present, returns a STRING_CST
   corresponding to the string-literal.  Otherwise, returns
   NULL_TREE.  */

static tree
cp_parser_asm_specification_opt (cp_parser* parser)
{
  /* Peek at the next token.  */
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  /* If the next token isn't the `asm' keyword, then there's no
     asm-specification.  */
  if (!cp_parser_is_keyword (token, RID_ASM))
    return NULL_TREE;

  /* Consume the `asm' token.  */
  cp_lexer_consume_token (parser->lexer);
  /* Look for the `('.  */
  matching_parens parens;
  parens.require_open (parser);

  /* Look for the string-literal.  */
  tree asm_specification = cp_parser_string_literal (parser,
						     /*translate=*/false,
						     /*wide_ok=*/false);

  /* Look for the `)'.  */
  parens.require_close (parser);

  return asm_specification;
}

/* Parse an asm-operand-list.

   asm-operand-list:
     asm-operand
     asm-operand-list , asm-operand

   asm-operand:
     string-literal ( expression )
     [ string-literal ] string-literal ( expression )

   Returns a TREE_LIST representing the operands.  The TREE_VALUE of
   each node is the expression.  The TREE_PURPOSE is itself a
   TREE_LIST whose TREE_PURPOSE is a STRING_CST for the bracketed
   string-literal (or NULL_TREE if not present) and whose TREE_VALUE
   is a STRING_CST for the string literal before the parenthesis. Returns
   ERROR_MARK_NODE if any of the operands are invalid.  */

static tree
cp_parser_asm_operand_list (cp_parser* parser)
{
  tree asm_operands = NULL_TREE;
  bool invalid_operands = false;

  while (true)
    {
      tree name;

      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
	{
	  /* Consume the `[' token.  */
	  cp_lexer_consume_token (parser->lexer);
	  /* Read the operand name.  */
	  name = cp_parser_identifier (parser);
	  if (name != error_mark_node)
	    name = build_string (IDENTIFIER_LENGTH (name),
				 IDENTIFIER_POINTER (name));
	  /* Look for the closing `]'.  */
	  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
	}
      else
	name = NULL_TREE;
      /* Look for the string-literal.  */
      tree string_literal = cp_parser_string_literal (parser,
						      /*translate=*/false,
						      /*wide_ok=*/false);

      /* Look for the `('.  */
      matching_parens parens;
      parens.require_open (parser);
      /* Parse the expression.  */
      tree expression = cp_parser_expression (parser);
      /* Look for the `)'.  */
      parens.require_close (parser);

      if (name == error_mark_node
	  || string_literal == error_mark_node
	  || expression == error_mark_node)
        invalid_operands = true;

      /* Add this operand to the list.  */
      asm_operands = tree_cons (build_tree_list (name, string_literal),
				expression,
				asm_operands);
      /* If the next token is not a `,', there are no more
	 operands.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Consume the `,'.  */
      cp_lexer_consume_token (parser->lexer);
    }

  return invalid_operands ? error_mark_node : nreverse (asm_operands);
}

/* Parse an asm-clobber-list.

   asm-clobber-list:
     string-literal
     asm-clobber-list , string-literal

   Returns a TREE_LIST, indicating the clobbers in the order that they
   appeared.  The TREE_VALUE of each node is a STRING_CST.  */

static tree
cp_parser_asm_clobber_list (cp_parser* parser)
{
  tree clobbers = NULL_TREE;

  while (true)
    {
      /* Look for the string literal.  */
      tree string_literal = cp_parser_string_literal (parser,
						      /*translate=*/false,
						      /*wide_ok=*/false);
      /* Add it to the list.  */
      clobbers = tree_cons (NULL_TREE, string_literal, clobbers);
      /* If the next token is not a `,', then the list is
	 complete.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Consume the `,' token.  */
      cp_lexer_consume_token (parser->lexer);
    }

  return clobbers;
}

/* Parse an asm-label-list.

   asm-label-list:
     identifier
     asm-label-list , identifier

   Returns a TREE_LIST, indicating the labels in the order that they
   appeared.  The TREE_VALUE of each node is a label.  */

static tree
cp_parser_asm_label_list (cp_parser* parser)
{
  tree labels = NULL_TREE;

  while (true)
    {
      tree identifier, label, name;

      /* Look for the identifier.  */
      identifier = cp_parser_identifier (parser);
      if (!error_operand_p (identifier))
        {
	  label = lookup_label (identifier);
	  if (TREE_CODE (label) == LABEL_DECL)
	    {
	      TREE_USED (label) = 1;
	      check_goto (label);
	      name = build_string (IDENTIFIER_LENGTH (identifier),
				   IDENTIFIER_POINTER (identifier));
	      labels = tree_cons (name, label, labels);
	    }
	}
      /* If the next token is not a `,', then the list is
	 complete.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      /* Consume the `,' token.  */
      cp_lexer_consume_token (parser->lexer);
    }

  return nreverse (labels);
}

/* Return TRUE iff the next tokens in the stream are possibly the
   beginning of a GNU extension attribute. */

static bool
cp_next_tokens_can_be_gnu_attribute_p (cp_parser *parser)
{
  return cp_nth_tokens_can_be_gnu_attribute_p (parser, 1);
}

/* Return TRUE iff the next tokens in the stream are possibly the
   beginning of a standard C++-11 attribute specifier.  */

static bool
cp_next_tokens_can_be_std_attribute_p (cp_parser *parser)
{
  return cp_nth_tokens_can_be_std_attribute_p (parser, 1);
}

/* Return TRUE iff the next Nth tokens in the stream are possibly the
   beginning of a standard C++-11 attribute specifier.  */

static bool
cp_nth_tokens_can_be_std_attribute_p (cp_parser *parser, size_t n)
{
  cp_token *token = cp_lexer_peek_nth_token (parser->lexer, n);

  return (cxx_dialect >= cxx11
	  && ((token->type == CPP_KEYWORD && token->keyword == RID_ALIGNAS)
	      || (token->type == CPP_OPEN_SQUARE
		  && (token = cp_lexer_peek_nth_token (parser->lexer, n + 1))
		  && token->type == CPP_OPEN_SQUARE)));
}

/* Return TRUE iff the next Nth tokens in the stream are possibly the
   beginning of a GNU extension attribute.  */

static bool
cp_nth_tokens_can_be_gnu_attribute_p (cp_parser *parser, size_t n)
{
  cp_token *token = cp_lexer_peek_nth_token (parser->lexer, n);

  return token->type == CPP_KEYWORD && token->keyword == RID_ATTRIBUTE;
}

/* Return true iff the next tokens can be the beginning of either a
   GNU attribute list, or a standard C++11 attribute sequence.  */

static bool
cp_next_tokens_can_be_attribute_p (cp_parser *parser)
{
  return (cp_next_tokens_can_be_gnu_attribute_p (parser)
	  || cp_next_tokens_can_be_std_attribute_p (parser));
}

/* Return true iff the next Nth tokens can be the beginning of either
   a GNU attribute list, or a standard C++11 attribute sequence.  */

static bool
cp_nth_tokens_can_be_attribute_p (cp_parser *parser, size_t n)
{
  return (cp_nth_tokens_can_be_gnu_attribute_p (parser, n)
	  || cp_nth_tokens_can_be_std_attribute_p (parser, n));
}

/* Parse either a standard C++-11 attribute-specifier-seq, or a series
   of GNU attributes, or return NULL.  */

static tree
cp_parser_attributes_opt (cp_parser *parser)
{
  tree attrs = NULL_TREE;
  while (true)
    {
      if (cp_next_tokens_can_be_gnu_attribute_p (parser))
	attrs = attr_chainon (attrs, cp_parser_gnu_attributes_opt (parser));
      else if (cp_next_tokens_can_be_std_attribute_p (parser))
	attrs = attr_chainon (attrs, cp_parser_std_attribute_spec_seq (parser));
      else
	break;
    }
  return attrs;
}

/* Parse an (optional) series of attributes.

   attributes:
     attributes attribute

   attribute:
     __attribute__ (( attribute-list [opt] ))

   The return value is as for cp_parser_gnu_attribute_list.  */

static tree
cp_parser_gnu_attributes_opt (cp_parser* parser)
{
  tree attributes = NULL_TREE;

  auto cleanup = make_temp_override
    (parser->auto_is_implicit_function_template_parm_p, false);

  while (true)
    {
      cp_token *token;
      tree attribute_list;
      bool ok = true;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* If it's not `__attribute__', then we're done.  */
      if (token->keyword != RID_ATTRIBUTE)
	break;

      /* Consume the `__attribute__' keyword.  */
      cp_lexer_consume_token (parser->lexer);
      /* Look for the two `(' tokens.  */
      matching_parens outer_parens;
      if (!outer_parens.require_open (parser))
	ok = false;
      matching_parens inner_parens;
      if (!inner_parens.require_open (parser))
	ok = false;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      if (token->type != CPP_CLOSE_PAREN)
	/* Parse the attribute-list.  */
	attribute_list = cp_parser_gnu_attribute_list (parser);
      else
	/* If the next token is a `)', then there is no attribute
	   list.  */
	attribute_list = NULL;

      /* Look for the two `)' tokens.  */
      if (!inner_parens.require_close (parser))
	ok = false;
      if (!outer_parens.require_close (parser))
	ok = false;
      if (!ok)
	cp_parser_skip_to_end_of_statement (parser);

      /* Add these new attributes to the list.  */
      attributes = attr_chainon (attributes, attribute_list);
    }

  return attributes;
}

/* Parse a GNU attribute-list.

   attribute-list:
     attribute
     attribute-list , attribute

   attribute:
     identifier
     identifier ( identifier )
     identifier ( identifier , expression-list )
     identifier ( expression-list )

   Returns a TREE_LIST, or NULL_TREE on error.  Each node corresponds
   to an attribute.  The TREE_PURPOSE of each node is the identifier
   indicating which attribute is in use.  The TREE_VALUE represents
   the arguments, if any.  */

static tree
cp_parser_gnu_attribute_list (cp_parser* parser, bool exactly_one /* = false */)
{
  tree attribute_list = NULL_TREE;
  bool save_translate_strings_p = parser->translate_strings_p;

  /* Don't create wrapper nodes within attributes: the
     handlers don't know how to handle them.  */
  auto_suppress_location_wrappers sentinel;

  parser->translate_strings_p = false;
  while (true)
    {
      cp_token *token;
      tree identifier;
      tree attribute;

      /* Look for the identifier.  We also allow keywords here; for
	 example `__attribute__ ((const))' is legal.  */
      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_NAME
	  || token->type == CPP_KEYWORD)
	{
	  tree arguments = NULL_TREE;

	  /* Consume the token, but save it since we need it for the
	     SIMD enabled function parsing.  */
	  cp_token *id_token = cp_lexer_consume_token (parser->lexer);

	  /* Save away the identifier that indicates which attribute
	     this is.  */
	  identifier = (token->type == CPP_KEYWORD)
	    /* For keywords, use the canonical spelling, not the
	       parsed identifier.  */
	    ? ridpointers[(int) token->keyword]
	    : id_token->u.value;

	  identifier = canonicalize_attr_name (identifier);
	  attribute = build_tree_list (identifier, NULL_TREE);

	  /* Peek at the next token.  */
	  token = cp_lexer_peek_token (parser->lexer);
	  /* If it's an `(', then parse the attribute arguments.  */
	  if (token->type == CPP_OPEN_PAREN)
	    {
	      vec<tree, va_gc> *vec;
	      int attr_flag = (attribute_takes_identifier_p (identifier)
			       ? id_attr : normal_attr);
	      if (is_attribute_p ("assume", identifier))
		attr_flag = assume_attr;
	      vec = cp_parser_parenthesized_expression_list
		    (parser, attr_flag, /*cast_p=*/false,
		    /*allow_expansion_p=*/false,
		    /*non_constant_p=*/NULL);
	      if (vec == NULL)
		arguments = error_mark_node;
	      else
		{
		  arguments = build_tree_list_vec (vec);
		  release_tree_vector (vec);
		}
	      /* Save the arguments away.  */
	      TREE_VALUE (attribute) = arguments;
	    }

	  if (arguments != error_mark_node)
	    {
	      /* Add this attribute to the list.  */
	      TREE_CHAIN (attribute) = attribute_list;
	      attribute_list = attribute;
	    }

	  token = cp_lexer_peek_token (parser->lexer);
	}
      /* Unless EXACTLY_ONE is set look for more attributes.
	 If the next token isn't a `,', we're done.  */
      if (exactly_one || token->type != CPP_COMMA)
	break;

      /* Consume the comma and keep going.  */
      cp_lexer_consume_token (parser->lexer);
    }
  parser->translate_strings_p = save_translate_strings_p;

  /* We built up the list in reverse order.  */
  return nreverse (attribute_list);
}

/* Parse arguments of omp::directive attribute.

   ( directive-name ,[opt] clause-list[opt] )

   For directive just remember the first/last tokens for subsequent
   parsing.  */

static void
cp_parser_omp_directive_args (cp_parser *parser, tree attribute)
{
  cp_token *first = cp_lexer_peek_nth_token (parser->lexer, 2);
  if (first->type == CPP_CLOSE_PAREN)
    {
      cp_lexer_consume_token (parser->lexer);
      error_at (first->location, "expected OpenMP directive name");
      cp_lexer_consume_token (parser->lexer);
      TREE_VALUE (attribute) = NULL_TREE;
      return;
    }
  size_t n = cp_parser_skip_balanced_tokens (parser, 1);
  if (n == 1)
    {
      cp_lexer_consume_token (parser->lexer);
      error_at (first->location, "expected attribute argument as balanced "
				 "token sequence");
      TREE_VALUE (attribute) = NULL_TREE;
      return;
    }
  for (n = n - 2; n; --n)
    cp_lexer_consume_token (parser->lexer);
  cp_token *last = cp_lexer_peek_token (parser->lexer);
  cp_lexer_consume_token (parser->lexer);
  tree arg = make_node (DEFERRED_PARSE);
  DEFPARSE_TOKENS (arg) = cp_token_cache_new (first, last);
  DEFPARSE_INSTANTIATIONS (arg) = nullptr;
  TREE_VALUE (attribute) = tree_cons (NULL_TREE, arg, TREE_VALUE (attribute));
}

/* Parse arguments of omp::sequence attribute.

   ( omp::[opt] directive-attr [ , omp::[opt] directive-attr ]... )  */

static void
cp_parser_omp_sequence_args (cp_parser *parser, tree attribute)
{
  matching_parens parens;
  parens.consume_open (parser);
  do
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_NAME
	  && token->u.value == omp_identifier
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_SCOPE))
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  token = cp_lexer_peek_token (parser->lexer);
	}
      bool directive = false;
      const char *p;
      if (token->type != CPP_NAME)
	p = "";
      else
	p = IDENTIFIER_POINTER (token->u.value);
      if (strcmp (p, "directive") == 0)
	directive = true;
      else if (strcmp (p, "sequence") != 0)
	{
	  error_at (token->location, "expected %<directive%> or %<sequence%>");
	  cp_parser_skip_to_closing_parenthesis (parser,
						 /*recovering=*/true,
						 /*or_comma=*/true,
						 /*consume_paren=*/false);
	  if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	    break;
	  cp_lexer_consume_token (parser->lexer);
	}
      cp_lexer_consume_token (parser->lexer);
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
	cp_parser_required_error (parser, RT_OPEN_PAREN, false,
				  UNKNOWN_LOCATION);
      else if (directive)
	cp_parser_omp_directive_args (parser, attribute);
      else
	cp_parser_omp_sequence_args (parser, attribute);
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      cp_lexer_consume_token (parser->lexer);
    }
  while (1);
  if (!parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, true, false,
					   /*consume_paren=*/true);
}

/*  Parse a standard C++11 attribute.

    The returned representation is a TREE_LIST which TREE_PURPOSE is
    the scoped name of the attribute, and the TREE_VALUE is its
    arguments list.

    Note that the scoped name of the attribute is itself a TREE_LIST
    which TREE_PURPOSE is the namespace of the attribute, and
    TREE_VALUE its name.  This is unlike a GNU attribute -- as parsed
    by cp_parser_gnu_attribute_list -- that doesn't have any namespace
    and which TREE_PURPOSE is directly the attribute name.

    Clients of the attribute code should use get_attribute_namespace
    and get_attribute_name to get the actual namespace and name of
    attributes, regardless of their being GNU or C++11 attributes.

    attribute:
      attribute-token attribute-argument-clause [opt]

    attribute-token:
      identifier
      attribute-scoped-token

    attribute-scoped-token:
      attribute-namespace :: identifier

    attribute-namespace:
      identifier

    attribute-argument-clause:
      ( balanced-token-seq )

    balanced-token-seq:
      balanced-token [opt]
      balanced-token-seq balanced-token

    balanced-token:
      ( balanced-token-seq )
      [ balanced-token-seq ]
      { balanced-token-seq }.  */

static tree
cp_parser_std_attribute (cp_parser *parser, tree attr_ns)
{
  tree attribute, attr_id = NULL_TREE, arguments;
  cp_token *token;

  auto cleanup = make_temp_override
    (parser->auto_is_implicit_function_template_parm_p, false);

  /* First, parse name of the attribute, a.k.a attribute-token.  */

  token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_NAME)
    attr_id = token->u.value;
  else if (token->type == CPP_KEYWORD)
    attr_id = ridpointers[(int) token->keyword];
  else if (token->flags & NAMED_OP)
    attr_id = get_identifier (cpp_type2name (token->type, token->flags));

  if (attr_id == NULL_TREE)
    return NULL_TREE;

  cp_lexer_consume_token (parser->lexer);

  token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_SCOPE)
    {
      /* We are seeing a scoped attribute token.  */

      cp_lexer_consume_token (parser->lexer);
      if (attr_ns)
	error_at (token->location, "attribute using prefix used together "
				   "with scoped attribute token");
      attr_ns = attr_id;

      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_NAME)
	attr_id = token->u.value;
      else if (token->type == CPP_KEYWORD)
	attr_id = ridpointers[(int) token->keyword];
      else if (token->flags & NAMED_OP)
	attr_id = get_identifier (cpp_type2name (token->type, token->flags));
      else
	{
	  error_at (token->location,
		    "expected an identifier for the attribute name");
	  return error_mark_node;
	}
      cp_lexer_consume_token (parser->lexer);

      attr_ns = canonicalize_attr_name (attr_ns);
      attr_id = canonicalize_attr_name (attr_id);
      attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
				   NULL_TREE);
      token = cp_lexer_peek_token (parser->lexer);
    }
  else if (attr_ns)
    {
      attr_ns = canonicalize_attr_name (attr_ns);
      attr_id = canonicalize_attr_name (attr_id);
      attribute = build_tree_list (build_tree_list (attr_ns, attr_id),
				   NULL_TREE);
    }
  else
    {
      attr_id = canonicalize_attr_name (attr_id);
      attribute = build_tree_list (build_tree_list (NULL_TREE, attr_id),
				   NULL_TREE);

      /* We used to treat C++11 noreturn attribute as equivalent to GNU's,
	 but no longer: we have to be able to tell [[noreturn]] and
	 __attribute__((noreturn)) apart.  */
      /* C++14 deprecated attribute is equivalent to GNU's.  */
      if (is_attribute_p ("deprecated", attr_id))
	TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
      /* C++17 fallthrough attribute is equivalent to GNU's.  */
      else if (is_attribute_p ("fallthrough", attr_id))
	TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
      /* C++23 assume attribute is equivalent to GNU's.  */
      else if (is_attribute_p ("assume", attr_id))
	TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
      /* Transactional Memory TS optimize_for_synchronized attribute is
	 equivalent to GNU transaction_callable.  */
      else if (is_attribute_p ("optimize_for_synchronized", attr_id))
	TREE_PURPOSE (attribute)
	  = get_identifier ("transaction_callable");
      /* Transactional Memory attributes are GNU attributes.  */
      else if (tm_attr_to_mask (attr_id))
	TREE_PURPOSE (attribute) = attr_id;
    }

  /* Now parse the optional argument clause of the attribute.  */

  if (token->type != CPP_OPEN_PAREN)
    {
      if ((flag_openmp || flag_openmp_simd)
	  && attr_ns == omp_identifier
	  && (is_attribute_p ("directive", attr_id)
	      || is_attribute_p ("sequence", attr_id)))
	{
	  error_at (token->location, "%<omp::%E%> attribute requires argument",
		    attr_id);
	  return NULL_TREE;
	}
      return attribute;
    }

  {
    vec<tree, va_gc> *vec;
    int attr_flag = normal_attr;

    /* Maybe we don't expect to see any arguments for this attribute.  */
    const attribute_spec *as
      = lookup_attribute_spec (TREE_PURPOSE (attribute));
    if (as && as->max_length == 0)
      {
	error_at (token->location, "%qE attribute does not take any arguments",
		  attr_id);
	cp_parser_skip_to_closing_parenthesis (parser,
					       /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);
	return error_mark_node;
      }

    if (is_attribute_p ("assume", attr_id)
	&& (attr_ns == NULL_TREE || attr_ns == gnu_identifier))
      /* The assume attribute needs special handling of the argument.  */
      attr_flag = assume_attr;
    else if (attr_ns == gnu_identifier
	     && attribute_takes_identifier_p (attr_id))
      /* A GNU attribute that takes an identifier in parameter.  */
      attr_flag = id_attr;

    /* If this is a fake attribute created to handle -Wno-attributes,
       we must skip parsing the arguments.  */
    if (as == NULL || attribute_ignored_p (as))
      {
	if ((flag_openmp || flag_openmp_simd) && attr_ns == omp_identifier)
	  {
	    if (is_attribute_p ("directive", attr_id))
	      {
		cp_parser_omp_directive_args (parser, attribute);
		return attribute;
	      }
	    else if (is_attribute_p ("sequence", attr_id))
	      {
		TREE_VALUE (TREE_PURPOSE (attribute))
		  = get_identifier ("directive");
		cp_parser_omp_sequence_args (parser, attribute);
		TREE_VALUE (attribute) = nreverse (TREE_VALUE (attribute));
		return attribute;
	      }
	  }

	/* For unknown attributes, just skip balanced tokens instead of
	   trying to parse the arguments.  */
	for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1; n; --n)
	  cp_lexer_consume_token (parser->lexer);
	return attribute;
      }

    vec = cp_parser_parenthesized_expression_list
      (parser, attr_flag, /*cast_p=*/false,
       /*allow_expansion_p=*/true,
       /*non_constant_p=*/NULL);
    if (vec == NULL)
      arguments = error_mark_node;
    else
      {
	if (vec->is_empty ())
	  /* e.g. [[attr()]].  */
	  error_at (token->location, "parentheses must be omitted if "
		    "%qE attribute argument list is empty",
		    attr_id);
	arguments = build_tree_list_vec (vec);
	release_tree_vector (vec);
      }

    if (arguments == error_mark_node)
      attribute = error_mark_node;
    else
      TREE_VALUE (attribute) = arguments;
  }

  return attribute;
}

/* Warn if the attribute ATTRIBUTE appears more than once in the
   attribute-list ATTRIBUTES.  This used to be enforced for certain
   attributes, but the restriction was removed in P2156.
   LOC is the location of ATTRIBUTE.  Returns true if ATTRIBUTE was not
   found in ATTRIBUTES.  */

static bool
cp_parser_check_std_attribute (location_t loc, tree attributes, tree attribute)
{
  static auto alist = { "noreturn", "deprecated", "nodiscard", "maybe_unused",
			"likely", "unlikely", "fallthrough",
			"no_unique_address", "carries_dependency" };
  if (attributes)
    for (const auto &a : alist)
      if (is_attribute_p (a, get_attribute_name (attribute))
	  && is_attribute_namespace_p ("", attribute)
	  && lookup_attribute ("", a, attributes))
	{
	  if (!from_macro_expansion_at (loc))
	    warning_at (loc, OPT_Wattributes, "attribute %qs specified "
			"multiple times", a);
	  return false;
	}
  return true;
}

/* Parse a list of standard C++-11 attributes.

   attribute-list:
     attribute [opt]
     attribute-list , attribute[opt]
     attribute ...
     attribute-list , attribute ...
*/

static tree
cp_parser_std_attribute_list (cp_parser *parser, tree attr_ns)
{
  tree attributes = NULL_TREE, attribute = NULL_TREE;
  cp_token *token = NULL;

  while (true)
    {
      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
      attribute = cp_parser_std_attribute (parser, attr_ns);
      if (attribute == error_mark_node)
	break;
      if (attribute != NULL_TREE)
	{
	  if (cp_parser_check_std_attribute (loc, attributes, attribute))
	    {
	      TREE_CHAIN (attribute) = attributes;
	      attributes = attribute;
	    }
	}
      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_ELLIPSIS)
	{
	  cp_lexer_consume_token (parser->lexer);
	  if (attribute == NULL_TREE)
	    error_at (token->location,
		      "expected attribute before %<...%>");
	  else
	    {
	      tree pack = make_pack_expansion (TREE_VALUE (attribute));
	      if (pack == error_mark_node)
		return error_mark_node;
	      TREE_VALUE (attribute) = pack;
	    }
	  token = cp_lexer_peek_token (parser->lexer);
	}
      if (token->type != CPP_COMMA)
	break;
      cp_lexer_consume_token (parser->lexer);
    }
  attributes = nreverse (attributes);
  return attributes;
}

/* Optionally parse a C++20 contract role. A NULL return means that no
   contract role was specified.

    contract-role:
      % default
      % identifier

   If the identifier does not name a known contract role, it will
   be assumed to be default. Returns the identifier for the role
   token.  */

static tree
cp_parser_contract_role (cp_parser *parser)
{
  gcc_assert (cp_lexer_next_token_is (parser->lexer, CPP_MOD));
  cp_lexer_consume_token (parser->lexer);

  cp_token *token = cp_lexer_peek_token (parser->lexer);
  tree role_id = NULL_TREE;
  if (token->type == CPP_NAME)
    role_id = token->u.value;
  else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
    role_id = get_identifier ("default");
  else
    {
      error_at (token->location, "expected contract-role");
      return error_mark_node;
    }
  cp_lexer_consume_token (parser->lexer);

  /* FIXME: Warn about invalid/unknown roles?  */
  return role_id;
}

/* Parse an optional contract mode.

     contract-mode:
	contract-semantic
	[contract-level] [contract-role]

     contract-semantic:
       check_never_continue
       check_maybe_continue
       check_always_continue

     contract-level:
       default
       audit
       axiom

     contract-role:
       default
       identifier

   This grammar is taken from P1332R0. During parsing, this sets options
   on the MODE object to determine the configuration of the contract.

   Returns a tree containing the identifiers used in the configuration.
   This is either an IDENTIFIER with the literal semantic or a TREE_LIST
   whose TREE_VALUE is the contract-level and whose TREE_PURPOSE is the
   contract-role, if any. NULL_TREE is returned if no information is
   given (i.e., all defaults selected).  */

static tree
cp_parser_contract_mode_opt (cp_parser *parser,
			     bool postcondition_p)
{
  /* The mode is empty; the level and role are default.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    return NULL_TREE;

  /* There is only a role; the level is default.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
    {
      tree role_id = cp_parser_contract_role (parser);
      return build_tree_list (role_id, get_identifier ("default"));
    }

  /* Otherwise, match semantic or level.  */
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  contract_level level = CONTRACT_INVALID;
  contract_semantic semantic = CCS_INVALID;
  tree config_id;
  if (token->type == CPP_NAME)
    {
      config_id = token->u.value;

      /* Either a named level, a concrete semantic, or an identifier
	 for a postcondition.  */
      const char *ident = IDENTIFIER_POINTER (token->u.value);
      level = map_contract_level (ident);
      semantic = map_contract_semantic (ident);

      /* The identifier is the return value for a postcondition.  */
      if (level == CONTRACT_INVALID && semantic == CCS_INVALID
	  && postcondition_p)
	return NULL_TREE;
    }
  else if (token->type == CPP_KEYWORD && token->keyword == RID_DEFAULT)
    {
      config_id = get_identifier ("default");
      level = CONTRACT_DEFAULT;
    }
  else
    {
      /* We got some other token other than a ':'.  */
      error_at (token->location, "expected contract semantic or level");
      return NULL_TREE;
    }

  /* Consume the literal semantic or level token.  */
  cp_lexer_consume_token (parser->lexer);

  if (semantic == CCS_INVALID && level == CONTRACT_INVALID)
    {
      error_at (token->location,
		"expected contract level: "
		"%<default%>, %<audit%>, or %<axiom%>");
      return NULL_TREE;
    }

  /* We matched an explicit semantic. */
  if (semantic != CCS_INVALID)
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
	{
	  error ("invalid use of contract role for explicit semantic");
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	}
      return config_id;
    }

  /* We matched a level, there may be a role; otherwise this is default.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_MOD))
    {
      tree role_id = cp_parser_contract_role (parser);
      return build_tree_list (role_id, config_id);
    }

  return build_tree_list (NULL_TREE, config_id);
}

static tree
find_error (tree *tp, int *, void *)
{
  if (*tp == error_mark_node)
    return *tp;
  return NULL_TREE;
}

static bool
contains_error_p (tree t)
{
  return walk_tree (&t, find_error, NULL, NULL);
}

/* Parse a standard C++20 contract attribute specifier.

  contract-attribute-specifier:
    [ [ assert contract-level [opt] : conditional-expression ] ]
    [ [ pre contract-level [opt] : conditional-expression ] ]
    [ [ post contract-level [opt] identifier [opt] : conditional-expression ] ]

   For free functions, we cannot determine the type of the postcondition
   identifier because the we haven't called grokdeclarator yet. In those
   cases we parse the postcondition as if the identifier was declared as
   'auto <identifier>'. We then instantiate the postcondition once the
   return type is known.

   For member functions, contracts are in the complete-class context, so the
   parse is deferred. We also have the return type avaialable (unless it's
   deduced), so we don't need to parse the postcondition in terms of a
   placeholder.  */

static tree
cp_parser_contract_attribute_spec (cp_parser *parser, tree attribute)
{
  gcc_assert (contract_attribute_p (attribute));
  cp_token *token = cp_lexer_consume_token (parser->lexer);
  location_t loc = token->location;

  bool assertion_p = is_attribute_p ("assert", attribute);
  bool postcondition_p = is_attribute_p ("post", attribute);

  /* Parse the optional mode.  */
  tree mode = cp_parser_contract_mode_opt (parser, postcondition_p);

  /* Check for postcondition identifiers.  */
  cp_expr identifier;
  if (postcondition_p && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    identifier = cp_parser_identifier (parser);
  if (identifier == error_mark_node)
    return error_mark_node;

  cp_parser_require (parser, CPP_COLON, RT_COLON);

  /* Defer the parsing of pre/post contracts inside class definitions.  */
  tree contract;
  if (!assertion_p &&
      current_class_type &&
      TYPE_BEING_DEFINED (current_class_type))
    {
      /* Skip until we reach an unenclose ']'. If we ran into an unnested ']'
	 that doesn't close the attribute, return an error and let the attribute
	 handling code emit an error for missing ']]'.  */
      cp_token *first = cp_lexer_peek_token (parser->lexer);
      cp_parser_skip_to_closing_parenthesis_1 (parser,
					       /*recovering=*/false,
					       CPP_CLOSE_SQUARE,
					       /*consume_paren=*/false);
      if (cp_lexer_peek_token (parser->lexer)->type != CPP_CLOSE_SQUARE
	  || cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_CLOSE_SQUARE)
	return error_mark_node;
      cp_token *last = cp_lexer_peek_token (parser->lexer);

      /* Build a deferred-parse node.  */
      tree condition = make_node (DEFERRED_PARSE);
      DEFPARSE_TOKENS (condition) = cp_token_cache_new (first, last);
      DEFPARSE_INSTANTIATIONS (condition) = NULL;

      /* And its corresponding contract.  */
      contract = grok_contract (attribute, mode, identifier, condition, loc);
    }
  else
    {
      /* Enable location wrappers when parsing contracts.  */
      auto suppression = make_temp_override (suppress_location_wrappers, 0);

      /* Build a fake variable for the result identifier.  */
      tree result = NULL_TREE;
      if (identifier)
	{
	  begin_scope (sk_block, NULL_TREE);
	  result = make_postcondition_variable (identifier);
	  ++processing_template_decl;
	}

      /* Parse the condition, ensuring that parameters or the return variable
	 aren't flagged for use outside the body of a function.  */
      ++processing_contract_condition;
      cp_expr condition = cp_parser_conditional_expression (parser);
      --processing_contract_condition;

      /* Try to recover from errors by scanning up to the end of the
	 attribute.  Sometimes we get partially parsed expressions, so
	 we need to search the condition for errors.  */
      if (contains_error_p (condition))
	cp_parser_skip_up_to_closing_square_bracket (parser);

      /* Build the contract.  */
      contract = grok_contract (attribute, mode, result, condition, loc);

      /* Leave our temporary scope for the postcondition result.  */
      if (result)
	{
	  --processing_template_decl;
	  pop_bindings_and_leave_scope ();
	}
    }

  if (!flag_contracts)
    {
      error_at (loc, "contracts are only available with %<-fcontracts%>");
      return error_mark_node;
    }

  return finish_contract_attribute (attribute, contract);
}

/* Parse a contract condition for a deferred contract.  */

void cp_parser_late_contract_condition (cp_parser *parser,
					tree fn,
					tree attribute)
{
  tree contract = TREE_VALUE (TREE_VALUE (attribute));

  /* Make sure we've gotten something that hasn't been parsed yet or that
     we're not parsing an invalid contract.  */
  tree condition = CONTRACT_CONDITION (contract);
  if (TREE_CODE (condition) != DEFERRED_PARSE)
    return;

  tree identifier = NULL_TREE;
  if (TREE_CODE (contract) == POSTCONDITION_STMT)
    identifier = POSTCONDITION_IDENTIFIER (contract);

  /* Build a fake variable for the result identifier.  */
  tree result = NULL_TREE;
  if (identifier)
    {
      /* TODO: Can we guarantee that the identifier has a location? */
      location_t loc = cp_expr_location (contract);
      tree type = TREE_TYPE (TREE_TYPE (fn));
      if (!check_postcondition_result (fn, type, loc))
	{
	  invalidate_contract (contract);
	  return;
	}

      begin_scope (sk_block, NULL_TREE);
      result = make_postcondition_variable (identifier, type);
      ++processing_template_decl;
    }

  /* 'this' is not allowed in preconditions of constructors or in postconditions
     of destructors.  Note that the previous value of this variable is
     established by the calling function, so we need to save it here.  */
  tree saved_ccr = current_class_ref;
  tree saved_ccp = current_class_ptr;
  if ((DECL_CONSTRUCTOR_P (fn) && PRECONDITION_P (contract)) ||
       (DECL_DESTRUCTOR_P (fn) && POSTCONDITION_P (contract)))
    {
      current_class_ref = current_class_ptr = NULL_TREE;
      parser->local_variables_forbidden_p |= THIS_FORBIDDEN;
    }

  push_unparsed_function_queues (parser);

  /* Push the saved tokens onto the parser's lexer stack.  */
  cp_token_cache *tokens = DEFPARSE_TOKENS (condition);
  cp_parser_push_lexer_for_tokens (parser, tokens);

  /* Parse the condition, ensuring that parameters or the return variable
     aren't flagged for use outside the body of a function.  */
  ++processing_contract_condition;
  condition = cp_parser_conditional_expression (parser);
  --processing_contract_condition;

  /* Revert to the main lexer.  */
  cp_parser_pop_lexer (parser);

  /* Restore the queue.  */
  pop_unparsed_function_queues (parser);

  current_class_ref = saved_ccr;
  current_class_ptr = saved_ccp;

  /* Commit to changes.  */
  update_late_contract (contract, result, condition);

  /* Leave our temporary scope for the postcondition result.  */
  if (result)
    {
      --processing_template_decl;
      pop_bindings_and_leave_scope ();
    }
}

/* Parse a standard C++-11 attribute specifier.

   attribute-specifier:
     [ [ attribute-using-prefix [opt] attribute-list ] ]
     contract-attribute-specifier
     alignment-specifier

   attribute-using-prefix:
     using attribute-namespace :

   alignment-specifier:
     alignas ( type-id ... [opt] )
     alignas ( alignment-expression ... [opt] ).

   Extensions for contracts:

   contract-attribute-specifier:
     [ [ assert :  contract-mode [opt] : conditional-expression ] ]
     [ [ pre :  contract-mode [opt] : conditional-expression ] ]
     [ [ post :  contract-mode [opt] identifier [opt] :
	 conditional-expression ] ]  */

static tree
cp_parser_std_attribute_spec (cp_parser *parser)
{
  tree attributes = NULL_TREE;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  if (token->type == CPP_OPEN_SQUARE
      && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_OPEN_SQUARE)
    {
      tree attr_ns = NULL_TREE;
      tree attr_name = NULL_TREE;

      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);

      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_NAME)
	{
	  attr_name = token->u.value;
	  attr_name = canonicalize_attr_name (attr_name);
	}

      /* Handle contract-attribute-specs specially.  */
      if (attr_name && contract_attribute_p (attr_name))
	{
	  tree attrs = cp_parser_contract_attribute_spec (parser, attr_name);
	  if (attrs != error_mark_node)
	    attributes = attrs;
	  goto finish_attrs;
	}

      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
	{
	  token = cp_lexer_peek_nth_token (parser->lexer, 2);
	  if (token->type == CPP_NAME)
	    attr_ns = token->u.value;
	  else if (token->type == CPP_KEYWORD)
	    attr_ns = ridpointers[(int) token->keyword];
	  else if (token->flags & NAMED_OP)
	    attr_ns = get_identifier (cpp_type2name (token->type,
						     token->flags));
	  if (attr_ns
	      && cp_lexer_nth_token_is (parser->lexer, 3, CPP_COLON))
	    {
	      if (cxx_dialect < cxx17)
		pedwarn (input_location, OPT_Wc__17_extensions,
			 "attribute using prefix only available "
			 "with %<-std=c++17%> or %<-std=gnu++17%>");

	      cp_lexer_consume_token (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	    }
	  else
	    attr_ns = NULL_TREE;
	}

      attributes = cp_parser_std_attribute_list (parser, attr_ns);

      finish_attrs:
      if (!cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE)
	  || !cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
	cp_parser_skip_to_end_of_statement (parser);
      else
	/* Warn about parsing c++11 attribute in non-c++11 mode, only
	   when we are sure that we have actually parsed them.  */
	maybe_warn_cpp0x (CPP0X_ATTRIBUTES);
    }
  else
    {
      tree alignas_expr;

      /* Look for an alignment-specifier.  */

      token = cp_lexer_peek_token (parser->lexer);

      if (token->type != CPP_KEYWORD
	  || token->keyword != RID_ALIGNAS)
	return NULL_TREE;

      cp_lexer_consume_token (parser->lexer);
      maybe_warn_cpp0x (CPP0X_ATTRIBUTES);

      matching_parens parens;
      if (!parens.require_open (parser))
	return error_mark_node;

      cp_parser_parse_tentatively (parser);
      alignas_expr = cp_parser_type_id (parser);

      if (!cp_parser_parse_definitely (parser))
	{
	  alignas_expr = cp_parser_assignment_expression (parser);
	  if (alignas_expr == error_mark_node)
	    cp_parser_skip_to_end_of_statement (parser);
	  if (alignas_expr == NULL_TREE
	      || alignas_expr == error_mark_node)
	    return alignas_expr;
	}

      alignas_expr = cxx_alignas_expr (alignas_expr);
      alignas_expr = build_tree_list (NULL_TREE, alignas_expr);

      /* Handle alignas (pack...).  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	{
	  cp_lexer_consume_token (parser->lexer);
	  alignas_expr = make_pack_expansion (alignas_expr);
	}

      /* Something went wrong, so don't build the attribute.  */
      if (alignas_expr == error_mark_node)
	return error_mark_node;

      /* Missing ')' means the code cannot possibly be valid; go ahead
	 and commit to make sure we issue a hard error.  */
      if (cp_parser_uncommitted_to_tentative_parse_p (parser)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
	cp_parser_commit_to_tentative_parse (parser);

      if (!parens.require_close (parser))
	return error_mark_node;

      /* Build the C++-11 representation of an 'aligned'
	 attribute.  */
      attributes
	= build_tree_list (build_tree_list (gnu_identifier,
					    aligned_identifier), alignas_expr);
    }

  return attributes;
}

/* Parse a standard C++-11 attribute-specifier-seq.

   attribute-specifier-seq:
     attribute-specifier-seq [opt] attribute-specifier  */

static tree
cp_parser_std_attribute_spec_seq (cp_parser *parser)
{
  tree attr_specs = NULL_TREE;
  tree attr_last = NULL_TREE;

  /* Don't create wrapper nodes within attributes: the
     handlers don't know how to handle them.  */
  auto_suppress_location_wrappers sentinel;

  while (true)
    {
      tree attr_spec = cp_parser_std_attribute_spec (parser);
      if (attr_spec == NULL_TREE)
	break;
      if (attr_spec == error_mark_node)
	return error_mark_node;

      if (attr_last)
	TREE_CHAIN (attr_last) = attr_spec;
      else
	attr_specs = attr_last = attr_spec;
      attr_last = tree_last (attr_last);
    }

  return attr_specs;
}

/* Skip a balanced-token starting at Nth token (with 1 as the next token),
   return index of the first token after balanced-token, or N on failure.  */

static size_t
cp_parser_skip_balanced_tokens (cp_parser *parser, size_t n)
{
  size_t orig_n = n;
  int nparens = 0, nbraces = 0, nsquares = 0;
  do
    switch (cp_lexer_peek_nth_token (parser->lexer, n++)->type)
      {
      case CPP_PRAGMA_EOL:
	if (!parser->lexer->in_pragma)
	  break;
	/* FALLTHRU */
      case CPP_EOF:
	/* Ran out of tokens.  */
	return orig_n;
      case CPP_OPEN_PAREN:
	++nparens;
	break;
      case CPP_OPEN_BRACE:
	++nbraces;
	break;
      case CPP_OPEN_SQUARE:
	++nsquares;
	break;
      case CPP_CLOSE_PAREN:
	--nparens;
	break;
      case CPP_CLOSE_BRACE:
	--nbraces;
	break;
      case CPP_CLOSE_SQUARE:
	--nsquares;
	break;
      default:
	break;
      }
  while (nparens || nbraces || nsquares);
  return n;
}

/* Skip GNU attribute tokens starting at Nth token (with 1 as the next token),
   return index of the first token after the GNU attribute tokens, or N on
   failure.  */

static size_t
cp_parser_skip_gnu_attributes_opt (cp_parser *parser, size_t n)
{
  while (true)
    {
      if (!cp_lexer_nth_token_is_keyword (parser->lexer, n, RID_ATTRIBUTE)
	  || !cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_PAREN)
	  || !cp_lexer_nth_token_is (parser->lexer, n + 2, CPP_OPEN_PAREN))
	break;

      size_t n2 = cp_parser_skip_balanced_tokens (parser, n + 2);
      if (n2 == n + 2)
	break;
      if (!cp_lexer_nth_token_is (parser->lexer, n2, CPP_CLOSE_PAREN))
	break;
      n = n2 + 1;
    }
  return n;
}

/* Skip standard C++11 attribute tokens starting at Nth token (with 1 as the
   next token), return index of the first token after the standard C++11
   attribute tokens, or N on failure.  */

static size_t
cp_parser_skip_std_attribute_spec_seq (cp_parser *parser, size_t n)
{
  while (true)
    {
      if (cp_lexer_nth_token_is (parser->lexer, n, CPP_OPEN_SQUARE)
	  && cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_SQUARE))
	{
	  size_t n2 = cp_parser_skip_balanced_tokens (parser, n + 1);
	  if (n2 == n + 1)
	    break;
	  if (!cp_lexer_nth_token_is (parser->lexer, n2, CPP_CLOSE_SQUARE))
	    break;
	  n = n2 + 1;
	}
      else if (cp_lexer_nth_token_is_keyword (parser->lexer, n, RID_ALIGNAS)
	       && cp_lexer_nth_token_is (parser->lexer, n + 1, CPP_OPEN_PAREN))
	{
	  size_t n2 = cp_parser_skip_balanced_tokens (parser, n + 1);
	  if (n2 == n + 1)
	    break;
	  n = n2;
	}
      else
	break;
    }
  return n;
}

/* Skip standard C++11 or GNU attribute tokens starting at Nth token (with 1
   as the next token), return index of the first token after the attribute
   tokens, or N on failure.  */

static size_t
cp_parser_skip_attributes_opt (cp_parser *parser, size_t n)
{
  if (cp_nth_tokens_can_be_gnu_attribute_p (parser, n))
    return cp_parser_skip_gnu_attributes_opt (parser, n);
  return cp_parser_skip_std_attribute_spec_seq (parser, n);
}

/* Parse an optional `__extension__' keyword.  Returns TRUE if it is
   present, and FALSE otherwise.  *SAVED_PEDANTIC is set to the
   current value of the PEDANTIC flag, regardless of whether or not
   the `__extension__' keyword is present.  The caller is responsible
   for restoring the value of the PEDANTIC flag.  */

static bool
cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic)
{
  /* Save the old value of the PEDANTIC flag.  */
  *saved_pedantic = pedantic;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXTENSION))
    {
      /* Consume the `__extension__' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* We're not being pedantic while the `__extension__' keyword is
	 in effect.  */
      pedantic = 0;

      return true;
    }

  return false;
}

/* Parse a label declaration.

   label-declaration:
     __label__ label-declarator-seq ;

   label-declarator-seq:
     identifier , label-declarator-seq
     identifier  */

static void
cp_parser_label_declaration (cp_parser* parser)
{
  /* Look for the `__label__' keyword.  */
  cp_parser_require_keyword (parser, RID_LABEL, RT_LABEL);

  while (true)
    {
      tree identifier;

      /* Look for an identifier.  */
      identifier = cp_parser_identifier (parser);
      /* If we failed, stop.  */
      if (identifier == error_mark_node)
	break;
      /* Declare it as a label.  */
      finish_label_decl (identifier);
      /* If the next token is a `;', stop.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	break;
      /* Look for the `,' separating the label declarations.  */
      cp_parser_require (parser, CPP_COMMA, RT_COMMA);
    }

  /* Look for the final `;'.  */
  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
}

// -------------------------------------------------------------------------- //
// Concept definitions

static tree
cp_parser_concept_definition (cp_parser *parser)
{
  /* A concept definition is an unevaluated context.  */
  cp_unevaluated u;

  gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT));
  cp_lexer_consume_token (parser->lexer);

  cp_expr id = cp_parser_identifier (parser);
  if (id == error_mark_node)
    {
      cp_parser_skip_to_end_of_statement (parser);
      cp_parser_consume_semicolon_at_end_of_statement (parser);
      return NULL_TREE;
    }

  tree attrs = cp_parser_attributes_opt (parser);

  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
    {
      cp_parser_skip_to_end_of_statement (parser);
      cp_parser_consume_semicolon_at_end_of_statement (parser);
      return error_mark_node;
    }

  processing_constraint_expression_sentinel parsing_constraint;
  tree init = cp_parser_constraint_expression (parser);
  if (init == error_mark_node)
    cp_parser_skip_to_end_of_statement (parser);

  /* Consume the trailing ';'. Diagnose the problem if it isn't there,
     but continue as if it were.  */
  cp_parser_consume_semicolon_at_end_of_statement (parser);

  return finish_concept_definition (id, init, attrs);
}

// -------------------------------------------------------------------------- //
// Requires Clause

/* Diagnose an expression that should appear in ()'s within a requires-clause
   and suggest where to place those parentheses.  */

static void
cp_parser_diagnose_ungrouped_constraint_plain (location_t loc)
{
  error_at (loc, "expression must be enclosed in parentheses");
}

static void
cp_parser_diagnose_ungrouped_constraint_rich (location_t loc)
{
  gcc_rich_location richloc (loc);
  richloc.add_fixit_insert_before ("(");
  richloc.add_fixit_insert_after (")");
  error_at (&richloc, "expression must be enclosed in parentheses");
}

/* Characterizes the likely kind of expression intended by a mis-written
   primary constraint.  */
enum primary_constraint_error
{
  pce_ok,
  pce_maybe_operator,
  pce_maybe_postfix
};

/* Returns true if the token(s) following a primary-expression in a
   constraint-logical-* expression would require parentheses.  */

static primary_constraint_error
cp_parser_constraint_requires_parens (cp_parser *parser, bool lambda_p)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  switch (token->type)
    {
      default:
	return pce_ok;

      case CPP_EQ:
	{
	  /* An equal sign may be part of the definition of a function,
	     and not an assignment operator, when parsing the expression
	     for a trailing requires-clause. For example:

		template<typename T>
		struct S {
		  S() requires C<T> = default;
		};

	     Don't try to reparse this a binary operator.  */
	  if (cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_DELETE)
	      || cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_DEFAULT))
	    return pce_ok;

	  gcc_fallthrough ();
	}

      /* Arithmetic operators.  */
      case CPP_PLUS:
      case CPP_MINUS:
      case CPP_MULT:
      case CPP_DIV:
      case CPP_MOD:
      /* Bitwise operators.  */
      case CPP_AND:
      case CPP_OR:
      case CPP_XOR:
      case CPP_RSHIFT:
      case CPP_LSHIFT:
      /* Relational operators.  */
      case CPP_EQ_EQ:
      case CPP_NOT_EQ:
      case CPP_LESS:
      case CPP_GREATER:
      case CPP_LESS_EQ:
      case CPP_GREATER_EQ:
      case CPP_SPACESHIP:
      /* Pointer-to-member.  */
      case CPP_DOT_STAR:
      case CPP_DEREF_STAR:
      /* Assignment operators.  */
      case CPP_PLUS_EQ:
      case CPP_MINUS_EQ:
      case CPP_MULT_EQ:
      case CPP_DIV_EQ:
      case CPP_MOD_EQ:
      case CPP_AND_EQ:
      case CPP_OR_EQ:
      case CPP_XOR_EQ:
      case CPP_RSHIFT_EQ:
      case CPP_LSHIFT_EQ:
      /* Conditional operator */
      case CPP_QUERY:
	/* Unenclosed binary or conditional operator.  */
	return pce_maybe_operator;

      case CPP_OPEN_PAREN:
	{
	  /* A primary constraint that precedes the parameter-list of a
	     lambda expression is followed by an open paren.

		[]<typename T> requires C (T a, T b) { ... }

	     Don't try to re-parse this as a postfix expression.  */
	  if (lambda_p)
	    return pce_ok;

	  gcc_fallthrough ();
	}
      case CPP_OPEN_SQUARE:
	{
	  /* A primary-constraint-expression followed by a '[[' is not a
	     postfix expression.  */
	  if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE))
	    return pce_ok;

	  gcc_fallthrough ();
	}
      case CPP_PLUS_PLUS:
      case CPP_MINUS_MINUS:
      case CPP_DOT:
	/* Unenclosed postfix operator.  */
	return pce_maybe_postfix;

      case CPP_DEREF:
	/* A primary constraint that precedes the lambda-declarator of a
	   lambda expression is followed by trailing return type.

	      []<typename T> requires C -> void {}

	   Don't try to re-parse this as a postfix expression in
	   C++23 and later.  In C++20 ( needs to come in between but we
	   allow it to be omitted with pedwarn.  */
	if (lambda_p)
	  return pce_ok;
	/* Unenclosed postfix operator.  */
	return pce_maybe_postfix;
   }
}

/* Returns true if the next token begins a unary expression, preceded by
   an operator or keyword.  */

static bool
cp_parser_unary_constraint_requires_parens (cp_parser *parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  switch (token->type)
    {
      case CPP_NOT:
      case CPP_PLUS:
      case CPP_MINUS:
      case CPP_MULT:
      case CPP_COMPL:
      case CPP_PLUS_PLUS:
      case CPP_MINUS_MINUS:
	return true;

      case CPP_KEYWORD:
	{
	  switch (token->keyword)
	    {
	      case RID_STATCAST:
	      case RID_DYNCAST:
	      case RID_REINTCAST:
	      case RID_CONSTCAST:
	      case RID_TYPEID:
	      case RID_SIZEOF:
	      case RID_ALIGNOF:
	      case RID_NOEXCEPT:
	      case RID_NEW:
	      case RID_DELETE:
	      case RID_THROW:
		return true;

	     default:
		break;
	  }
	}

      default:
	break;
    }

  return false;
}

/* Parse a primary expression within a constraint.  */

static cp_expr
cp_parser_constraint_primary_expression (cp_parser *parser, bool lambda_p)
{
  /* If this looks like a unary expression, parse it as such, but diagnose
     it as ill-formed; it requires parens.  */
  if (cp_parser_unary_constraint_requires_parens (parser))
    {
      cp_expr e = cp_parser_assignment_expression (parser, NULL, false, false);
      cp_parser_diagnose_ungrouped_constraint_rich (e.get_location());
      return e;
    }

  cp_lexer_save_tokens (parser->lexer);
  cp_id_kind idk;
  location_t loc = input_location;
  cp_expr expr = cp_parser_primary_expression (parser,
					       /*address_p=*/false,
					       /*cast_p=*/false,
					       /*template_arg_p=*/false,
					       &idk);
  expr.maybe_add_location_wrapper ();

  primary_constraint_error pce = pce_ok;
  if (expr != error_mark_node)
    {
      /* The primary-expression could be part of an unenclosed non-logical
	 compound expression.  */
      pce = cp_parser_constraint_requires_parens (parser, lambda_p);
    }
  if (pce == pce_ok)
    {
      cp_lexer_commit_tokens (parser->lexer);
      return finish_constraint_primary_expr (expr);
    }

  /* Retry the parse at a lower precedence. If that succeeds, diagnose the
     error, but return the expression as if it were valid.  */
  cp_lexer_rollback_tokens (parser->lexer);
  cp_parser_parse_tentatively (parser);
  if (pce == pce_maybe_operator)
    expr = cp_parser_assignment_expression (parser, NULL, false, false);
  else
    expr = cp_parser_simple_cast_expression (parser);
  if (cp_parser_parse_definitely (parser))
    {
      cp_parser_diagnose_ungrouped_constraint_rich (expr.get_location());
      return expr;
    }

  /* Otherwise, something has gone very wrong, and we can't generate a more
     meaningful diagnostic or recover.  */
  cp_parser_diagnose_ungrouped_constraint_plain (loc);
  return error_mark_node;
}

/* Parse a constraint-logical-and-expression.

     constraint-logical-and-expression:
       primary-expression
       constraint-logical-and-expression '&&' primary-expression  */

static cp_expr
cp_parser_constraint_logical_and_expression (cp_parser *parser, bool lambda_p)
{
  cp_expr lhs = cp_parser_constraint_primary_expression (parser, lambda_p);
  while (cp_lexer_next_token_is (parser->lexer, CPP_AND_AND))
    {
      cp_token *op = cp_lexer_consume_token (parser->lexer);
      tree rhs = cp_parser_constraint_primary_expression (parser, lambda_p);
      lhs = finish_constraint_and_expr (op->location, lhs, rhs);
    }
  return lhs;
}

/* Parse a constraint-logical-or-expression.

     constraint-logical-or-expression:
       constraint-logical-and-expression
       constraint-logical-or-expression '||' constraint-logical-and-expression  */

static cp_expr
cp_parser_constraint_logical_or_expression (cp_parser *parser, bool lambda_p)
{
  cp_expr lhs = cp_parser_constraint_logical_and_expression (parser, lambda_p);
  while (cp_lexer_next_token_is (parser->lexer, CPP_OR_OR))
    {
      cp_token *op = cp_lexer_consume_token (parser->lexer);
      cp_expr rhs = cp_parser_constraint_logical_and_expression (parser, lambda_p);
      lhs = finish_constraint_or_expr (op->location, lhs, rhs);
    }
  return lhs;
}

/* Parse the expression after a requires-clause. This has a different grammar
    than that in the concepts TS.  */

static tree
cp_parser_requires_clause_expression (cp_parser *parser, bool lambda_p)
{
  processing_constraint_expression_sentinel parsing_constraint;
  ++processing_template_decl;
  cp_expr expr = cp_parser_constraint_logical_or_expression (parser, lambda_p);
  --processing_template_decl;
  if (check_for_bare_parameter_packs (expr))
    expr = error_mark_node;
  return expr;
}

/* Parse a expression after a requires clause.

    constraint-expression:
      logical-or-expression

   The required logical-or-expression must be a constant expression. Note
   that we don't check that the expression is constepxr here. We defer until
   we analyze constraints and then, we only check atomic constraints.  */

static tree
cp_parser_constraint_expression (cp_parser *parser)
{
  processing_constraint_expression_sentinel parsing_constraint;
  ++processing_template_decl;
  cp_expr expr = cp_parser_binary_expression (parser, false, true,
					      PREC_NOT_OPERATOR, NULL);
  --processing_template_decl;
  if (check_for_bare_parameter_packs (expr))
    expr = error_mark_node;
  expr.maybe_add_location_wrapper ();
  return expr;
}

/* Optionally parse a requires clause:

      requires-clause:
	`requires` constraint-logical-or-expression.
   [ConceptsTS]
	`requires constraint-expression.

   LAMBDA_P is true when the requires-clause is parsed before the
   parameter-list of a lambda-declarator.  */

static tree
cp_parser_requires_clause_opt (cp_parser *parser, bool lambda_p)
{
  /* A requires clause is an unevaluated context.  */
  cp_unevaluated u;

  cp_token *tok = cp_lexer_peek_token (parser->lexer);
  if (tok->keyword != RID_REQUIRES)
    {
      if (!flag_concepts && tok->type == CPP_NAME
	  && tok->u.value == ridpointers[RID_REQUIRES])
	{
	  error_at (cp_lexer_peek_token (parser->lexer)->location,
		    "%<requires%> only available with "
		    "%<-std=c++20%> or %<-fconcepts%>");
	  /* Parse and discard the requires-clause.  */
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_constraint_expression (parser);
	}
      return NULL_TREE;
    }

  cp_token *tok2 = cp_lexer_peek_nth_token (parser->lexer, 2);
  if (tok2->type == CPP_OPEN_BRACE)
    {
      /* An opening brace following the start of a requires-clause is
	 ill-formed; the user likely forgot the second `requires' that
	 would start a requires-expression.  */
      gcc_rich_location richloc (tok2->location);
      richloc.add_fixit_insert_after (tok->location, " requires");
      error_at (&richloc, "missing additional %<requires%> to start "
		"a requires-expression");
      /* Don't consume the `requires', so that it's reused as the start of a
	 requires-expression.  */
    }
  else
    cp_lexer_consume_token (parser->lexer);

  if (!flag_concepts_ts)
    return cp_parser_requires_clause_expression (parser, lambda_p);
  else
    return cp_parser_constraint_expression (parser);
}

/*---------------------------------------------------------------------------
                           Requires expressions
---------------------------------------------------------------------------*/

/* Parse a requires expression

   requirement-expression:
       'requires' requirement-parameter-list [opt] requirement-body */

static tree
cp_parser_requires_expression (cp_parser *parser)
{
  gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES));
  location_t loc = cp_lexer_consume_token (parser->lexer)->location;

  /* Avoid committing to outer tentative parse.  */
  tentative_firewall firewall (parser);

  /* This is definitely a requires-expression.  */
  cp_parser_commit_to_tentative_parse (parser);

  tree parms, reqs;
  {
    /* Local parameters are delared as variables within the scope
       of the expression.  They are not visible past the end of
       the expression.  Expressions within the requires-expression
       are unevaluated.  */
    struct scope_sentinel
    {
      scope_sentinel ()
      {
	++cp_unevaluated_operand;
	begin_scope (sk_function_parms, NULL_TREE);
	current_binding_level->requires_expression = true;
      }

      ~scope_sentinel ()
      {
	pop_bindings_and_leave_scope ();
	--cp_unevaluated_operand;
      }
    } s;

    /* Parse the optional parameter list. */
    if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
      {
	parms = cp_parser_requirement_parameter_list (parser);
	if (parms == error_mark_node)
	  return error_mark_node;
      }
    else
      parms = NULL_TREE;

    /* Parse the requirement body. */
    ++processing_template_decl;
    reqs = cp_parser_requirement_body (parser);
    --processing_template_decl;
    if (reqs == error_mark_node)
      return error_mark_node;
  }

  /* This needs to happen after pop_bindings_and_leave_scope, as it reverses
     the parm chain.  */
  grokparms (parms, &parms);
  loc = make_location (loc, loc, parser->lexer);
  tree expr = finish_requires_expr (loc, parms, reqs);
  if (!processing_template_decl)
    {
      /* Perform semantic processing now to diagnose any invalid types and
	 expressions.  */
      int saved_errorcount = errorcount;
      tsubst_requires_expr (expr, NULL_TREE, tf_warning_or_error, NULL_TREE);
      if (errorcount > saved_errorcount)
	return error_mark_node;
    }
  return expr;
}

/* Parse a parameterized requirement.

   requirement-parameter-list:
       '(' parameter-declaration-clause ')' */

static tree
cp_parser_requirement_parameter_list (cp_parser *parser)
{
  matching_parens parens;
  if (!parens.require_open (parser))
    return error_mark_node;

  tree parms = (cp_parser_parameter_declaration_clause
		(parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL));

  if (!parens.require_close (parser))
    return error_mark_node;

  /* Modify the declared parameters by removing their context
     so they don't refer to the enclosing scope and explicitly
     indicating that they are constraint variables. */
  for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
    {
      if (parm == void_list_node || parm == explicit_void_list_node)
	break;
      tree decl = TREE_VALUE (parm);
      if (decl != error_mark_node)
	{
	  DECL_CONTEXT (decl) = NULL_TREE;
	  CONSTRAINT_VAR_P (decl) = true;
	}
    }

  return parms;
}

/* Parse the body of a requirement.

   requirement-body:
       '{' requirement-list '}' */
static tree
cp_parser_requirement_body (cp_parser *parser)
{
  matching_braces braces;
  if (!braces.require_open (parser))
    return error_mark_node;

  tree reqs = cp_parser_requirement_seq (parser);

  if (!braces.require_close (parser))
    return error_mark_node;

  return reqs;
}

/* Parse a sequence of requirements.

   requirement-seq:
       requirement
       requirement-seq requirement */

static tree
cp_parser_requirement_seq (cp_parser *parser)
{
  tree result = NULL_TREE;
  do
    {
      tree req = cp_parser_requirement (parser);
      if (req != error_mark_node)
	result = tree_cons (NULL_TREE, req, result);
    }
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE)
	 && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF));

  /* If there are no valid requirements, this is not a valid expression. */
  if (!result)
    return error_mark_node;

  /* Reverse the order of requirements so they are analyzed in order. */
  return nreverse (result);
}

/* Parse a syntactic requirement or type requirement.

     requirement:
       simple-requirement
       compound-requirement
       type-requirement
       nested-requirement */

static tree
cp_parser_requirement (cp_parser *parser)
{
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    return cp_parser_compound_requirement (parser);
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TYPENAME))
    {
      /* It's probably a type-requirement.  */
      cp_parser_parse_tentatively (parser);
      tree req = cp_parser_type_requirement (parser);
      if (cp_parser_parse_definitely (parser))
	return req;
      /* No, maybe it's something like typename T::type(); */
      cp_parser_parse_tentatively (parser);
      req = cp_parser_simple_requirement (parser);
      if (cp_parser_parse_definitely (parser))
	return req;
      /* Non-tentative for the error.  */
      return cp_parser_type_requirement (parser);
    }
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES))
    return cp_parser_nested_requirement (parser);
  else
    return cp_parser_simple_requirement (parser);
}

/* Parse a simple requirement.

     simple-requirement:
       expression ';' */

static tree
cp_parser_simple_requirement (cp_parser *parser)
{
  location_t start = cp_lexer_peek_token (parser->lexer)->location;
  cp_expr expr = cp_parser_expression (parser, NULL, false, false);
  if (expr == error_mark_node)
    cp_parser_skip_to_end_of_statement (parser);

  cp_parser_consume_semicolon_at_end_of_statement (parser);

  if (!expr || expr == error_mark_node)
    return error_mark_node;

  /* Sometimes we don't get locations, so use the cached token location
     as a reasonable approximation.  */
  if (expr.get_location() == UNKNOWN_LOCATION)
    expr.set_location (start);

  for (tree t = expr; ; )
    {
      if (TREE_CODE (t) == TRUTH_ANDIF_EXPR
	  || TREE_CODE (t) == TRUTH_ORIF_EXPR)
	{
	  t = TREE_OPERAND (t, 0);
	  continue;
	}
      if (concept_check_p (t))
	{
	  gcc_rich_location richloc (get_start (start));
	  richloc.add_fixit_insert_before (start, "requires ");
	  warning_at (&richloc, OPT_Wmissing_requires, "testing "
		      "if a concept-id is a valid expression; add "
		      "%<requires%> to check satisfaction");
	}
      break;
    }

  return finish_simple_requirement (expr.get_location (), expr);
}

/* Parse a type requirement

     type-requirement
         nested-name-specifier [opt] required-type-name ';'

     required-type-name:
         type-name
         'template' [opt] simple-template-id  */

static tree
cp_parser_type_requirement (cp_parser *parser)
{
  cp_token *start_tok = cp_lexer_consume_token (parser->lexer);
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  // Save the scope before parsing name specifiers.
  tree saved_scope = parser->scope;
  tree saved_object_scope = parser->object_scope;
  tree saved_qualifying_scope = parser->qualifying_scope;
  cp_parser_global_scope_opt (parser, /*current_scope_valid_p=*/false);
  cp_parser_nested_name_specifier_opt (parser,
                                       /*typename_keyword_p=*/true,
                                       /*check_dependency_p=*/false,
                                       /*type_p=*/true,
                                       /*is_declaration=*/false);

  tree type;
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
    {
      cp_lexer_consume_token (parser->lexer);
      type = cp_parser_template_id (parser,
                                    /*template_keyword_p=*/true,
                                    /*check_dependency=*/false,
                                    /*tag_type=*/none_type,
                                    /*is_declaration=*/false);
      type = make_typename_type (parser->scope, type, typename_type,
                                 /*complain=*/tf_error);
    }
  else
   type = cp_parser_type_name (parser, /*typename_keyword_p=*/true);

  if (TREE_CODE (type) == TYPE_DECL)
    type = TREE_TYPE (type);

  parser->scope = saved_scope;
  parser->object_scope = saved_object_scope;
  parser->qualifying_scope = saved_qualifying_scope;

  if (type == error_mark_node)
    cp_parser_skip_to_end_of_statement (parser);

  cp_parser_consume_semicolon_at_end_of_statement (parser);

  if (type == error_mark_node)
    return error_mark_node;

  loc = make_location (loc, start_tok->location, parser->lexer);
  return finish_type_requirement (loc, type);
}

/* Parse a compound requirement

     compound-requirement:
         '{' expression '}' 'noexcept' [opt] trailing-return-type [opt] ';' */

static tree
cp_parser_compound_requirement (cp_parser *parser)
{
  /* Parse an expression enclosed in '{ }'s. */
  matching_braces braces;
  if (!braces.require_open (parser))
    return error_mark_node;

  cp_token *expr_token = cp_lexer_peek_token (parser->lexer);

  tree expr = cp_parser_expression (parser, NULL, false, false);
  if (expr == error_mark_node)
    cp_parser_skip_to_closing_brace (parser);

  if (!braces.require_close (parser))
    {
      cp_parser_skip_to_end_of_statement (parser);
      cp_parser_consume_semicolon_at_end_of_statement (parser);
      return error_mark_node;
    }

  /* If the expression was invalid, skip the remainder of the requirement.  */
  if (!expr || expr == error_mark_node)
    {
      cp_parser_skip_to_end_of_statement (parser);
      cp_parser_consume_semicolon_at_end_of_statement (parser);
      return error_mark_node;
    }

  /* Parse the optional noexcept. */
  bool noexcept_p = false;
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_NOEXCEPT))
    {
      cp_lexer_consume_token (parser->lexer);
      noexcept_p = true;
    }

  /* Parse the optional trailing return type. */
  tree type = NULL_TREE;
  if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
    {
      cp_lexer_consume_token (parser->lexer);
      cp_token *tok = cp_lexer_peek_token (parser->lexer);

      bool saved_result_type_constraint_p = parser->in_result_type_constraint_p;
      parser->in_result_type_constraint_p = true;
      /* C++20 allows either a type-id or a type-constraint. Parsing
         a type-id will subsume the parsing for a type-constraint but
         allow for more syntactic forms (e.g., const C<T>*).  */
      type = cp_parser_trailing_type_id (parser);
      parser->in_result_type_constraint_p = saved_result_type_constraint_p;
      if (type == error_mark_node)
        return error_mark_node;

      location_t type_loc = make_location (tok->location, tok->location,
					   parser->lexer);

      /* Check that we haven't written something like 'const C<T>*'.  */
      if (type_uses_auto (type))
	{
	  if (!is_auto (type))
	    {
	      error_at (type_loc,
			"result type is not a plain type-constraint");
	      cp_parser_consume_semicolon_at_end_of_statement (parser);
	      return error_mark_node;
	    }
	}
      else if (!flag_concepts_ts)
	/* P1452R2 removed the trailing-return-type option.  */
	error_at (type_loc,
		  "return-type-requirement is not a type-constraint");
    }

  location_t loc = make_location (expr_token->location,
				  braces.open_location (),
				  parser->lexer);

  cp_parser_consume_semicolon_at_end_of_statement (parser);

  if (expr == error_mark_node || type == error_mark_node)
    return error_mark_node;

  return finish_compound_requirement (loc, expr, type, noexcept_p);
}

/* Parse a nested requirement. This is the same as a requires clause.

   nested-requirement:
     requires-clause */

static tree
cp_parser_nested_requirement (cp_parser *parser)
{
  gcc_assert (cp_lexer_next_token_is_keyword (parser->lexer, RID_REQUIRES));
  cp_token *tok = cp_lexer_consume_token (parser->lexer);
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
  tree req = cp_parser_constraint_expression (parser);
  if (req == error_mark_node)
    cp_parser_skip_to_end_of_statement (parser);
  loc = make_location (loc, tok->location, parser->lexer);
  cp_parser_consume_semicolon_at_end_of_statement (parser);
  if (req == error_mark_node)
    return error_mark_node;
  return finish_nested_requirement (loc, req);
}

/* Support Functions */

/* Return the appropriate prefer_type argument for lookup_name based on
   tag_type.  */

static inline LOOK_want
prefer_type_arg (tag_types tag_type)
{
  switch (tag_type)
    {
    case none_type:  return LOOK_want::NORMAL;	// No preference.
    case scope_type: return LOOK_want::TYPE_NAMESPACE;	// Type or namespace.
    default:         return LOOK_want::TYPE;	// Type only.
    }
}

/* Looks up NAME in the current scope, as given by PARSER->SCOPE.
   NAME should have one of the representations used for an
   id-expression.  If NAME is the ERROR_MARK_NODE, the ERROR_MARK_NODE
   is returned.  If PARSER->SCOPE is a dependent type, then a
   SCOPE_REF is returned.

   If NAME is a TEMPLATE_ID_EXPR, then it will be immediately
   returned; the name was already resolved when the TEMPLATE_ID_EXPR
   was formed.  Abstractly, such entities should not be passed to this
   function, because they do not need to be looked up, but it is
   simpler to check for this special case here, rather than at the
   call-sites.

   In cases not explicitly covered above, this function returns a
   DECL, OVERLOAD, or baselink representing the result of the lookup.
   If there was no entity with the indicated NAME, the ERROR_MARK_NODE
   is returned.

   If TAG_TYPE is not NONE_TYPE, it indicates an explicit type keyword
   (e.g., "struct") that was used.  In that case bindings that do not
   refer to types are ignored.

   If IS_TEMPLATE is TRUE, bindings that do not refer to templates are
   ignored.

   If IS_NAMESPACE is TRUE, bindings that do not refer to namespaces
   are ignored.

   If CHECK_DEPENDENCY is TRUE, names are not looked up in dependent
   types.

   If AMBIGUOUS_DECLS is non-NULL, *AMBIGUOUS_DECLS is set to a
   TREE_LIST of candidates if name-lookup results in an ambiguity, and
   NULL_TREE otherwise.  */

static cp_expr
cp_parser_lookup_name (cp_parser *parser, tree name,
		       enum tag_types tag_type,
		       bool is_template,
		       bool is_namespace,
		       bool check_dependency,
		       tree *ambiguous_decls,
		       location_t name_location)
{
  tree decl;
  tree object_type = parser->context->object_type;

  /* Assume that the lookup will be unambiguous.  */
  if (ambiguous_decls)
    *ambiguous_decls = NULL_TREE;

  /* Now that we have looked up the name, the OBJECT_TYPE (if any) is
     no longer valid.  Note that if we are parsing tentatively, and
     the parse fails, OBJECT_TYPE will be automatically restored.  */
  parser->context->object_type = NULL_TREE;

  if (name == error_mark_node)
    return error_mark_node;

  /* A template-id has already been resolved; there is no lookup to
     do.  */
  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    return name;
  if (BASELINK_P (name))
    {
      gcc_assert (TREE_CODE (BASELINK_FUNCTIONS (name))
		  == TEMPLATE_ID_EXPR);
      return name;
    }

  /* A BIT_NOT_EXPR is used to represent a destructor.  By this point,
     it should already have been checked to make sure that the name
     used matches the type being destroyed.  */
  if (TREE_CODE (name) == BIT_NOT_EXPR)
    {
      tree type;

      /* Figure out to which type this destructor applies.  */
      if (parser->scope)
	type = parser->scope;
      else if (object_type)
	type = object_type;
      else
	type = current_class_type;
      /* If that's not a class type, there is no destructor.  */
      if (!type || !CLASS_TYPE_P (type))
	return error_mark_node;

      /* In a non-static member function, check implicit this->.  */
      if (current_class_ref)
	return lookup_destructor (current_class_ref, parser->scope, name,
				  tf_warning_or_error);

      if (CLASSTYPE_LAZY_DESTRUCTOR (type))
	lazily_declare_fn (sfk_destructor, type);

      if (tree dtor = CLASSTYPE_DESTRUCTOR (type))
	return dtor;

      return error_mark_node;
    }

  /* By this point, the NAME should be an ordinary identifier.  If
     the id-expression was a qualified name, the qualifying scope is
     stored in PARSER->SCOPE at this point.  */
  gcc_assert (identifier_p (name));

  /* Perform the lookup.  */
  if (parser->scope)
    {
      bool dependent_p;

      if (parser->scope == error_mark_node)
	return error_mark_node;

      /* If the SCOPE is dependent, the lookup must be deferred until
	 the template is instantiated -- unless we are explicitly
	 looking up names in uninstantiated templates.  Even then, we
	 cannot look up the name if the scope is not a class type; it
	 might, for example, be a template type parameter.  */
      dependent_p = (TYPE_P (parser->scope)
		     && dependent_scope_p (parser->scope));
      if ((check_dependency || !CLASS_TYPE_P (parser->scope))
	  && dependent_p)
	/* Defer lookup.  */
	decl = error_mark_node;
      else
	{
	  tree pushed_scope = NULL_TREE;

	  /* If PARSER->SCOPE is a dependent type, then it must be a
	     class type, and we must not be checking dependencies;
	     otherwise, we would have processed this lookup above.  So
	     that PARSER->SCOPE is not considered a dependent base by
	     lookup_member, we must enter the scope here.  */
	  if (dependent_p)
	    pushed_scope = push_scope (parser->scope);

	  /* If the PARSER->SCOPE is a template specialization, it
	     may be instantiated during name lookup.  In that case,
	     errors may be issued.  Even if we rollback the current
	     tentative parse, those errors are valid.  */
	  decl = lookup_qualified_name (parser->scope, name,
					prefer_type_arg (tag_type),
					/*complain=*/true);

	  /* 3.4.3.1: In a lookup in which the constructor is an acceptable
	     lookup result and the nested-name-specifier nominates a class C:
	       * if the name specified after the nested-name-specifier, when
	       looked up in C, is the injected-class-name of C (Clause 9), or
	       * if the name specified after the nested-name-specifier is the
	       same as the identifier or the simple-template-id's template-
	       name in the last component of the nested-name-specifier,
	     the name is instead considered to name the constructor of
	     class C. [ Note: for example, the constructor is not an
	     acceptable lookup result in an elaborated-type-specifier so
	     the constructor would not be used in place of the
	     injected-class-name. --end note ] Such a constructor name
	     shall be used only in the declarator-id of a declaration that
	     names a constructor or in a using-declaration.  */
	  if (tag_type == none_type
	      && DECL_SELF_REFERENCE_P (decl)
	      && same_type_p (DECL_CONTEXT (decl), parser->scope))
	    decl = lookup_qualified_name (parser->scope, ctor_identifier,
					  prefer_type_arg (tag_type),
					  /*complain=*/true);

	  if (pushed_scope)
	    pop_scope (pushed_scope);
	}

      /* If the scope is a dependent type and either we deferred lookup or
	 we did lookup but didn't find the name, rememeber the name.  */
      if (decl == error_mark_node && TYPE_P (parser->scope)
	  && dependent_type_p (parser->scope))
	{
	  if (tag_type)
	    {
	      tree type;

	      /* The resolution to Core Issue 180 says that `struct
		 A::B' should be considered a type-name, even if `A'
		 is dependent.  */
	      type = make_typename_type (parser->scope, name, tag_type,
					 /*complain=*/tf_error);
	      if (type != error_mark_node)
		decl = TYPE_NAME (type);
	    }
	  else if (is_template
		   && (cp_parser_next_token_ends_template_argument_p (parser)
		       || cp_lexer_next_token_is (parser->lexer,
						  CPP_CLOSE_PAREN)))
	    decl = make_unbound_class_template (parser->scope,
						name, NULL_TREE,
						/*complain=*/tf_error);
	  else
	    decl = build_qualified_name (/*type=*/NULL_TREE,
					 parser->scope, name,
					 is_template);
	}
      parser->qualifying_scope = parser->scope;
      parser->object_scope = NULL_TREE;
    }
  else if (object_type)
    {
      bool dep = dependent_scope_p (object_type);

      /* Look up the name in the scope of the OBJECT_TYPE, unless the
	 OBJECT_TYPE is not a class.  */
      if (!dep && CLASS_TYPE_P (object_type))
	/* If the OBJECT_TYPE is a template specialization, it may
	   be instantiated during name lookup.  In that case, errors
	   may be issued.  Even if we rollback the current tentative
	   parse, those errors are valid.  */
	decl = lookup_member (object_type,
			      name,
			      /*protect=*/0,
			      /*prefer_type=*/tag_type != none_type,
			      tf_warning_or_error);
      else
	decl = NULL_TREE;

      if (!decl)
	/* Look it up in the enclosing context.  DR 141: When looking for a
	   template-name after -> or ., only consider class templates.  */
	decl = lookup_name (name, is_namespace ? LOOK_want::NAMESPACE
			    /* DR 141: When looking in the
			       current enclosing context for a
			       template-name after -> or ., only
			       consider class templates.  */
			    : is_template ? LOOK_want::TYPE
			    : prefer_type_arg (tag_type));

      /* If we did unqualified lookup of a dependent member-qualified name and
	 found something, do we want to use it?  P1787 clarified that we need
	 to look in the object scope first even if it's dependent, but for now
	 let's still use it in some cases.
	 FIXME remember unqualified lookup result to use if member lookup fails
	 at instantiation time.	 */
      if (decl && dep && is_template)
	{
	  saved_token_sentinel toks (parser->lexer, STS_ROLLBACK);
	  /* Only use the unqualified class template lookup if we're actually
	     looking at a template arg list.  */
	  if (!cp_parser_skip_entire_template_parameter_list (parser))
	    decl = NULL_TREE;
	}

      /* If we know we're looking for a type (e.g. A in p->A::x),
	 mock up a typename.  */
      if (!decl && object_type && tag_type != none_type
	  && dependentish_scope_p (object_type))
	{
	  tree type = build_typename_type (object_type, name, name,
					   typename_type);
	  decl = TYPE_NAME (type);
	}

      parser->object_scope = object_type;
      parser->qualifying_scope = NULL_TREE;
    }
  else
    {
      decl = lookup_name (name, is_namespace ? LOOK_want::NAMESPACE
			  : prefer_type_arg (tag_type));
      parser->qualifying_scope = NULL_TREE;
      parser->object_scope = NULL_TREE;
    }

  /* If the lookup failed, let our caller know.  */
  if (!decl || decl == error_mark_node)
    return error_mark_node;

  /* If we have resolved the name of a member declaration, check to
     see if the declaration is accessible.  When the name resolves to
     set of overloaded functions, accessibility is checked when
     overload resolution is done.  If we have a TREE_LIST, then the lookup
     is either ambiguous or it found multiple injected-class-names, the
     accessibility of which is trivially satisfied.

     During an explicit instantiation, access is not checked at all,
     as per [temp.explicit].  */
  if (DECL_P (decl))
    check_accessibility_of_qualified_id (decl, object_type, parser->scope,
					 tf_warning_or_error);

  /* Pull out the template from an injected-class-name (or multiple).  */
  if (is_template)
    decl = maybe_get_template_decl_from_type_decl (decl);

  /* If it's a TREE_LIST, the result of the lookup was ambiguous.  */
  if (TREE_CODE (decl) == TREE_LIST)
    {
      if (ambiguous_decls)
	*ambiguous_decls = decl;
      /* The error message we have to print is too complicated for
	 cp_parser_error, so we incorporate its actions directly.  */
      if (!cp_parser_simulate_error (parser))
	{
	  error_at (name_location, "reference to %qD is ambiguous",
		    name);
	  print_candidates (decl);
	}
      return error_mark_node;
    }

  gcc_assert (DECL_P (decl)
	      || TREE_CODE (decl) == OVERLOAD
	      || TREE_CODE (decl) == SCOPE_REF
	      || TREE_CODE (decl) == UNBOUND_CLASS_TEMPLATE
	      || BASELINK_P (decl));

  maybe_record_typedef_use (decl);

  return cp_expr (decl, name_location);
}

/* Like cp_parser_lookup_name, but for use in the typical case where
   CHECK_ACCESS is TRUE, IS_TYPE is FALSE, IS_TEMPLATE is FALSE,
   IS_NAMESPACE is FALSE, and CHECK_DEPENDENCY is TRUE.  */

static tree
cp_parser_lookup_name_simple (cp_parser* parser, tree name, location_t location)
{
  return cp_parser_lookup_name (parser, name,
				none_type,
				/*is_template=*/false,
				/*is_namespace=*/false,
				/*check_dependency=*/true,
				/*ambiguous_decls=*/NULL,
				location);
}

/* If DECL is a TEMPLATE_DECL that can be treated like a TYPE_DECL in
   the current context, return the TYPE_DECL.  If TAG_NAME_P is
   true, the DECL indicates the class being defined in a class-head,
   or declared in an elaborated-type-specifier.

   Otherwise, return DECL.  */

static tree
cp_parser_maybe_treat_template_as_class (tree decl, bool tag_name_p)
{
  /* If the TEMPLATE_DECL is being declared as part of a class-head,
     the translation from TEMPLATE_DECL to TYPE_DECL occurs:

       struct A {
	 template <typename T> struct B;
       };

       template <typename T> struct A::B {};

     Similarly, in an elaborated-type-specifier:

       namespace N { struct X{}; }

       struct A {
	 template <typename T> friend struct N::X;
       };

     However, if the DECL refers to a class type, and we are in
     the scope of the class, then the name lookup automatically
     finds the TYPE_DECL created by build_self_reference rather
     than a TEMPLATE_DECL.  For example, in:

       template <class T> struct S {
	 S s;
       };

     there is no need to handle such case.  */

  if (DECL_CLASS_TEMPLATE_P (decl) && tag_name_p)
    return DECL_TEMPLATE_RESULT (decl);

  return decl;
}

/* If too many, or too few, template-parameter lists apply to the
   declarator, issue an error message.  Returns TRUE if all went well,
   and FALSE otherwise.  */

static bool
cp_parser_check_declarator_template_parameters (cp_parser* parser,
						cp_declarator *declarator,
						location_t declarator_location)
{
  switch (declarator->kind)
    {
    case cdk_id:
      {
	unsigned num_templates = 0;
	tree scope = declarator->u.id.qualifying_scope;
	bool template_id_p = false;

	if (scope)
	  num_templates = num_template_headers_for_class (scope);
	else if (TREE_CODE (declarator->u.id.unqualified_name)
		 == TEMPLATE_ID_EXPR)
	  {
	    /* If the DECLARATOR has the form `X<y>' then it uses one
	       additional level of template parameters.  */
	    ++num_templates;
	    template_id_p = true;
	  }

	return cp_parser_check_template_parameters
	  (parser, num_templates, template_id_p, declarator_location,
	   declarator);
      }

    case cdk_function:
    case cdk_array:
    case cdk_pointer:
    case cdk_reference:
    case cdk_ptrmem:
      return (cp_parser_check_declarator_template_parameters
	      (parser, declarator->declarator, declarator_location));

    case cdk_decomp:
    case cdk_error:
      return true;

    default:
      gcc_unreachable ();
    }
  return false;
}

/* NUM_TEMPLATES were used in the current declaration.  If that is
   invalid, return FALSE and issue an error messages.  Otherwise,
   return TRUE.  If DECLARATOR is non-NULL, then we are checking a
   declarator and we can print more accurate diagnostics.  */

static bool
cp_parser_check_template_parameters (cp_parser* parser,
				     unsigned num_templates,
				     bool template_id_p,
				     location_t location,
				     cp_declarator *declarator)
{
  /* If there are the same number of template classes and parameter
     lists, that's OK.  */
  if (parser->num_template_parameter_lists == num_templates)
    return true;
  /* If there are more, but only one more, and the name ends in an identifier,
     then we are declaring a primary template.  That's OK too.  */
  if (!template_id_p
      && parser->num_template_parameter_lists == num_templates + 1)
    return true;

  if (cp_parser_simulate_error (parser))
    return false;

  /* If there are more template classes than parameter lists, we have
     something like:

       template <class T> void S<T>::R<T>::f ();  */
  if (parser->num_template_parameter_lists < num_templates)
    {
      if (declarator && !current_function_decl)
	error_at (location, "specializing member %<%T::%E%> "
		  "requires %<template<>%> syntax",
		  declarator->u.id.qualifying_scope,
		  declarator->u.id.unqualified_name);
      else if (declarator)
	error_at (location, "invalid declaration of %<%T::%E%>",
		  declarator->u.id.qualifying_scope,
		  declarator->u.id.unqualified_name);
      else
	error_at (location, "too few template-parameter-lists");
      return false;
    }
  /* Otherwise, there are too many template parameter lists.  We have
     something like:

     template <class T> template <class U> void S::f();  */
  error_at (location, "too many template-parameter-lists");
  return false;
}

/* Parse an optional `::' token indicating that the following name is
   from the global namespace.  If so, PARSER->SCOPE is set to the
   GLOBAL_NAMESPACE. Otherwise, PARSER->SCOPE is set to NULL_TREE,
   unless CURRENT_SCOPE_VALID_P is TRUE, in which case it is left alone.
   Returns the new value of PARSER->SCOPE, if the `::' token is
   present, and NULL_TREE otherwise.  */

static tree
cp_parser_global_scope_opt (cp_parser* parser, bool current_scope_valid_p)
{
  cp_token *token;

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* If we're looking at a `::' token then we're starting from the
     global namespace, not our current location.  */
  if (token->type == CPP_SCOPE)
    {
      /* Consume the `::' token.  */
      cp_lexer_consume_token (parser->lexer);
      /* Set the SCOPE so that we know where to start the lookup.  */
      parser->scope = global_namespace;
      parser->qualifying_scope = global_namespace;
      parser->object_scope = NULL_TREE;

      return parser->scope;
    }
  else if (!current_scope_valid_p)
    {
      parser->scope = NULL_TREE;
      parser->qualifying_scope = NULL_TREE;
      parser->object_scope = NULL_TREE;
    }

  return NULL_TREE;
}

/* Returns TRUE if the upcoming token sequence is the start of a
   constructor declarator or C++17 deduction guide.  If FRIEND_P is true, the
   declarator is preceded by the `friend' specifier.  The parser flags FLAGS
   is used to control type-specifier parsing.  */

static bool
cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
				    bool friend_p)
{
  bool constructor_p;
  bool outside_class_specifier_p;
  tree nested_name_specifier;
  cp_token *next_token;

  /* The common case is that this is not a constructor declarator, so
     try to avoid doing lots of work if at all possible.  It's not
     valid declare a constructor at function scope.  */
  if (parser->in_function_body)
    return false;
  /* And only certain tokens can begin a constructor declarator.  */
  next_token = cp_lexer_peek_token (parser->lexer);
  if (next_token->type != CPP_NAME
      && next_token->type != CPP_SCOPE
      && next_token->type != CPP_NESTED_NAME_SPECIFIER
      /* DR 2237 (C++20 only): A simple-template-id is no longer valid as the
	 declarator-id of a constructor or destructor.  */
      && (next_token->type != CPP_TEMPLATE_ID || cxx_dialect >= cxx20))
    return false;

  /* Parse tentatively; we are going to roll back all of the tokens
     consumed here.  */
  cp_parser_parse_tentatively (parser);
  /* Assume that we are looking at a constructor declarator.  */
  constructor_p = true;

  /* Look for the optional `::' operator.  */
  cp_parser_global_scope_opt (parser,
			      /*current_scope_valid_p=*/false);
  /* Look for the nested-name-specifier.  */
  nested_name_specifier
    = (cp_parser_nested_name_specifier_opt (parser,
					    /*typename_keyword_p=*/false,
					    /*check_dependency_p=*/false,
					    /*type_p=*/false,
					    /*is_declaration=*/false));

  /* Resolve the TYPENAME_TYPE, because the call above didn't do it.  */
  if (nested_name_specifier
      && TREE_CODE (nested_name_specifier) == TYPENAME_TYPE)
    {
      tree s = resolve_typename_type (nested_name_specifier,
				      /*only_current_p=*/false);
      if (TREE_CODE (s) != TYPENAME_TYPE)
	nested_name_specifier = s;
    }

  outside_class_specifier_p = (!at_class_scope_p ()
			       || !TYPE_BEING_DEFINED (current_class_type)
			       || friend_p);

  /* Outside of a class-specifier, there must be a
     nested-name-specifier.  Except in C++17 mode, where we
     might be declaring a guiding declaration.  */
  if (!nested_name_specifier && outside_class_specifier_p
      && cxx_dialect < cxx17)
    constructor_p = false;
  else if (nested_name_specifier == error_mark_node)
    constructor_p = false;

  /* If we have a class scope, this is easy; DR 147 says that S::S always
     names the constructor, and no other qualified name could.  */
  if (constructor_p && nested_name_specifier
      && CLASS_TYPE_P (nested_name_specifier))
    {
      tree id = cp_parser_unqualified_id (parser,
					  /*template_keyword_p=*/false,
					  /*check_dependency_p=*/false,
					  /*declarator_p=*/true,
					  /*optional_p=*/false);
      if (is_overloaded_fn (id))
	id = DECL_NAME (get_first_fn (id));
      if (!constructor_name_p (id, nested_name_specifier))
	constructor_p = false;
    }
  /* If we still think that this might be a constructor-declarator,
     look for a class-name.  */
  else if (constructor_p)
    {
      /* If we have:

	   template <typename T> struct S {
	     S();
	   };

	 we must recognize that the nested `S' names a class.  */
      if (cxx_dialect >= cxx17)
	cp_parser_parse_tentatively (parser);

      tree type_decl;
      type_decl = cp_parser_class_name (parser,
					/*typename_keyword_p=*/false,
					/*template_keyword_p=*/false,
					none_type,
					/*check_dependency_p=*/false,
					/*class_head_p=*/false,
					/*is_declaration=*/false);

      if (cxx_dialect >= cxx17
	  && !cp_parser_parse_definitely (parser))
	{
	  type_decl = NULL_TREE;
	  tree tmpl = cp_parser_template_name (parser,
					       /*template_keyword*/false,
					       /*check_dependency_p*/false,
					       /*is_declaration*/false,
					       none_type,
					       /*is_identifier*/NULL);
	  if (DECL_CLASS_TEMPLATE_P (tmpl)
	      || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))
	    /* It's a deduction guide, return true.  */;
	  else
	    cp_parser_simulate_error (parser);
	}

      /* If there was no class-name, then this is not a constructor.
	 Otherwise, if we are in a class-specifier and we aren't
	 handling a friend declaration, check that its type matches
	 current_class_type (c++/38313).  Note: error_mark_node
	 is left alone for error recovery purposes.  */
      constructor_p = (!cp_parser_error_occurred (parser)
		       && (outside_class_specifier_p
			   || type_decl == NULL_TREE
			   || type_decl == error_mark_node
			   || same_type_p (current_class_type,
					   TREE_TYPE (type_decl))));

      /* If we're still considering a constructor, we have to see a `(',
	 to begin the parameter-declaration-clause, followed by either a
	 `)', an `...', or a decl-specifier.  We need to check for a
	 type-specifier to avoid being fooled into thinking that:

	   S (f) (int);

	 is a constructor.  (It is actually a function named `f' that
	 takes one parameter (of type `int') and returns a value of type
	 `S'.  */
      if (constructor_p
	  && !cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
	constructor_p = false;

      if (constructor_p
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_ELLIPSIS)
	  /* A parameter declaration begins with a decl-specifier,
	     which is either the "attribute" keyword, a storage class
	     specifier, or (usually) a type-specifier.  */
	  && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
	  /* GNU attributes can actually appear both at the start of
	     a parameter and parenthesized declarator.
	     S (__attribute__((unused)) int);
	     is a constructor, but
	     S (__attribute__((unused)) foo) (int);
	     is a function declaration. [[attribute]] can appear in the
	     first form too, but not in the second form.  */
	  && !cp_next_tokens_can_be_std_attribute_p (parser))
	{
	  tree type;
	  tree pushed_scope = NULL_TREE;
	  unsigned saved_num_template_parameter_lists;

	  if (cp_parser_allow_gnu_extensions_p (parser)
	      && cp_next_tokens_can_be_gnu_attribute_p (parser))
	    {
	      unsigned int n = cp_parser_skip_gnu_attributes_opt (parser, 1);
	      while (--n)
		cp_lexer_consume_token (parser->lexer);
	    }

	  /* Names appearing in the type-specifier should be looked up
	     in the scope of the class.  */
	  if (current_class_type)
	    type = NULL_TREE;
	  else if (type_decl)
	    {
	      type = TREE_TYPE (type_decl);
	      if (TREE_CODE (type) == TYPENAME_TYPE)
		{
		  type = resolve_typename_type (type,
						/*only_current_p=*/false);
		  if (TREE_CODE (type) == TYPENAME_TYPE)
		    {
		      cp_parser_abort_tentative_parse (parser);
		      return false;
		    }
		}
	      pushed_scope = push_scope (type);
	    }

	  /* Inside the constructor parameter list, surrounding
	     template-parameter-lists do not apply.  */
	  saved_num_template_parameter_lists
	    = parser->num_template_parameter_lists;
	  parser->num_template_parameter_lists = 0;

	  /* Look for the type-specifier.  It's not optional, but its typename
	     might be.  Unless this is a friend declaration; we don't want to
	     treat

	       friend S (T::fn)(int);

	     as a constructor, but with P0634, we might assume a type when
	     looking for the type-specifier.  It is actually a function named
	     `T::fn' that takes one parameter (of type `int') and returns a
	     value of type `S'.  Constructors can be friends, but they must
	     use a qualified name.

	     Parse with an empty set of declaration specifiers since we're
	     trying to match a decl-specifier-seq of the first parameter.  
	     This must be non-null so that cp_parser_simple_type_specifier
	     will recognize a constrained placeholder type such as:
	     'C<int> auto' where C is a type concept.  */
	  cp_decl_specifier_seq ctor_specs;
	  clear_decl_specs (&ctor_specs);
	  cp_parser_type_specifier (parser,
				    (friend_p ? CP_PARSER_FLAGS_NONE
				     : (flags & ~CP_PARSER_FLAGS_OPTIONAL)),
				    /*decl_specs=*/&ctor_specs,
				    /*is_declarator=*/true,
				    /*declares_class_or_enum=*/NULL,
				    /*is_cv_qualifier=*/NULL);

	  parser->num_template_parameter_lists
	    = saved_num_template_parameter_lists;

	  /* Leave the scope of the class.  */
	  if (pushed_scope)
	    pop_scope (pushed_scope);

	  constructor_p = !cp_parser_error_occurred (parser);
	}
    }

  /* We did not really want to consume any tokens.  */
  cp_parser_abort_tentative_parse (parser);

  return constructor_p;
}

/* Parse the definition of the function given by the DECL_SPECIFIERS,
   ATTRIBUTES, and DECLARATOR.  The access checks have been deferred;
   they must be performed once we are in the scope of the function.

   Returns the function defined.  */

static tree
cp_parser_function_definition_from_specifiers_and_declarator
  (cp_parser* parser,
   cp_decl_specifier_seq *decl_specifiers,
   tree attributes,
   const cp_declarator *declarator)
{
  tree fn;
  bool success_p;

  /* Begin the function-definition.  */
  success_p = start_function (decl_specifiers, declarator, attributes);

  /* The things we're about to see are not directly qualified by any
     template headers we've seen thus far.  */
  reset_specialization ();

  /* If there were names looked up in the decl-specifier-seq that we
     did not check, check them now.  We must wait until we are in the
     scope of the function to perform the checks, since the function
     might be a friend.  */
  perform_deferred_access_checks (tf_warning_or_error);

  if (success_p)
    {
      cp_finalize_omp_declare_simd (parser, current_function_decl);
      parser->omp_declare_simd = NULL;
      cp_finalize_oacc_routine (parser, current_function_decl, true);
      parser->oacc_routine = NULL;
    }

  if (!success_p)
    {
      /* Skip the entire function.  */
      cp_parser_skip_to_end_of_block_or_statement (parser);
      fn = error_mark_node;
    }
  else if (DECL_INITIAL (current_function_decl) != error_mark_node)
    {
      /* Seen already, skip it.  An error message has already been output.  */
      cp_parser_skip_to_end_of_block_or_statement (parser);
      fn = current_function_decl;
      current_function_decl = NULL_TREE;
      /* If this is a function from a class, pop the nested class.  */
      if (current_class_name)
	pop_nested_class ();
    }
  else
    {
      auto_timevar tv (DECL_DECLARED_INLINE_P (current_function_decl)
		       ? TV_PARSE_INLINE : TV_PARSE_FUNC);
      fn = cp_parser_function_definition_after_declarator (parser,
							 /*inline_p=*/false);
    }

  return fn;
}

/* Parse the part of a function-definition that follows the
   declarator.  INLINE_P is TRUE iff this function is an inline
   function defined within a class-specifier.

   Returns the function defined.  */

static tree
cp_parser_function_definition_after_declarator (cp_parser* parser,
						bool inline_p)
{
  tree fn;
  bool saved_in_unbraced_linkage_specification_p;
  bool saved_in_function_body;
  unsigned saved_num_template_parameter_lists;
  cp_token *token;
  bool fully_implicit_function_template_p
    = parser->fully_implicit_function_template_p;
  parser->fully_implicit_function_template_p = false;
  tree implicit_template_parms
    = parser->implicit_template_parms;
  parser->implicit_template_parms = 0;
  cp_binding_level* implicit_template_scope
    = parser->implicit_template_scope;
  parser->implicit_template_scope = 0;

  saved_in_function_body = parser->in_function_body;
  parser->in_function_body = true;
  /* If the next token is `return', then the code may be trying to
     make use of the "named return value" extension that G++ used to
     support.  */
  token = cp_lexer_peek_token (parser->lexer);
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_RETURN))
    {
      /* Consume the `return' keyword.  */
      cp_lexer_consume_token (parser->lexer);
      /* Look for the identifier that indicates what value is to be
	 returned.  */
      cp_parser_identifier (parser);
      /* Issue an error message.  */
      error_at (token->location,
		"named return values are no longer supported");
      /* Skip tokens until we reach the start of the function body.  */
      while (true)
	{
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  if (token->type == CPP_OPEN_BRACE
	      || token->type == CPP_EOF
	      || token->type == CPP_PRAGMA_EOL)
	    break;
	  cp_lexer_consume_token (parser->lexer);
	}
    }
  /* The `extern' in `extern "C" void f () { ... }' does not apply to
     anything declared inside `f'.  */
  saved_in_unbraced_linkage_specification_p
    = parser->in_unbraced_linkage_specification_p;
  parser->in_unbraced_linkage_specification_p = false;
  /* Inside the function, surrounding template-parameter-lists do not
     apply.  */
  saved_num_template_parameter_lists
    = parser->num_template_parameter_lists;
  parser->num_template_parameter_lists = 0;

  /* If the next token is `try', `__transaction_atomic', or
     `__transaction_relaxed`, then we are looking at either function-try-block
     or function-transaction-block.  Note that all of these include the
     function-body.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_ATOMIC))
    cp_parser_function_transaction (parser, RID_TRANSACTION_ATOMIC);
  else if (cp_lexer_next_token_is_keyword (parser->lexer,
      RID_TRANSACTION_RELAXED))
    cp_parser_function_transaction (parser, RID_TRANSACTION_RELAXED);
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
    cp_parser_function_try_block (parser);
  else
    cp_parser_ctor_initializer_opt_and_function_body
      (parser, /*in_function_try_block=*/false);

  /* Finish the function.  */
  fn = finish_function (inline_p);

  if (modules_p ()
      && !inline_p
      && TYPE_P (DECL_CONTEXT (fn))
      && (DECL_DECLARED_INLINE_P (fn)
	  || processing_template_decl))
    set_defining_module (fn);

  /* Generate code for it, if necessary.  */
  expand_or_defer_fn (fn);

  /* Restore the saved values.  */
  parser->in_unbraced_linkage_specification_p
    = saved_in_unbraced_linkage_specification_p;
  parser->num_template_parameter_lists
    = saved_num_template_parameter_lists;
  parser->in_function_body = saved_in_function_body;

  parser->fully_implicit_function_template_p
    = fully_implicit_function_template_p;
  parser->implicit_template_parms
    = implicit_template_parms;
  parser->implicit_template_scope
    = implicit_template_scope;

  if (parser->fully_implicit_function_template_p)
    finish_fully_implicit_template (parser, /*member_decl_opt=*/0);

  return fn;
}

/* Parse a template-declaration body (following argument list).  */

static void
cp_parser_template_declaration_after_parameters (cp_parser* parser,
						 tree parameter_list,
						 bool member_p)
{
  tree decl = NULL_TREE;
  bool friend_p = false;

  /* We just processed one more parameter list.  */
  ++parser->num_template_parameter_lists;

  /* Get the deferred access checks from the parameter list.  These
     will be checked once we know what is being declared, as for a
     member template the checks must be performed in the scope of the
     class containing the member.  */
  vec<deferred_access_check, va_gc> *checks = get_deferred_access_checks ();

  /* Tentatively parse for a new template parameter list, which can either be
     the template keyword or a template introduction.  */
  if (cp_parser_template_declaration_after_export (parser, member_p))
    /* OK */;
  else if (cxx_dialect >= cxx11
	   && cp_lexer_next_token_is_keyword (parser->lexer, RID_USING))
    decl = cp_parser_alias_declaration (parser);
  else if (flag_concepts
           && cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)
	   && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
    /* -fconcept-ts 'concept bool' syntax is handled below, in
	cp_parser_single_declaration.  */
    decl = cp_parser_concept_definition (parser);
  else
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);
      decl = cp_parser_single_declaration (parser,
					   checks,
					   member_p,
                                           /*explicit_specialization_p=*/false,
					   &friend_p);

      /* If this is a member template declaration, let the front
	 end know.  */
      if (member_p && !friend_p && decl)
	{
	  if (TREE_CODE (decl) == TYPE_DECL)
	    cp_parser_check_access_in_redeclaration (decl, token->location);

	  decl = finish_member_template_decl (decl);
	}
      else if (friend_p && decl
	       && DECL_DECLARES_TYPE_P (decl))
	make_friend_class (current_class_type, TREE_TYPE (decl),
			   /*complain=*/true);
    }
  /* We are done with the current parameter list.  */
  --parser->num_template_parameter_lists;

  pop_deferring_access_checks ();

  /* Finish up.  */
  finish_template_decl (parameter_list);

  /* Check the template arguments for a literal operator template.  */
  if (decl
      && DECL_DECLARES_FUNCTION_P (decl)
      && UDLIT_OPER_P (DECL_NAME (decl)))
    {
      bool ok = true;
      if (parameter_list == NULL_TREE)
	ok = false;
      else
	{
	  int num_parms = TREE_VEC_LENGTH (parameter_list);
	  if (num_parms == 1)
	    {
	      tree parm_list = TREE_VEC_ELT (parameter_list, 0);
	      tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
	      if (TREE_CODE (parm) != PARM_DECL)
		ok = false;
	      else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))
		       && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
		/* OK, C++20 string literal operator template.  We don't need
		   to warn in lower dialects here because we will have already
		   warned about the template parameter.  */;
	      else if (TREE_TYPE (parm) != char_type_node
		       || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
		ok = false;
	    }
	  else if (num_parms == 2 && cxx_dialect >= cxx14)
	    {
	      tree parm_type = TREE_VEC_ELT (parameter_list, 0);
	      tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
	      tree parm_list = TREE_VEC_ELT (parameter_list, 1);
	      tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
	      if (TREE_CODE (parm) != PARM_DECL
		  || TREE_TYPE (parm) != TREE_TYPE (type)
		  || !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
		ok = false;
	      else
		/* http://cplusplus.github.io/EWG/ewg-active.html#66  */
		pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
			 "ISO C++ did not adopt string literal operator templa"
			 "tes taking an argument pack of characters");
	    }
	  else
	    ok = false;
	}
      if (!ok)
	{
	  if (cxx_dialect > cxx17)
	    error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
		      "template %qD has invalid parameter list; expected "
		      "non-type template parameter pack %<<char...>%> or "
		      "single non-type parameter of class type",
		      decl);
	  else
	    error_at (DECL_SOURCE_LOCATION (decl), "literal operator "
		      "template %qD has invalid parameter list; expected "
		      "non-type template parameter pack %<<char...>%>",
		      decl);
	}
    }

  /* Register member declarations.  */
  if (member_p && !friend_p && decl && !DECL_CLASS_TEMPLATE_P (decl))
    finish_member_declaration (decl);
  /* If DECL is a function template, we must return to parse it later.
     (Even though there is no definition, there might be default
     arguments that need handling.)  */
  if (member_p && decl
      && DECL_DECLARES_FUNCTION_P (decl))
    vec_safe_push (unparsed_funs_with_definitions, decl);
}

/* Parse a template introduction header for a template-declaration.  Returns
   false if tentative parse fails.  */

static bool
cp_parser_template_introduction (cp_parser* parser, bool member_p)
{
  cp_parser_parse_tentatively (parser);

  tree saved_scope = parser->scope;
  tree saved_object_scope = parser->object_scope;
  tree saved_qualifying_scope = parser->qualifying_scope;
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;

  cp_token *start_token = cp_lexer_peek_token (parser->lexer);

  /* In classes don't parse valid unnamed bitfields as invalid
     template introductions.  */
  if (member_p)
    parser->colon_corrects_to_scope_p = false;

  /* Look for the optional `::' operator.  */
  cp_parser_global_scope_opt (parser,
			      /*current_scope_valid_p=*/false);
  /* Look for the nested-name-specifier.  */
  cp_parser_nested_name_specifier_opt (parser,
				       /*typename_keyword_p=*/false,
				       /*check_dependency_p=*/true,
				       /*type_p=*/false,
				       /*is_declaration=*/false);

  cp_token *token = cp_lexer_peek_token (parser->lexer);
  tree concept_name = cp_parser_identifier (parser);

  /* Look up the concept for which we will be matching
     template parameters.  */
  tree tmpl_decl = cp_parser_lookup_name_simple (parser, concept_name,
						 token->location);
  parser->scope = saved_scope;
  parser->object_scope = saved_object_scope;
  parser->qualifying_scope = saved_qualifying_scope;
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;

  if (concept_name == error_mark_node
      || (seen_error () && !concept_definition_p (tmpl_decl)))
    cp_parser_simulate_error (parser);

  /* Look for opening brace for introduction.  */
  matching_braces braces;
  braces.require_open (parser);
  location_t open_loc = input_location;

  if (!cp_parser_parse_definitely (parser))
    return false;

  push_deferring_access_checks (dk_deferred);

  /* Build vector of placeholder parameters and grab
     matching identifiers.  */
  tree introduction_list = cp_parser_introduction_list (parser);

  /* Look for closing brace for introduction.  */
  if (!braces.require_close (parser))
    return true;

  /* The introduction-list shall not be empty.  */
  int nargs = TREE_VEC_LENGTH (introduction_list);
  if (nargs == 0)
    {
      /* In cp_parser_introduction_list we have already issued an error.  */
      return true;
    }

  if (tmpl_decl == error_mark_node)
    {
      cp_parser_name_lookup_error (parser, concept_name, tmpl_decl, NLE_NULL,
				   token->location);
      return true;
    }

  /* Build and associate the constraint.  */
  location_t introduction_loc = make_location (open_loc,
					       start_token->location,
					       parser->lexer);
  tree parms = finish_template_introduction (tmpl_decl,
					     introduction_list,
					     introduction_loc);
  if (parms && parms != error_mark_node)
    {
      if (!flag_concepts_ts)
	pedwarn (introduction_loc, 0, "template-introductions"
		 " are not part of C++20 concepts; use %qs to enable",
		 "-fconcepts-ts");

      cp_parser_template_declaration_after_parameters (parser, parms,
						       member_p);
      return true;
    }

  if (parms == NULL_TREE)
    error_at (token->location, "no matching concept for template-introduction");

  return true;
}

/* Parse a normal template-declaration following the template keyword.  */

static void
cp_parser_explicit_template_declaration (cp_parser* parser, bool member_p)
{
  tree parameter_list;
  bool need_lang_pop;
  location_t location = input_location;

  /* Look for the `<' token.  */
  if (!cp_parser_require (parser, CPP_LESS, RT_LESS))
    return;
  if (at_class_scope_p () && current_function_decl)
    {
      /* 14.5.2.2 [temp.mem]

         A local class shall not have member templates.  */
      error_at (location,
                "invalid declaration of member template in local class");
      cp_parser_skip_to_end_of_block_or_statement (parser);
      return;
    }
  /* [temp]

     A template ... shall not have C linkage.  */
  if (current_lang_name == lang_name_c)
    {
      error_at (location, "template with C linkage");
      maybe_show_extern_c_location ();
      /* Give it C++ linkage to avoid confusing other parts of the
         front end.  */
      push_lang_context (lang_name_cplusplus);
      need_lang_pop = true;
    }
  else
    need_lang_pop = false;

  /* We cannot perform access checks on the template parameter
     declarations until we know what is being declared, just as we
     cannot check the decl-specifier list.  */
  push_deferring_access_checks (dk_deferred);

  /* If the next token is `>', then we have an invalid
     specialization.  Rather than complain about an invalid template
     parameter, issue an error message here.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER))
    {
      cp_parser_error (parser, "invalid explicit specialization");
      begin_specialization ();
      parameter_list = NULL_TREE;
    }
  else
    {
      /* Parse the template parameters.  */
      parameter_list = cp_parser_template_parameter_list (parser);
    }

  /* Look for the `>'.  */
  cp_parser_require_end_of_template_parameter_list (parser);

  /* Manage template requirements */
  if (flag_concepts)
  {
    tree reqs = get_shorthand_constraints (current_template_parms);
    if (tree treqs = cp_parser_requires_clause_opt (parser, false))
      reqs = combine_constraint_expressions (reqs, treqs);
    TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
  }

  cp_parser_template_declaration_after_parameters (parser, parameter_list,
						   member_p);

  /* For the erroneous case of a template with C linkage, we pushed an
     implicit C++ linkage scope; exit that scope now.  */
  if (need_lang_pop)
    pop_lang_context ();
}

/* Parse a template-declaration, assuming that the `export' (and
   `extern') keywords, if present, has already been scanned.  MEMBER_P
   is as for cp_parser_template_declaration.  */

static bool
cp_parser_template_declaration_after_export (cp_parser* parser, bool member_p)
{
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
    {
      cp_lexer_consume_token (parser->lexer);
      cp_parser_explicit_template_declaration (parser, member_p);
      return true;
    }
  else if (flag_concepts)
    return cp_parser_template_introduction (parser, member_p);

  return false;
}

/* Perform the deferred access checks from a template-parameter-list.
   CHECKS is a TREE_LIST of access checks, as returned by
   get_deferred_access_checks.  */

static void
cp_parser_perform_template_parameter_access_checks (vec<deferred_access_check, va_gc> *checks)
{
  ++processing_template_parmlist;
  perform_access_checks (checks, tf_warning_or_error);
  --processing_template_parmlist;
}

/* Parse a `decl-specifier-seq [opt] init-declarator [opt] ;' or
   `function-definition' sequence that follows a template header.
   If MEMBER_P is true, this declaration appears in a class scope.

   Returns the DECL for the declared entity.  If FRIEND_P is non-NULL,
   *FRIEND_P is set to TRUE iff the declaration is a friend.  */

static tree
cp_parser_single_declaration (cp_parser* parser,
			      vec<deferred_access_check, va_gc> *checks,
			      bool member_p,
                              bool explicit_specialization_p,
			      bool* friend_p)
{
  int declares_class_or_enum;
  tree decl = NULL_TREE;
  cp_decl_specifier_seq decl_specifiers;
  bool function_definition_p = false;
  cp_token *decl_spec_token_start;

  /* This function is only used when processing a template
     declaration.  */
  gcc_assert (innermost_scope_kind () == sk_template_parms
	      || innermost_scope_kind () == sk_template_spec);

  /* Defer access checks until we know what is being declared.  */
  push_deferring_access_checks (dk_deferred);

  /* Try the `decl-specifier-seq [opt] init-declarator [opt]'
     alternative.  */
  decl_spec_token_start = cp_lexer_peek_token (parser->lexer);
  cp_parser_decl_specifier_seq (parser,
				(CP_PARSER_FLAGS_OPTIONAL
				 | CP_PARSER_FLAGS_TYPENAME_OPTIONAL),
				&decl_specifiers,
				&declares_class_or_enum);

  cp_omp_declare_simd_data odsd;
  if (decl_specifiers.attributes && (flag_openmp || flag_openmp_simd))
    cp_parser_handle_directive_omp_attributes (parser,
					       &decl_specifiers.attributes,
					       &odsd, true);

  if (friend_p)
    *friend_p = cp_parser_friend_p (&decl_specifiers);

  /* There are no template typedefs.  */
  if (decl_spec_seq_has_spec_p (&decl_specifiers, ds_typedef))
    {
      error_at (decl_spec_token_start->location,
		"template declaration of %<typedef%>");
      decl = error_mark_node;
    }

  /* Gather up the access checks that occurred the
     decl-specifier-seq.  */
  stop_deferring_access_checks ();

  /* Check for the declaration of a template class.  */
  if (declares_class_or_enum)
    {
      if (cp_parser_declares_only_class_p (parser)
	  || (declares_class_or_enum & 2))
	{
	  decl = shadow_tag (&decl_specifiers);

	  /* In this case:

	       struct C {
		 friend template <typename T> struct A<T>::B;
	       };

	     A<T>::B will be represented by a TYPENAME_TYPE, and
	     therefore not recognized by shadow_tag.  */
	  if (friend_p && *friend_p
	      && !decl
	      && decl_specifiers.type
	      && TYPE_P (decl_specifiers.type))
	    decl = decl_specifiers.type;

	  if (decl && decl != error_mark_node)
	    decl = TYPE_NAME (decl);
	  else
	    decl = error_mark_node;

	  /* If this is a declaration, but not a definition, associate
	     any constraints with the type declaration. Constraints
	     are associated with definitions in cp_parser_class_specifier.  */
	  if (declares_class_or_enum == 1)
	    associate_classtype_constraints (TREE_TYPE (decl));

	  /* Perform access checks for template parameters.  */
	  cp_parser_perform_template_parameter_access_checks (checks);

	  /* Give a helpful diagnostic for
	       template <class T> struct A { } a;
	     if we aren't already recovering from an error.  */
	  if (!cp_parser_declares_only_class_p (parser)
	      && !seen_error ())
	    {
	      error_at (cp_lexer_peek_token (parser->lexer)->location,
			"a class template declaration must not declare "
			"anything else");
	      cp_parser_skip_to_end_of_block_or_statement (parser);
	      goto out;
	    }
	}
    }

  /* Complain about missing 'typename' or other invalid type names.  */
  if (!decl_specifiers.any_type_specifiers_p
      && cp_parser_parse_and_diagnose_invalid_type_name (parser))
    {
      /* cp_parser_parse_and_diagnose_invalid_type_name calls
	 cp_parser_skip_to_end_of_block_or_statement, so don't try to parse
	 the rest of this declaration.  */
      decl = error_mark_node;
      goto out;
    }

  /* If it's not a template class, try for a template function.  If
     the next token is a `;', then this declaration does not declare
     anything.  But, if there were errors in the decl-specifiers, then
     the error might well have come from an attempted class-specifier.
     In that case, there's no need to warn about a missing declarator.  */
  if (!decl
      && (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)
	  || decl_specifiers.type != error_mark_node))
    {
      int flags = CP_PARSER_FLAGS_TYPENAME_OPTIONAL;
      /* We don't delay parsing for friends, though CWG 2510 may change
	 that.  */
      if (member_p && !(friend_p && *friend_p))
	flags |= CP_PARSER_FLAGS_DELAY_NOEXCEPT;
      decl = cp_parser_init_declarator (parser,
					flags,
				        &decl_specifiers,
				        checks,
				        /*function_definition_allowed_p=*/true,
				        member_p,
				        declares_class_or_enum,
				        &function_definition_p,
					NULL, NULL, NULL);

    /* 7.1.1-1 [dcl.stc]

       A storage-class-specifier shall not be specified in an explicit
       specialization...  */
    if (decl
        && explicit_specialization_p
        && decl_specifiers.storage_class != sc_none)
      {
        error_at (decl_spec_token_start->location,
		  "explicit template specialization cannot have a storage class");
        decl = error_mark_node;
      }

    if (decl && VAR_P (decl))
      check_template_variable (decl);
    }

  /* Look for a trailing `;' after the declaration.  */
  if (!function_definition_p
      && (decl == error_mark_node
	  || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON)))
    cp_parser_skip_to_end_of_block_or_statement (parser);

 out:
  pop_deferring_access_checks ();

  /* Clear any current qualification; whatever comes next is the start
     of something new.  */
  parser->scope = NULL_TREE;
  parser->qualifying_scope = NULL_TREE;
  parser->object_scope = NULL_TREE;

  cp_finalize_omp_declare_simd (parser, &odsd);

  return decl;
}

/* Parse a cast-expression that is not the operand of a unary "&".  */

static cp_expr
cp_parser_simple_cast_expression (cp_parser *parser)
{
  return cp_parser_cast_expression (parser, /*address_p=*/false,
				    /*cast_p=*/false, /*decltype*/false, NULL);
}

/* Parse a functional cast to TYPE.  Returns an expression
   representing the cast.  */

static cp_expr
cp_parser_functional_cast (cp_parser* parser, tree type)
{
  vec<tree, va_gc> *vec;
  tree expression_list;
  cp_expr cast;
  bool nonconst_p;

  location_t start_loc = input_location;

  if (!type)
    type = error_mark_node;

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
    {
      cp_lexer_set_source_position (parser->lexer);
      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
      expression_list = cp_parser_braced_list (parser, &nonconst_p);
      CONSTRUCTOR_IS_DIRECT_INIT (expression_list) = 1;
      if (TREE_CODE (type) == TYPE_DECL)
	type = TREE_TYPE (type);

      cast = finish_compound_literal (type, expression_list,
				      tf_warning_or_error, fcl_functional);
      /* Create a location of the form:
	    type_name{i, f}
	    ^~~~~~~~~~~~~~~
	 with caret == start at the start of the type name,
	 finishing at the closing brace.  */
      location_t combined_loc = make_location (start_loc, start_loc,
					       parser->lexer);
      cast.set_location (combined_loc);
      return cast;
   }


  vec = cp_parser_parenthesized_expression_list (parser, non_attr,
						 /*cast_p=*/true,
						 /*allow_expansion_p=*/true,
						 /*non_constant_p=*/NULL);
  if (vec == NULL)
    expression_list = error_mark_node;
  else
    {
      expression_list = build_tree_list_vec (vec);
      release_tree_vector (vec);
    }

  /* Create a location of the form:
       float(i)
       ^~~~~~~~
     with caret == start at the start of the type name,
     finishing at the closing paren.  */
  location_t combined_loc = make_location (start_loc, start_loc,
					   parser->lexer);
  cast = build_functional_cast (combined_loc, type, expression_list,
                                tf_warning_or_error);
  
  /* [expr.const]/1: In an integral constant expression "only type
     conversions to integral or enumeration type can be used".  */
  if (TREE_CODE (type) == TYPE_DECL)
    type = TREE_TYPE (type);
  if (cast != error_mark_node
      && !cast_valid_in_integral_constant_expression_p (type)
      && cp_parser_non_integral_constant_expression (parser,
						     NIC_CONSTRUCTOR))
    return error_mark_node;

  return cast;
}

/* Save the tokens that make up the body of a member function defined
   in a class-specifier.  The DECL_SPECIFIERS and DECLARATOR have
   already been parsed.  The ATTRIBUTES are any GNU "__attribute__"
   specifiers applied to the declaration.  Returns the FUNCTION_DECL
   for the member function.  */

static tree
cp_parser_save_member_function_body (cp_parser* parser,
				     cp_decl_specifier_seq *decl_specifiers,
				     cp_declarator *declarator,
				     tree attributes)
{
  cp_token *first;
  cp_token *last;
  tree fn;
  bool function_try_block = false;

  /* Create the FUNCTION_DECL.  */
  fn = grokmethod (decl_specifiers, declarator, attributes);
  cp_finalize_omp_declare_simd (parser, fn);
  cp_finalize_oacc_routine (parser, fn, true);
  /* If something went badly wrong, bail out now.  */
  if (fn == error_mark_node)
    {
      /* If there's a function-body, skip it.  */
      if (cp_parser_token_starts_function_definition_p
	  (cp_lexer_peek_token (parser->lexer)))
	cp_parser_skip_to_end_of_block_or_statement (parser);
      return error_mark_node;
    }

  /* Remember it, if there are default args to post process.  */
  cp_parser_save_default_args (parser, fn);

  /* Save away the tokens that make up the body of the
     function.  */
  first = parser->lexer->next_token;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRANSACTION_RELAXED))
    cp_lexer_consume_token (parser->lexer);
  else if (cp_lexer_next_token_is_keyword (parser->lexer,
					   RID_TRANSACTION_ATOMIC))
    {
      cp_lexer_consume_token (parser->lexer);
      /* Match cp_parser_txn_attribute_opt [[ identifier ]].  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_SQUARE)
	  && (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME)
	      || cp_lexer_nth_token_is (parser->lexer, 3, CPP_KEYWORD))
	  && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_SQUARE)
	  && cp_lexer_nth_token_is (parser->lexer, 5, CPP_CLOSE_SQUARE))
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	}
      else
	while (cp_next_tokens_can_be_gnu_attribute_p (parser)
	       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
	  {
	    cp_lexer_consume_token (parser->lexer);
	    if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
	      break;
	  }
    }

  /* Handle function try blocks.  */
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
    {
      cp_lexer_consume_token (parser->lexer);
      function_try_block = true;
    }
  /* We can have braced-init-list mem-initializers before the fn body.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      cp_lexer_consume_token (parser->lexer);
      while (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE))
	{
	  /* cache_group will stop after an un-nested { } pair, too.  */
	  if (cp_parser_cache_group (parser, CPP_CLOSE_PAREN, /*depth=*/0))
	    break;

	  /* variadic mem-inits have ... after the ')'.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	    cp_lexer_consume_token (parser->lexer);
	}
    }
  cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
  /* Handle function try blocks.  */
  if (function_try_block)
    while (cp_lexer_next_token_is_keyword (parser->lexer, RID_CATCH))
      cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
  last = parser->lexer->next_token;

  /* Save away the inline definition; we will process it when the
     class is complete.  */
  DECL_PENDING_INLINE_INFO (fn) = cp_token_cache_new (first, last);
  DECL_PENDING_INLINE_P (fn) = 1;

  /* We need to know that this was defined in the class, so that
     friend templates are handled correctly.  */
  DECL_INITIALIZED_IN_CLASS_P (fn) = 1;

  /* Add FN to the queue of functions to be parsed later.  */
  vec_safe_push (unparsed_funs_with_definitions, fn);

  return fn;
}

/* Save the tokens that make up the in-class initializer for a non-static
   data member.  Returns a DEFERRED_PARSE.  */

static tree
cp_parser_save_nsdmi (cp_parser* parser)
{
  return cp_parser_cache_defarg (parser, /*nsdmi=*/true);
}

/* Parse a template-argument-list, as well as the trailing ">" (but
   not the opening "<").  See cp_parser_template_argument_list for the
   return value.  */

static tree
cp_parser_enclosed_template_argument_list (cp_parser* parser)
{
  tree arguments;
  tree saved_scope;
  tree saved_qualifying_scope;
  tree saved_object_scope;
  bool saved_greater_than_is_operator_p;

  /* [temp.names]

     When parsing a template-id, the first non-nested `>' is taken as
     the end of the template-argument-list rather than a greater-than
     operator.  */
  saved_greater_than_is_operator_p
    = parser->greater_than_is_operator_p;
  parser->greater_than_is_operator_p = false;
  /* Parsing the argument list may modify SCOPE, so we save it
     here.  */
  saved_scope = parser->scope;
  saved_qualifying_scope = parser->qualifying_scope;
  saved_object_scope = parser->object_scope;
  /* We need to evaluate the template arguments, even though this
     template-id may be nested within a "sizeof".  */
  cp_evaluated ev;
  /* Parse the template-argument-list itself.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER)
      || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT)
      || cp_lexer_next_token_is (parser->lexer, CPP_GREATER_EQ)
      || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT_EQ))
    {
      arguments = make_tree_vec (0);
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (arguments, 0);
    }
  else
    arguments = cp_parser_template_argument_list (parser);
  /* Look for the `>' that ends the template-argument-list. If we find
     a '>>' instead, it's probably just a typo.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT))
    {
      if (cxx_dialect != cxx98)
        {
          /* In C++0x, a `>>' in a template argument list or cast
             expression is considered to be two separate `>'
             tokens. So, change the current token to a `>', but don't
             consume it: it will be consumed later when the outer
             template argument list (or cast expression) is parsed.
             Note that this replacement of `>' for `>>' is necessary
             even if we are parsing tentatively: in the tentative
             case, after calling
             cp_parser_enclosed_template_argument_list we will always
             throw away all of the template arguments and the first
             closing `>', either because the template argument list
             was erroneous or because we are replacing those tokens
             with a CPP_TEMPLATE_ID token.  The second `>' (which will
             not have been thrown away) is needed either to close an
             outer template argument list or to complete a new-style
             cast.  */
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
          token->type = CPP_GREATER;
        }
      else if (!saved_greater_than_is_operator_p)
	{
	  /* If we're in a nested template argument list, the '>>' has
	    to be a typo for '> >'. We emit the error message, but we
	    continue parsing and we push a '>' as next token, so that
	    the argument list will be parsed correctly.  Note that the
	    global source location is still on the token before the
	    '>>', so we need to say explicitly where we want it.  */
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  gcc_rich_location richloc (token->location);
	  richloc.add_fixit_replace ("> >");
	  error_at (&richloc, "%<>>%> should be %<> >%> "
		    "within a nested template argument list");

	  token->type = CPP_GREATER;
	}
      else
	{
	  /* If this is not a nested template argument list, the '>>'
	    is a typo for '>'. Emit an error message and continue.
	    Same deal about the token location, but here we can get it
	    right by consuming the '>>' before issuing the diagnostic.  */
	  cp_token *token = cp_lexer_consume_token (parser->lexer);
	  error_at (token->location,
		    "spurious %<>>%>, use %<>%> to terminate "
		    "a template argument list");
	}
    }
  /* Similarly for >>= and >=.  */
  else if (cp_lexer_next_token_is (parser->lexer, CPP_GREATER_EQ)
	   || cp_lexer_next_token_is (parser->lexer, CPP_RSHIFT_EQ))
    {
      cp_token *token = cp_lexer_consume_token (parser->lexer);
      gcc_rich_location richloc (token->location);
      enum cpp_ttype new_type;
      const char *replacement;
      if (token->type == CPP_GREATER_EQ)
	{
	  replacement = "> =";
	  new_type = CPP_EQ;
	}
      else if (!saved_greater_than_is_operator_p)
	{
	  if (cxx_dialect != cxx98)
	    replacement = ">> =";
	  else
	    replacement = "> > =";
	  new_type = CPP_GREATER;
	}
      else
	{
	  replacement = "> >=";
	  new_type = CPP_GREATER_EQ;
	}
      richloc.add_fixit_replace (replacement);
      error_at (&richloc, "%qs should be %qs to terminate a template "
		"argument list",
		cpp_type2name (token->type, token->flags), replacement);
      token->type = new_type;
    }
  else
    cp_parser_require_end_of_template_parameter_list (parser);
  /* The `>' token might be a greater-than operator again now.  */
  parser->greater_than_is_operator_p
    = saved_greater_than_is_operator_p;
  /* Restore the SAVED_SCOPE.  */
  parser->scope = saved_scope;
  parser->qualifying_scope = saved_qualifying_scope;
  parser->object_scope = saved_object_scope;

  return arguments;
}

/* MEMBER_FUNCTION is a member function, or a friend.  If default
   arguments, or the body of the function have not yet been parsed,
   parse them now.  */

static void
cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function)
{
  auto_timevar tv (TV_PARSE_INMETH);

  /* If this member is a template, get the underlying
     FUNCTION_DECL.  */
  if (DECL_FUNCTION_TEMPLATE_P (member_function))
    member_function = DECL_TEMPLATE_RESULT (member_function);

  /* There should not be any class definitions in progress at this
     point; the bodies of members are only parsed outside of all class
     definitions.  */
  gcc_assert (parser->num_classes_being_defined == 0);
  /* While we're parsing the member functions we might encounter more
     classes.  We want to handle them right away, but we don't want
     them getting mixed up with functions that are currently in the
     queue.  */
  push_unparsed_function_queues (parser);

  /* Make sure that any template parameters are in scope.  */
  maybe_begin_member_template_processing (member_function);

  /* If the body of the function has not yet been parsed, parse it
     now.  Except if the tokens have been purged (PR c++/39751).  */
  if (DECL_PENDING_INLINE_P (member_function)
      && !DECL_PENDING_INLINE_INFO (member_function)->first->purged_p)
    {
      tree function_scope;
      cp_token_cache *tokens;

      /* The function is no longer pending; we are processing it.  */
      tokens = DECL_PENDING_INLINE_INFO (member_function);
      DECL_PENDING_INLINE_INFO (member_function) = NULL;
      DECL_PENDING_INLINE_P (member_function) = 0;

      /* If this is a local class, enter the scope of the containing
	 function.  */
      function_scope = current_function_decl;
      if (function_scope)
	push_function_context ();

      /* Push the body of the function onto the lexer stack.  */
      cp_parser_push_lexer_for_tokens (parser, tokens);

      /* Let the front end know that we going to be defining this
	 function.  */
      start_preparsed_function (member_function, NULL_TREE,
				SF_PRE_PARSED | SF_INCLASS_INLINE);

      /* #pragma omp declare reduction needs special parsing.  */
      if (DECL_OMP_DECLARE_REDUCTION_P (member_function))
	{
	  parser->lexer->in_pragma = true;
	  cp_parser_omp_declare_reduction_exprs (member_function, parser);
	  finish_function (/*inline_p=*/true);
	  cp_check_omp_declare_reduction (member_function);
	}
      else
	/* Now, parse the body of the function.  */
	cp_parser_function_definition_after_declarator (parser,
							/*inline_p=*/true);

      /* Leave the scope of the containing function.  */
      if (function_scope)
	pop_function_context ();
      cp_parser_pop_lexer (parser);
    }

  /* Remove any template parameters from the symbol table.  */
  maybe_end_member_template_processing ();

  /* Restore the queue.  */
  pop_unparsed_function_queues (parser);
}

/* If DECL contains any default args, remember it on the unparsed
   functions queue.  */

static void
cp_parser_save_default_args (cp_parser* parser, tree decl)
{
  tree probe;

  for (probe = TYPE_ARG_TYPES (TREE_TYPE (decl));
       probe;
       probe = TREE_CHAIN (probe))
    if (TREE_PURPOSE (probe))
      {
	cp_default_arg_entry entry = {current_class_type, decl};
	vec_safe_push (unparsed_funs_with_default_args, entry);
	break;
      }

  /* Remember if there is a noexcept-specifier to post process.  */
  tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl));
  if (UNPARSED_NOEXCEPT_SPEC_P (spec))
    vec_safe_push (unparsed_noexcepts, decl);

  /* Contracts are deferred.  */
  for (tree attr = DECL_ATTRIBUTES (decl); attr; attr = TREE_CHAIN (attr))
    if (cxx_contract_attribute_p (attr))
      {
	vec_safe_push (unparsed_contracts, decl);
	break;
      }
}

/* DEFAULT_ARG contains the saved tokens for the initializer of DECL,
   which is either a FIELD_DECL or PARM_DECL.  Parse it and return
   the result.  For a PARM_DECL, PARMTYPE is the corresponding type
   from the parameter-type-list.  */

static tree
cp_parser_late_parse_one_default_arg (cp_parser *parser, tree decl,
				      tree default_arg, tree parmtype)
{
  cp_token_cache *tokens;
  tree parsed_arg;
  bool dummy;

  if (default_arg == error_mark_node)
    return error_mark_node;

  /* Push the saved tokens for the default argument onto the parser's
     lexer stack.  */
  tokens = DEFPARSE_TOKENS (default_arg);
  cp_parser_push_lexer_for_tokens (parser, tokens);

  start_lambda_scope (decl);

  /* Parse the default argument.  */
  parsed_arg = cp_parser_initializer (parser, &dummy, &dummy);
  if (BRACE_ENCLOSED_INITIALIZER_P (parsed_arg))
    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);

  finish_lambda_scope ();

  if (parsed_arg == error_mark_node)
    cp_parser_skip_to_end_of_statement (parser);

  if (!processing_template_decl)
    {
      /* In a non-template class, check conversions now.  In a template,
	 we'll wait and instantiate these as needed.  */
      if (TREE_CODE (decl) == PARM_DECL)
	parsed_arg = check_default_argument (parmtype, parsed_arg,
					     tf_warning_or_error);
      else if (maybe_reject_flexarray_init (decl, parsed_arg))
	parsed_arg = error_mark_node;
      else
	parsed_arg = digest_nsdmi_init (decl, parsed_arg, tf_warning_or_error);
    }

  /* If the token stream has not been completely used up, then
     there was extra junk after the end of the default
     argument.  */
  if (!cp_lexer_next_token_is (parser->lexer, CPP_EOF))
    {
      if (TREE_CODE (decl) == PARM_DECL)
	cp_parser_error (parser, "expected %<,%>");
      else
	cp_parser_error (parser, "expected %<;%>");
    }

  /* Revert to the main lexer.  */
  cp_parser_pop_lexer (parser);

  return parsed_arg;
}

/* FIELD is a non-static data member with an initializer which we saved for
   later; parse it now.  */

static void
cp_parser_late_parsing_nsdmi (cp_parser *parser, tree field)
{
  tree def;

  maybe_begin_member_template_processing (field);

  push_unparsed_function_queues (parser);
  def = cp_parser_late_parse_one_default_arg (parser, field,
					      DECL_INITIAL (field),
					      NULL_TREE);
  pop_unparsed_function_queues (parser);

  maybe_end_member_template_processing ();

  DECL_INITIAL (field) = def;
}

/* FN is a FUNCTION_DECL which may contains a parameter with an
   unparsed DEFERRED_PARSE.  Parse the default args now.  This function
   assumes that the current scope is the scope in which the default
   argument should be processed.  */

static void
cp_parser_late_parsing_default_args (cp_parser *parser, tree fn)
{
  unsigned char saved_local_variables_forbidden_p;

  /* While we're parsing the default args, we might (due to the
     statement expression extension) encounter more classes.  We want
     to handle them right away, but we don't want them getting mixed
     up with default args that are currently in the queue.  */
  push_unparsed_function_queues (parser);

  /* Local variable names (and the `this' keyword) may not appear
     in a default argument.  */
  saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
  parser->local_variables_forbidden_p = LOCAL_VARS_AND_THIS_FORBIDDEN;

  push_defarg_context (fn);

  begin_scope (sk_function_parms, fn);

  /* Gather the PARM_DECLs into a vec so we can keep track of them when
     pushdecl clears DECL_CHAIN.  */
  releasing_vec parms;
  for (tree parmdecl = DECL_ARGUMENTS (fn); parmdecl;
       parmdecl = DECL_CHAIN (parmdecl))
    vec_safe_push (parms, parmdecl);

  tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn));
  for (int i = 0;
       parm && parm != void_list_node;
       parm = TREE_CHAIN (parm),
	 ++i)
    {
      tree default_arg = TREE_PURPOSE (parm);
      tree parsed_arg;

      tree parmdecl = parms[i];
      pushdecl (parmdecl);

      if (!default_arg)
	continue;

      if (TREE_CODE (default_arg) != DEFERRED_PARSE)
	/* This can happen for a friend declaration for a function
	   already declared with default arguments.  */
	continue;

      parsed_arg
	= cp_parser_late_parse_one_default_arg (parser, parmdecl,
						default_arg,
						TREE_VALUE (parm));
      TREE_PURPOSE (parm) = parsed_arg;

      /* Update any instantiations we've already created.  */
      for (tree copy : DEFPARSE_INSTANTIATIONS (default_arg))
	TREE_PURPOSE (copy) = parsed_arg;
    }

  pop_bindings_and_leave_scope ();

  /* Restore DECL_CHAINs after clobbering by pushdecl.  */
  parm = NULL_TREE;
  for (int i = parms->length () - 1; i >= 0; --i)
    {
      DECL_CHAIN (parms[i]) = parm;
      parm = parms[i];
    }

  pop_defarg_context ();

  /* Make sure no default arg is missing.  */
  check_default_args (fn);

  /* Restore the state of local_variables_forbidden_p.  */
  parser->local_variables_forbidden_p = saved_local_variables_forbidden_p;

  /* Restore the queue.  */
  pop_unparsed_function_queues (parser);
}

/* Subroutine of cp_parser_sizeof_operand, for handling C++11

     sizeof ... ( identifier )

   where the 'sizeof' token has already been consumed.  */

static tree
cp_parser_sizeof_pack (cp_parser *parser)
{
  /* Consume the `...'.  */
  cp_lexer_consume_token (parser->lexer);
  maybe_warn_variadic_templates ();

  matching_parens parens;
  bool paren = cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN);
  if (paren)
    parens.consume_open (parser);
  else
    permerror (cp_lexer_peek_token (parser->lexer)->location,
	       "%<sizeof...%> argument must be surrounded by parentheses");

  cp_token *token = cp_lexer_peek_token (parser->lexer);
  tree name = cp_parser_identifier (parser);
  if (name == error_mark_node)
    return error_mark_node;
  /* The name is not qualified.  */
  parser->scope = NULL_TREE;
  parser->qualifying_scope = NULL_TREE;
  parser->object_scope = NULL_TREE;
  tree expr = cp_parser_lookup_name_simple (parser, name, token->location);
  if (expr == error_mark_node)
    cp_parser_name_lookup_error (parser, name, expr, NLE_NULL,
				 token->location);
  if (TREE_CODE (expr) == TYPE_DECL || TREE_CODE (expr) == TEMPLATE_DECL)
    expr = TREE_TYPE (expr);
  else if (TREE_CODE (expr) == CONST_DECL)
    expr = DECL_INITIAL (expr);
  expr = make_pack_expansion (expr);
  if (expr != error_mark_node)
    PACK_EXPANSION_SIZEOF_P (expr) = true;

  if (paren)
    parens.require_close (parser);

  return expr;
}

/* Parse the operand of `sizeof' (or a similar operator).  Returns
   either a TYPE or an expression, depending on the form of the
   input.  The KEYWORD indicates which kind of expression we have
   encountered.  */

static tree
cp_parser_sizeof_operand (cp_parser* parser, enum rid keyword)
{
  tree expr = NULL_TREE;
  const char *saved_message;
  const char *saved_message_arg;
  bool saved_integral_constant_expression_p;
  bool saved_non_integral_constant_expression_p;

  /* If it's a `...', then we are computing the length of a parameter
     pack.  */
  if (keyword == RID_SIZEOF
      && cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
    return cp_parser_sizeof_pack (parser);

  /* Types cannot be defined in a `sizeof' expression.  Save away the
     old message.  */
  saved_message = parser->type_definition_forbidden_message;
  saved_message_arg = parser->type_definition_forbidden_message_arg;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in %qs expressions");
  parser->type_definition_forbidden_message_arg
    = IDENTIFIER_POINTER (ridpointers[keyword]);

  /* The restrictions on constant-expressions do not apply inside
     sizeof expressions.  */
  saved_integral_constant_expression_p
    = parser->integral_constant_expression_p;
  saved_non_integral_constant_expression_p
    = parser->non_integral_constant_expression_p;
  parser->integral_constant_expression_p = false;

  auto cleanup = make_temp_override
    (parser->auto_is_implicit_function_template_parm_p, false);

  /* Do not actually evaluate the expression.  */
  ++cp_unevaluated_operand;
  ++c_inhibit_evaluation_warnings;
  /* If it's a `(', then we might be looking at the type-id
     construction.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      tree type = NULL_TREE;

      tentative_firewall firewall (parser);

      /* We can't be sure yet whether we're looking at a type-id or an
	 expression.  */
      cp_parser_parse_tentatively (parser);

      matching_parens parens;
      parens.consume_open (parser);

      /* Note: as a GNU Extension, compound literals are considered
	 postfix-expressions as they are in C99, so they are valid
	 arguments to sizeof.  See comment in cp_parser_cast_expression
	 for details.  */
      if (cp_parser_compound_literal_p (parser))
	cp_parser_simulate_error (parser);
      else
	{
	  bool saved_in_type_id_in_expr_p = parser->in_type_id_in_expr_p;
	  parser->in_type_id_in_expr_p = true;
	  /* Look for the type-id.  */
	  type = cp_parser_type_id (parser);
	  /* Look for the closing `)'.  */
	  parens.require_close (parser);
	  parser->in_type_id_in_expr_p = saved_in_type_id_in_expr_p;
	}

      /* If all went well, then we're done.  */
      if (cp_parser_parse_definitely (parser))
	expr = type;
      else
	{
	  /* Commit to the tentative_firewall so we get syntax errors.  */
	  cp_parser_commit_to_tentative_parse (parser);

	  expr = cp_parser_unary_expression (parser);
	}
    }
  else
    expr = cp_parser_unary_expression (parser);

  /* Go back to evaluating expressions.  */
  --cp_unevaluated_operand;
  --c_inhibit_evaluation_warnings;

  /* And restore the old one.  */
  parser->type_definition_forbidden_message = saved_message;
  parser->type_definition_forbidden_message_arg = saved_message_arg;
  parser->integral_constant_expression_p
    = saved_integral_constant_expression_p;
  parser->non_integral_constant_expression_p
    = saved_non_integral_constant_expression_p;

  return expr;
}

/* If the current declaration has no declarator, return true.  */

static bool
cp_parser_declares_only_class_p (cp_parser *parser)
{
  /* If the next token is a `;' or a `,' then there is no
     declarator.  */
  return (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
	  || cp_lexer_next_token_is (parser->lexer, CPP_COMMA));
}

/* Update the DECL_SPECS to reflect the storage class indicated by
   KEYWORD.  */

static void
cp_parser_set_storage_class (cp_parser *parser,
			     cp_decl_specifier_seq *decl_specs,
			     enum rid keyword,
			     cp_token *token)
{
  cp_storage_class storage_class;

  switch (keyword)
    {
    case RID_AUTO:
      storage_class = sc_auto;
      break;
    case RID_REGISTER:
      storage_class = sc_register;
      break;
    case RID_STATIC:
      storage_class = sc_static;
      break;
    case RID_EXTERN:
      storage_class = sc_extern;
      break;
    case RID_MUTABLE:
      storage_class = sc_mutable;
      break;
    default:
      gcc_unreachable ();
    }

  if (parser->in_unbraced_linkage_specification_p)
    {
      error_at (token->location, "invalid use of %qD in linkage specification",
		ridpointers[keyword]);
      return;
    }
  else if (decl_specs->storage_class != sc_none)
    {
      if (decl_specs->conflicting_specifiers_p)
	return;
      gcc_rich_location richloc (token->location);
      richloc.add_location_if_nearby (decl_specs->locations[ds_storage_class]);
      if (decl_specs->storage_class == storage_class)
	error_at (&richloc, "duplicate %qD specifier", ridpointers[keyword]);
      else
	error_at (&richloc,
		  "%qD specifier conflicts with %qs",
		  ridpointers[keyword],
		  cp_storage_class_name[decl_specs->storage_class]);
      decl_specs->conflicting_specifiers_p = true;
      return;
    }

  if ((keyword == RID_EXTERN || keyword == RID_STATIC)
      && decl_spec_seq_has_spec_p (decl_specs, ds_thread)
      && decl_specs->gnu_thread_keyword_p)
    {
      pedwarn (decl_specs->locations[ds_thread], 0,
		"%<__thread%> before %qD", ridpointers[keyword]);
    }

  decl_specs->storage_class = storage_class;
  set_and_check_decl_spec_loc (decl_specs, ds_storage_class, token);

  /* A storage class specifier cannot be applied alongside a typedef
     specifier. If there is a typedef specifier present then set
     conflicting_specifiers_p which will trigger an error later
     on in grokdeclarator. */
  if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
      && !decl_specs->conflicting_specifiers_p)
    {
      gcc_rich_location richloc (token->location);
      richloc.add_location_if_nearby (decl_specs->locations[ds_typedef]);
      error_at (&richloc,
		"%qD specifier conflicts with %<typedef%>",
		ridpointers[keyword]);
      decl_specs->conflicting_specifiers_p = true;
    }
}

/* Update the DECL_SPECS to reflect the TYPE_SPEC.  If TYPE_DEFINITION_P
   is true, the type is a class or enum definition.  */

static void
cp_parser_set_decl_spec_type (cp_decl_specifier_seq *decl_specs,
			      tree type_spec,
			      cp_token *token,
			      bool type_definition_p)
{
  decl_specs->any_specifiers_p = true;

  /* If the user tries to redeclare bool, char8_t, char16_t, char32_t, or
     wchar_t (with, for example, in "typedef int wchar_t;") we remember that
     this is what happened.  In system headers, we ignore these
     declarations so that G++ can work with system headers that are not
     C++-safe.  */
  if (decl_spec_seq_has_spec_p (decl_specs, ds_typedef)
      && !type_definition_p
      && (type_spec == boolean_type_node
	  || type_spec == char8_type_node
	  || type_spec == char16_type_node
	  || type_spec == char32_type_node
	  || type_spec == wchar_type_node)
      && (decl_specs->type
	  || decl_spec_seq_has_spec_p (decl_specs, ds_long)
	  || decl_spec_seq_has_spec_p (decl_specs, ds_short)
	  || decl_spec_seq_has_spec_p (decl_specs, ds_unsigned)
	  || decl_spec_seq_has_spec_p (decl_specs, ds_signed)))
    {
      decl_specs->redefined_builtin_type = type_spec;
      set_and_check_decl_spec_loc (decl_specs,
				   ds_redefined_builtin_type_spec,
				   token);
      if (!decl_specs->type)
	{
	  decl_specs->type = type_spec;
	  decl_specs->type_definition_p = false;
	  set_and_check_decl_spec_loc (decl_specs,ds_type_spec, token);
	}
    }
  else if (decl_specs->type)
    decl_specs->multiple_types_p = true;
  else
    {
      decl_specs->type = type_spec;
      decl_specs->type_definition_p = type_definition_p;
      decl_specs->redefined_builtin_type = NULL_TREE;
      set_and_check_decl_spec_loc (decl_specs, ds_type_spec, token);
    }
}

/* True iff TOKEN is the GNU keyword __thread.  */

static bool
token_is__thread (cp_token *token)
{
  gcc_assert (token->keyword == RID_THREAD);
  return id_equal (token->u.value, "__thread");
}

/* Set the location for a declarator specifier and check if it is
   duplicated.

   DECL_SPECS is the sequence of declarator specifiers onto which to
   set the location.

   DS is the single declarator specifier to set which location  is to
   be set onto the existing sequence of declarators.

   LOCATION is the location for the declarator specifier to
   consider.  */

static void
set_and_check_decl_spec_loc (cp_decl_specifier_seq *decl_specs,
			     cp_decl_spec ds, cp_token *token)
{
  gcc_assert (ds < ds_last);

  if (decl_specs == NULL)
    return;

  location_t location = token->location;

  if (decl_specs->locations[ds] == 0)
    {
      decl_specs->locations[ds] = location;
      if (ds == ds_thread)
	decl_specs->gnu_thread_keyword_p = token_is__thread (token);
    }
  else
    {
      if (ds == ds_long)
	{
	  if (decl_specs->locations[ds_long_long] != 0)
	    error_at (location,
		      "%<long long long%> is too long for GCC");
	  else
	    {
	      decl_specs->locations[ds_long_long] = location;
	      pedwarn_cxx98 (location,
			     OPT_Wlong_long,
			     "ISO C++ 1998 does not support %<long long%>");
	    }
	}
      else if (ds == ds_thread)
	{
	  bool gnu = token_is__thread (token);
	  gcc_rich_location richloc (location);
	  if (gnu != decl_specs->gnu_thread_keyword_p)
	    {
	      richloc.add_range (decl_specs->locations[ds_thread]);
	      error_at (&richloc,
			"both %<__thread%> and %<thread_local%> specified");
	    }
	  else
	    {
	      richloc.add_fixit_remove ();
	      error_at (&richloc, "duplicate %qD", token->u.value);
	    }
	}
      else
	{
	  static const char *const decl_spec_names[] = {
	    "signed",
	    "unsigned",
	    "short",
	    "long",
	    "const",
	    "volatile",
	    "restrict",
	    "inline",
	    "virtual",
	    "explicit",
	    "friend",
	    "typedef",
	    "using",
	    "constexpr",
	    "__complex",
	    "constinit",
	    "consteval"
	  };
	  gcc_rich_location richloc (location);
	  richloc.add_fixit_remove ();
	  error_at (&richloc, "duplicate %qs", decl_spec_names[ds]);
	}
    }
}

/* Return true iff the declarator specifier DS is present in the
   sequence of declarator specifiers DECL_SPECS.  */

bool
decl_spec_seq_has_spec_p (const cp_decl_specifier_seq * decl_specs,
			  cp_decl_spec ds)
{
  gcc_assert (ds < ds_last);

  if (decl_specs == NULL)
    return false;

  return decl_specs->locations[ds] != 0;
}

/* DECL_SPECIFIERS is the representation of a decl-specifier-seq.
   Returns TRUE iff `friend' appears among the DECL_SPECIFIERS.  */

static bool
cp_parser_friend_p (const cp_decl_specifier_seq *decl_specifiers)
{
  return decl_spec_seq_has_spec_p (decl_specifiers, ds_friend);
}

/* Issue an error message indicating that TOKEN_DESC was expected.
   If KEYWORD is true, it indicated this function is called by
   cp_parser_require_keword and the required token can only be
   a indicated keyword.

   If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
   within any error as the location of an "opening" token matching
   the close token TYPE (e.g. the location of the '(' when TOKEN_DESC is
   RT_CLOSE_PAREN).  */

static void
cp_parser_required_error (cp_parser *parser,
			  required_token token_desc,
			  bool keyword,
			  location_t matching_location)
{
  if (cp_parser_simulate_error (parser))
    return;

  const char *gmsgid = NULL;
  switch (token_desc)
    {
      case RT_NEW:
	gmsgid = G_("expected %<new%>");
	break;
      case RT_DELETE:
	gmsgid = G_("expected %<delete%>");
	break;
      case RT_RETURN:
	gmsgid = G_("expected %<return%>");
	break;
      case RT_WHILE:
	gmsgid = G_("expected %<while%>");
	break;
      case RT_EXTERN:
	gmsgid = G_("expected %<extern%>");
	break;
      case RT_STATIC_ASSERT:
	gmsgid = G_("expected %<static_assert%>");
	break;
      case RT_DECLTYPE:
	gmsgid = G_("expected %<decltype%>");
	break;
      case RT_OPERATOR:
	gmsgid = G_("expected %<operator%>");
	break;
      case RT_CLASS:
	gmsgid = G_("expected %<class%>");
	break;
      case RT_TEMPLATE:
	gmsgid = G_("expected %<template%>");
	break;
      case RT_NAMESPACE:
	gmsgid = G_("expected %<namespace%>");
	break;
      case RT_USING:
	gmsgid = G_("expected %<using%>");
	break;
      case RT_ASM:
	gmsgid = G_("expected %<asm%>");
	break;
      case RT_TRY:
	gmsgid = G_("expected %<try%>");
	break;
      case RT_CATCH:
	gmsgid = G_("expected %<catch%>");
	break;
      case RT_THROW:
	gmsgid = G_("expected %<throw%>");
	break;
      case RT_AUTO:
        gmsgid = G_("expected %<auto%>");
        break;
      case RT_LABEL:
	gmsgid = G_("expected %<__label__%>");
	break;
      case RT_AT_TRY:
	gmsgid = G_("expected %<@try%>");
	break;
      case RT_AT_SYNCHRONIZED:
	gmsgid = G_("expected %<@synchronized%>");
	break;
      case RT_AT_THROW:
	gmsgid = G_("expected %<@throw%>");
	break;
      case RT_TRANSACTION_ATOMIC:
	gmsgid = G_("expected %<__transaction_atomic%>");
	break;
      case RT_TRANSACTION_RELAXED:
	gmsgid = G_("expected %<__transaction_relaxed%>");
	break;
      case RT_CO_YIELD:
	gmsgid = G_("expected %<co_yield%>");
	break;
      default:
	break;
    }

  if (!gmsgid && !keyword)
    {
      switch (token_desc)
        {
	  case RT_SEMICOLON:
	    gmsgid = G_("expected %<;%>");
	    break;
	  case RT_OPEN_PAREN:
	    gmsgid = G_("expected %<(%>");
	    break;
	  case RT_CLOSE_BRACE:
	    gmsgid = G_("expected %<}%>");
	    break;
	  case RT_OPEN_BRACE:
	    gmsgid = G_("expected %<{%>");
	    break;
	  case RT_CLOSE_SQUARE:
	    gmsgid = G_("expected %<]%>");
	    break;
	  case RT_OPEN_SQUARE:
	    gmsgid = G_("expected %<[%>");
	    break;
	  case RT_COMMA:
	    gmsgid = G_("expected %<,%>");
	    break;
	  case RT_SCOPE:
	    gmsgid = G_("expected %<::%>");
	    break;
	  case RT_LESS:
	    gmsgid = G_("expected %<<%>");
	    break;
	  case RT_GREATER:
	    gmsgid = G_("expected %<>%>");
	    break;
	  case RT_EQ:
	    gmsgid = G_("expected %<=%>");
	    break;
	  case RT_ELLIPSIS:
	    gmsgid = G_("expected %<...%>");
	    break;
	  case RT_MULT:
	    gmsgid = G_("expected %<*%>");
	    break;
	  case RT_COMPL:
	    gmsgid = G_("expected %<~%>");
	    break;
	  case RT_COLON:
	    gmsgid = G_("expected %<:%>");
	    break;
	  case RT_COLON_SCOPE:
	    gmsgid = G_("expected %<:%> or %<::%>");
	    break;
	  case RT_CLOSE_PAREN:
	    gmsgid = G_("expected %<)%>");
	    break;
	  case RT_COMMA_CLOSE_PAREN:
	    gmsgid = G_("expected %<,%> or %<)%>");
	    break;
	  case RT_PRAGMA_EOL:
	    gmsgid = G_("expected end of line");
	    break;
	  case RT_NAME:
	    gmsgid = G_("expected identifier");
	    break;
	  case RT_SELECT:
	    gmsgid = G_("expected selection-statement");
	    break;
	  case RT_ITERATION:
	    gmsgid = G_("expected iteration-statement");
	    break;
	  case RT_JUMP:
	    gmsgid = G_("expected jump-statement");
	    break;
	  case RT_CLASS_KEY:
	    gmsgid = G_("expected class-key");
	    break;
	  case RT_CLASS_TYPENAME_TEMPLATE:
	    gmsgid = G_("expected %<class%>, %<typename%>, or %<template%>");
	    break;
	  default:
	    gcc_unreachable ();
	}
    }

  if (gmsgid)
    cp_parser_error_1 (parser, gmsgid, token_desc, matching_location);
}


/* If the next token is of the indicated TYPE, consume it.  Otherwise,
   issue an error message indicating that TOKEN_DESC was expected.

   Returns the token consumed, if the token had the appropriate type.
   Otherwise, returns NULL.

   If MATCHING_LOCATION is not UNKNOWN_LOCATION, then highlight it
   within any error as the location of an "opening" token matching
   the close token TYPE (e.g. the location of the '(' when TOKEN_DESC is
   RT_CLOSE_PAREN).  */

static cp_token *
cp_parser_require (cp_parser* parser,
		   enum cpp_ttype type,
		   required_token token_desc,
		   location_t matching_location)
{
  if (cp_lexer_next_token_is (parser->lexer, type))
    return cp_lexer_consume_token (parser->lexer);
  else
    {
      /* Output the MESSAGE -- unless we're parsing tentatively.  */
      if (!cp_parser_simulate_error (parser))
	cp_parser_required_error (parser, token_desc, /*keyword=*/false,
				  matching_location);
      return NULL;
    }
}

/* Skip an entire parameter list from start to finish.  The next token must
   be the initial "<" of the parameter list.  Returns true on success and
   false otherwise.  */

static bool
cp_parser_skip_entire_template_parameter_list (cp_parser* parser)
{
  /* Consume the "<" because cp_parser_skip_to_end_of_template_parameter_list
     requires it.  */
  cp_lexer_consume_token (parser->lexer);
  return cp_parser_skip_to_end_of_template_parameter_list (parser);
}

/* Ensure we are at the end of a template parameter list.  If we are, return.
   If we are not, something has gone wrong, in which case issue an error and
   skip to end of the parameter list.  */

static void
cp_parser_require_end_of_template_parameter_list (cp_parser* parser)
{
  /* Are we ready, yet?  If not, issue error message.  */
  if (cp_parser_require (parser, CPP_GREATER, RT_GREATER))
    return;

  cp_parser_skip_to_end_of_template_parameter_list (parser);
}

/* You should only call this function from inside a template parameter list
   (i.e. the current token should at least be the initial "<" of the
   parameter list).  If you are skipping the entire list, it may be better to
   use cp_parser_skip_entire_template_parameter_list.

   Tokens are skipped until the final ">" is found, or if we see
   '{', '}', ';', or if we find an unbalanced ')' or ']'.

   Returns true if we successfully reached the end, and false if
   something unexpected happened (e.g. end of file).  */

static bool
cp_parser_skip_to_end_of_template_parameter_list (cp_parser* parser)
{
  /* Current level of '< ... >'.  */
  unsigned level = 0;
  /* Ignore '<' and '>' nested inside '( ... )' or '[ ... ]'.  */
  unsigned nesting_depth = 0;

  /* Skip tokens until the desired token is found.  */
  while (true)
    {
      /* Peek at the next token.  */
      switch (cp_lexer_peek_token (parser->lexer)->type)
	{
	case CPP_LESS:
	  if (!nesting_depth)
	    ++level;
	  break;

        case CPP_RSHIFT:
          if (cxx_dialect == cxx98)
            /* C++0x views the `>>' operator as two `>' tokens, but
               C++98 does not. */
            break;
          else if (!nesting_depth && level-- == 0)
	    {
              /* We've hit a `>>' where the first `>' closes the
                 template argument list, and the second `>' is
                 spurious.  Just consume the `>>' and stop; we've
                 already produced at least one error.  */
	      cp_lexer_consume_token (parser->lexer);
	      return false;
	    }
          /* Fall through for C++0x, so we handle the second `>' in
             the `>>'.  */
	  gcc_fallthrough ();

	case CPP_GREATER:
	  if (!nesting_depth && level-- == 0)
	    {
	      /* We've reached the token we want, consume it and stop.  */
	      cp_lexer_consume_token (parser->lexer);
	      return true;
	    }
	  break;

	case CPP_OPEN_PAREN:
	case CPP_OPEN_SQUARE:
	  ++nesting_depth;
	  break;

	case CPP_CLOSE_PAREN:
	case CPP_CLOSE_SQUARE:
	  if (nesting_depth-- == 0)
	    return false;
	  break;

	case CPP_EOF:
	case CPP_PRAGMA_EOL:
	case CPP_SEMICOLON:
	case CPP_OPEN_BRACE:
	case CPP_CLOSE_BRACE:
	  /* The '>' was probably forgotten, don't look further.  */
	  return false;

	default:
	  break;
	}

      /* Consume this token.  */
      cp_lexer_consume_token (parser->lexer);
    }
}

/* If the next token is the indicated keyword, consume it.  Otherwise,
   issue an error message indicating that TOKEN_DESC was expected.

   Returns the token consumed, if the token had the appropriate type.
   Otherwise, returns NULL.  */

static cp_token *
cp_parser_require_keyword (cp_parser* parser,
			   enum rid keyword,
			   required_token token_desc)
{
  cp_token *token = cp_parser_require (parser, CPP_KEYWORD, token_desc);

  if (token && token->keyword != keyword)
    {
      cp_parser_required_error (parser, token_desc, /*keyword=*/true,
                                UNKNOWN_LOCATION);
      return NULL;
    }

  return token;
}

/* Returns TRUE iff TOKEN is a token that can begin the body of a
   function-definition.  */

static bool
cp_parser_token_starts_function_definition_p (cp_token* token)
{
  return (/* An ordinary function-body begins with an `{'.  */
	  token->type == CPP_OPEN_BRACE
	  /* A ctor-initializer begins with a `:'.  */
	  || token->type == CPP_COLON
	  /* A function-try-block begins with `try'.  */
	  || token->keyword == RID_TRY
	  /* A function-transaction-block begins with `__transaction_atomic'
	     or `__transaction_relaxed'.  */
	  || token->keyword == RID_TRANSACTION_ATOMIC
	  || token->keyword == RID_TRANSACTION_RELAXED
	  /* The named return value extension begins with `return'.  */
	  || token->keyword == RID_RETURN);
}

/* Returns TRUE iff the next token is the ":" or "{" beginning a class
   definition.  */

static bool
cp_parser_next_token_starts_class_definition_p (cp_parser *parser)
{
  cp_token *token;

  token = cp_lexer_peek_token (parser->lexer);
  return (token->type == CPP_OPEN_BRACE
	  || (token->type == CPP_COLON
	      && !parser->colon_doesnt_start_class_def_p));
}

/* Returns TRUE iff the next token is the "," or ">" (or `>>', in
   C++0x) ending a template-argument.  */

static bool
cp_parser_next_token_ends_template_argument_p (cp_parser *parser)
{
  cp_token *token;

  token = cp_lexer_peek_token (parser->lexer);
  return (token->type == CPP_COMMA
          || token->type == CPP_GREATER
          || token->type == CPP_ELLIPSIS
	  || ((cxx_dialect != cxx98) && token->type == CPP_RSHIFT)
	  /* For better diagnostics, treat >>= like that too, that
	     shouldn't appear non-nested in template arguments.  */
	  || token->type == CPP_RSHIFT_EQ);
}

/* Returns TRUE iff the n-th token is a "<", or the n-th is a "[" and the
   (n+1)-th is a ":" (which is a possible digraph typo for "< ::").  */

static bool
cp_parser_nth_token_starts_template_argument_list_p (cp_parser * parser,
						     size_t n)
{
  cp_token *token;

  token = cp_lexer_peek_nth_token (parser->lexer, n);
  if (token->type == CPP_LESS)
    return true;
  /* Check for the sequence `<::' in the original code. It would be lexed as
     `[:', where `[' is a digraph, and there is no whitespace before
     `:'.  */
  if (token->type == CPP_OPEN_SQUARE && token->flags & DIGRAPH)
    {
      cp_token *token2;
      token2 = cp_lexer_peek_nth_token (parser->lexer, n+1);
      if (token2->type == CPP_COLON && !(token2->flags & PREV_WHITE))
	return true;
    }
  return false;
}

/* Returns the kind of tag indicated by TOKEN, if it is a class-key,
   or none_type otherwise.  */

static enum tag_types
cp_parser_token_is_class_key (cp_token* token)
{
  switch (token->keyword)
    {
    case RID_CLASS:
      return class_type;
    case RID_STRUCT:
      return record_type;
    case RID_UNION:
      return union_type;

    default:
      return none_type;
    }
}

/* Returns the kind of tag indicated by TOKEN, if it is a type-parameter-key,
   or none_type otherwise or if the token is null.  */

static enum tag_types
cp_parser_token_is_type_parameter_key (cp_token* token)
{
  if (!token)
    return none_type;

  switch (token->keyword)
    {
    case RID_CLASS:
      return class_type;
    case RID_TYPENAME:
      return typename_type;

    default:
      return none_type;
    }
}

/* Diagnose redundant enum-keys.  */

static void
cp_parser_maybe_warn_enum_key (cp_parser *parser, location_t key_loc,
			       tree type, rid scoped_key)
{
  if (!warn_redundant_tags)
    return;

  tree type_decl = TYPE_MAIN_DECL (type);
  tree name = DECL_NAME (type_decl);
  /* Look up the NAME to see if it unambiguously refers to the TYPE.  */
  push_deferring_access_checks (dk_no_check);
  tree decl = cp_parser_lookup_name_simple (parser, name, input_location);
  pop_deferring_access_checks ();

  /* The enum-key is redundant for uses of the TYPE that are not
     declarations and for which name lookup returns just the type
     itself.  */
  if (decl != type_decl)
    return;

  if (scoped_key != RID_CLASS
      && scoped_key != RID_STRUCT
      && current_lang_name != lang_name_cplusplus
      && current_namespace == global_namespace)
    {
      /* Avoid issuing the diagnostic for apparently redundant (unscoped)
	 enum tag in shared C/C++ code in files (such as headers) included
	 in the main source file.  */
      const line_map_ordinary *map = NULL;
      linemap_resolve_location (line_table, key_loc,
				LRK_MACRO_DEFINITION_LOCATION,
				&map);
      if (!MAIN_FILE_P (map))
	return;
    }

  gcc_rich_location richloc (key_loc);
  richloc.add_fixit_remove (key_loc);
  warning_at (&richloc, OPT_Wredundant_tags,
	      "redundant enum-key %<enum%s%> in reference to %q#T",
	      (scoped_key == RID_CLASS ? " class"
	       : scoped_key == RID_STRUCT ? " struct" : ""), type);
}

/* Describes the set of declarations of a struct, class, or class template
   or its specializations.  Used for -Wmismatched-tags.  */

class class_decl_loc_t
{
 public:

  class_decl_loc_t ()
    : locvec (), idxdef (), def_class_key ()
  {
    locvec.create (4);
  }

  /* Constructs an object for a single declaration of a class with
     CLASS_KEY at the current location in the current function (or
     at another scope).  KEY_REDUNDANT is true if the class-key may
     be omitted in the current context without an ambiguity with
     another symbol with the same name.
     DEF_P is true for a class declaration that is a definition.
     CURLOC is the associated location.  */
  class_decl_loc_t (tag_types class_key, bool key_redundant, bool def_p,
		    location_t curloc = input_location)
    : locvec (), idxdef (def_p ? 0 : UINT_MAX), def_class_key (class_key)
  {
    locvec.create (4);
    class_key_loc_t ckl (current_function_decl, curloc, class_key,
			 key_redundant);
    locvec.quick_push (ckl);
  }

  /* Copy, assign, and destroy the object.  Necessary because LOCVEC
     isn't safely copyable and assignable and doesn't release storage
     on its own.  */
  class_decl_loc_t (const class_decl_loc_t &rhs)
    : locvec (rhs.locvec.copy ()), idxdef (rhs.idxdef),
      def_class_key (rhs.def_class_key)
  { }

  class_decl_loc_t& operator= (const class_decl_loc_t &rhs)
  {
    if (this == &rhs)
      return *this;
    locvec.release ();
    locvec = rhs.locvec.copy ();
    idxdef = rhs.idxdef;
    def_class_key = rhs.def_class_key;
    return *this;
  }

  ~class_decl_loc_t ()
  {
    locvec.release ();
  }

  /* Issues -Wmismatched-tags for a single class.  */
  void diag_mismatched_tags (tree);

  /* Issues -Wmismatched-tags for all classes.  */
  static void diag_mismatched_tags ();

  /* Adds TYPE_DECL to the collection of class decls and diagnoses
     redundant tags (if -Wredundant-tags is enabled).  */
  static void add (cp_parser *, location_t, tag_types, tree, bool, bool);

  /* Either adds this decl to the collection of class decls
     or diagnoses it, whichever is appropriate.  */
  void add_or_diag_mismatched_tag (tree, tag_types, bool, bool);

private:

  tree function (unsigned i) const
  {
    return locvec[i].func;
  }

  location_t location (unsigned i) const
  {
    return locvec[i].loc;
  }

  bool key_redundant (unsigned i) const
  {
    return locvec[i].key_redundant;
  }

  tag_types class_key (unsigned i) const
  {
    return locvec[i].class_key;
  }

  /* True if a definition for the class has been seen.  */
  bool def_p () const
  {
    return idxdef < locvec.length ();
  }

  /* The location of a single mention of a class type with the given
     class-key.  */
  struct class_key_loc_t
  {
    class_key_loc_t (tree func, location_t loc, tag_types key, bool redundant)
      : func (func), loc (loc), class_key (key), key_redundant (redundant)
    { }

    /* The function the type is mentioned in.  */
    tree func;
    /* The exact location.  */
    location_t loc;
    /* The class-key used in the mention of the type.  */
    tag_types class_key;
    /* True when the class-key could be omitted at this location
       without an ambiguity with another symbol of the same name.  */
    bool key_redundant;
  };
  /* Avoid using auto_vec here since it's not safe to copy due to pr90904.  */
  vec <class_key_loc_t> locvec;
  /* LOCVEC index of the definition or UINT_MAX if none exists.  */
  unsigned idxdef;
  /* The class-key the class was last declared with or none_type when
     it has been declared with a mismatched key.  */
  tag_types def_class_key;

  /* A mapping between a TYPE_DECL for a class and the class_decl_loc_t
     description above.  */
  typedef hash_map<tree_decl_hash, class_decl_loc_t> class_to_loc_map_t;
  static class_to_loc_map_t class2loc;
};

class_decl_loc_t::class_to_loc_map_t class_decl_loc_t::class2loc;

/* Issue an error message if the CLASS_KEY does not match the TYPE.
   DEF_P is expected to be set for a definition of class TYPE.  DECL_P
   is set for a declaration of class TYPE and clear for a reference to
   it that is not a declaration of it.  */

static void
cp_parser_check_class_key (cp_parser *parser, location_t key_loc,
			   tag_types class_key, tree type, bool def_p,
			   bool decl_p)
{
  if (type == error_mark_node)
    return;

  bool seen_as_union = TREE_CODE (type) == UNION_TYPE;
  if (seen_as_union != (class_key == union_type))
    {
      if (permerror (input_location, "%qs tag used in naming %q#T",
		     class_key == union_type ? "union"
		     : class_key == record_type ? "struct" : "class",
		     type))
	inform (DECL_SOURCE_LOCATION (TYPE_NAME (type)),
		"%q#T was previously declared here", type);
      return;
    }

  if (!warn_mismatched_tags && !warn_redundant_tags)
    return;

  /* Only consider the true class-keys below and ignore typename_type,
     etc. that are not C++ class-keys.  */
  if (class_key != class_type
      && class_key != record_type
      && class_key != union_type)
    return;

  class_decl_loc_t::add (parser, key_loc, class_key, type, def_p, decl_p);
}

/* Returns the template or specialization of one to which the RECORD_TYPE
   TYPE corresponds.  */

static tree
specialization_of (tree type)
{
  tree ret = type;

  /* Determine the template or its partial specialization to which TYPE
     corresponds.  */
  if (tree spec = most_specialized_partial_spec (type, tf_none))
    if (spec != error_mark_node)
      ret = TREE_TYPE (TREE_VALUE (spec));

  if (ret == type)
    ret = CLASSTYPE_PRIMARY_TEMPLATE_TYPE (type);

  return TYPE_MAIN_DECL (ret);
}


/* Adds the class TYPE to the collection of class decls and diagnoses
   redundant tags (if -Wredundant-tags is enabled).
   DEF_P is expected to be set for a definition of class TYPE.  DECL_P
   is set for a (likely, based on syntactic context) declaration of class
   TYPE and clear for a reference to it that is not a declaration of it.  */

void
class_decl_loc_t::add (cp_parser *parser, location_t key_loc,
		       tag_types class_key, tree type, bool def_p, bool decl_p)
{
  tree type_decl = TYPE_MAIN_DECL (type);
  tree name = DECL_NAME (type_decl);
  /* Look up the NAME to see if it unambiguously refers to the TYPE
     and set KEY_REDUNDANT if so.  */
  push_deferring_access_checks (dk_no_check);
  tree decl = cp_parser_lookup_name_simple (parser, name, input_location);
  pop_deferring_access_checks ();

  /* The class-key is redundant for uses of the CLASS_TYPE that are
     neither definitions of it nor declarations, and for which name
     lookup returns just the type itself.  */
  bool key_redundant = (!def_p && !decl_p
			&& (decl == type_decl
			    || TREE_CODE (decl) == TEMPLATE_DECL
			    || (CLASS_TYPE_P (type)
				&& TYPE_BEING_DEFINED (type))));

  if (key_redundant
      && class_key != class_type
      && current_lang_name != lang_name_cplusplus
      && current_namespace == global_namespace)
    {
      /* Avoid issuing the diagnostic for apparently redundant struct
	 and union class-keys in shared C/C++ code in files (such as
	 headers) included in the main source file.  */
      const line_map_ordinary *map = NULL;
      linemap_resolve_location (line_table, key_loc,
				LRK_MACRO_DEFINITION_LOCATION,
				&map);
      if (!MAIN_FILE_P (map))
	key_redundant = false;
    }

  /* Set if a declaration of TYPE has previously been seen or if it must
     exist in a precompiled header.  */
  bool exist;
  class_decl_loc_t *rdl = &class2loc.get_or_insert (type_decl, &exist);
  if (!exist)
    {
      tree type = TREE_TYPE (type_decl);
      if (def_p || !COMPLETE_TYPE_P (type))
	{
	  /* TYPE_DECL is the first declaration or definition of the type
	     (outside precompiled headers -- see below).  Just create
	     a new entry for it and return unless it's a declaration
	     involving a template that may need to be diagnosed by
	     -Wredundant-tags.  */
	  *rdl = class_decl_loc_t (class_key, false, def_p);
	  if (TREE_CODE (decl) != TEMPLATE_DECL)
	    return;
	}
      else
	{
	  /* TYPE was previously defined in some unknown precompiled header.
	     Simply add a record of its definition at an unknown location and
	     proceed below to add a reference to it at the current location.
	     (Declarations in precompiled headers that are not definitions
	     are ignored.)  */
	  tag_types def_key
	    = CLASSTYPE_DECLARED_CLASS (type) ? class_type : record_type;
	  location_t def_loc = DECL_SOURCE_LOCATION (type_decl);
	  *rdl = class_decl_loc_t (def_key, false, true, def_loc);
	  exist = true;
	}
    }

  /* A prior declaration of TYPE_DECL has been seen.  */

  if (key_redundant)
    {
      gcc_rich_location richloc (key_loc);
      richloc.add_fixit_remove (key_loc);
      warning_at (&richloc, OPT_Wredundant_tags,
		  "redundant class-key %qs in reference to %q#T",
		  class_key == union_type ? "union"
		  : class_key == record_type ? "struct" : "class",
		  type);
    }

  if (!exist)
    /* Do nothing if this is the first declaration of the type.  */
    return;

  if (rdl->idxdef != UINT_MAX && rdl->def_class_key == class_key)
    /* Do nothing if the class-key in this declaration matches
       the definition.  */
    return;

  rdl->add_or_diag_mismatched_tag (type_decl, class_key, key_redundant,
				   def_p);
}

/* Either adds this DECL corresponding to the TYPE_DECL to the collection
   of class decls or diagnoses it, whichever is appropriate.  */

void
class_decl_loc_t::add_or_diag_mismatched_tag (tree type_decl,
					      tag_types class_key,
					      bool redundant,
					      bool def_p)
{
  /* Reset the CLASS_KEY associated with this type on mismatch.
     This is an optimization that lets the diagnostic code skip
     over classes that use the same class-key in all declarations.  */
  if (def_class_key != class_key)
    def_class_key = none_type;

  /* Set IDXDEF to the index of the vector corresponding to
     the definition.  */
  if (def_p)
    idxdef = locvec.length ();

  /* Append a record of this declaration to the vector.  */
  class_key_loc_t ckl (current_function_decl, input_location, class_key,
		       redundant);
  locvec.safe_push (ckl);

  if (idxdef == UINT_MAX)
    return;

  /* As a space optimization diagnose declarations of a class
     whose definition has been seen and purge the LOCVEC of
     all entries except the definition.  */
  diag_mismatched_tags (type_decl);
  if (idxdef)
    {
      class_decl_loc_t::class_key_loc_t ent = locvec[idxdef];
      locvec.release ();
      locvec.reserve (2);
      locvec.safe_push (ent);
      idxdef = 0;
    }
  else
    /* Pop the entry pushed above for this declaration.  */
    locvec.pop ();
}

/* Issues -Wmismatched-tags for a single class.  */

void
class_decl_loc_t::diag_mismatched_tags (tree type_decl)
{
  if (!warn_mismatched_tags)
    return;

  /* Number of uses of the class.  */
  const unsigned ndecls = locvec.length ();

  /* The class (or template) declaration guiding the decisions about
     the diagnostic.  For ordinary classes it's the same as THIS.  For
     uses of instantiations of templates other than their declarations
     it points to the record for the declaration of the corresponding
     primary template or partial specialization.  */
  class_decl_loc_t *cdlguide = this;

  tree type = TREE_TYPE (type_decl);
  if (CLASS_TYPE_P (type) && CLASSTYPE_IMPLICIT_INSTANTIATION (type))
    {
      /* For implicit instantiations of a primary template look up
	 the primary or partial specialization and use it as
	 the expected class-key rather than using the class-key of
	 the first reference to the instantiation.  The primary must
	 be (and inevitably is) at index zero.  */
      tree spec = specialization_of (type);
      cdlguide = class2loc.get (spec);
      gcc_assert (cdlguide != NULL);
    }
  else
    {
      /* Skip declarations that consistently use the same class-key.  */
      if (def_class_key != none_type)
	return;
    }

  /* Set if a definition for the class has been seen.  */
  const bool def_p = cdlguide->def_p ();

  /* The index of the declaration whose class-key this declaration
     is expected to match.  It's either the class-key of the class
     definition if one exists or the first declaration otherwise.  */
  const unsigned idxguide = def_p ? cdlguide->idxdef : 0;

  /* The class-key the class is expected to be declared with: it's
     either the key used in its definition or the first declaration
     if no definition has been provided.
     For implicit instantiations of a primary template it's
     the class-key used to declare the primary with.  The primary
     must be at index zero.  */
  const tag_types xpect_key = cdlguide->class_key (idxguide);

  unsigned idx = 0;
  /* Advance IDX to the first declaration that either is not
     a definition or that doesn't match the first declaration
     if no definition is provided.  */
  while (class_key (idx) == xpect_key)
    if (++idx == ndecls)
      return;

  /* Save the current function before changing it below.  */
  tree save_func = current_function_decl;
  /* Set the function declaration to print in diagnostic context.  */
  current_function_decl = function (idx);

  const char *xmatchkstr = xpect_key == record_type ? "class" : "struct";
  const char *xpectkstr = xpect_key == record_type ? "struct" : "class";

  location_t loc = location (idx);
  bool key_redundant_p = key_redundant (idx);
  auto_diagnostic_group d;
  /* Issue a warning for the first mismatched declaration.
     Avoid using "%#qT" since the class-key for the same type will
     be the same regardless of which one was used in the declaraion.  */
  if (warning_at (loc, OPT_Wmismatched_tags,
		  "%qT declared with a mismatched class-key %qs",
		  type_decl, xmatchkstr))
    {
      /* Suggest how to avoid the warning for each instance since
	 the guidance may be different depending on context.  */
      inform (loc,
	      (key_redundant_p
	       ? G_("remove the class-key or replace it with %qs")
	       : G_("replace the class-key with %qs")),
	      xpectkstr);

      /* Also point to the first declaration or definition that guided
	 the decision to issue the warning above.  */
      inform (cdlguide->location (idxguide),
	      (def_p
	       ? G_("%qT defined as %qs here")
	       : G_("%qT first declared as %qs here")),
	      type_decl, xpectkstr);
    }

  /* Issue warnings for the remaining inconsistent declarations.  */
  for (unsigned i = idx + 1; i != ndecls; ++i)
    {
      tag_types clskey = class_key (i);
      /* Skip over the declarations that match either the definition
	 if one was provided or the first declaration.  */
      if (clskey == xpect_key)
	continue;

      loc = location (i);
      key_redundant_p = key_redundant (i);
      /* Set the function declaration to print in diagnostic context.  */
      current_function_decl = function (i);
      if (warning_at (loc, OPT_Wmismatched_tags,
		      "%qT declared with a mismatched class-key %qs",
		      type_decl, xmatchkstr))
	/* Suggest how to avoid the warning for each instance since
	   the guidance may be different depending on context.  */
	inform (loc,
		(key_redundant_p
		 ? G_("remove the class-key or replace it with %qs")
		 : G_("replace the class-key with %qs")),
		xpectkstr);
    }

  /* Restore the current function in case it was replaced above.  */
  current_function_decl = save_func;
}

/* Issues -Wmismatched-tags for all classes.  Called at the end
   of processing a translation unit, after declarations of all class
   types and their uses have been recorded.  */

void
class_decl_loc_t::diag_mismatched_tags ()
{
  /* CLASS2LOC should be empty if both -Wmismatched-tags and
     -Wredundant-tags are disabled.  */
  gcc_assert (warn_mismatched_tags
	      || warn_redundant_tags
	      || class2loc.is_empty ());

  /* Save the current function before changing on return.  It should
     be null at this point.  */
  temp_override<tree> cleanup (current_function_decl);

  if (warn_mismatched_tags)
    {
      /* Iterate over the collected class/struct/template declarations.  */
      typedef class_to_loc_map_t::iterator iter_t;
      for (iter_t it = class2loc.begin (); it != class2loc.end (); ++it)
	{
	  tree type_decl = (*it).first;
	  class_decl_loc_t &recloc = (*it).second;
	  recloc.diag_mismatched_tags (type_decl);
	}
    }

  class2loc.empty ();
}

/* Issue an error message if DECL is redeclared with different
   access than its original declaration [class.access.spec/3].
   This applies to nested classes, nested class templates and
   enumerations [class.mem/1].  */

static void
cp_parser_check_access_in_redeclaration (tree decl, location_t location)
{
  if (!decl
      || (!CLASS_TYPE_P (TREE_TYPE (decl))
	  && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE))
    return;

  if ((TREE_PRIVATE (decl)
       != (current_access_specifier == access_private_node))
      || (TREE_PROTECTED (decl)
	  != (current_access_specifier == access_protected_node)))
    error_at (location, "%qD redeclared with different access", decl);
}

/* Look for the `template' keyword, as a syntactic disambiguator.
   Return TRUE iff it is present, in which case it will be
   consumed.  */

static bool
cp_parser_optional_template_keyword (cp_parser *parser)
{
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TEMPLATE))
    {
      /* In C++98 the `template' keyword can only be used within templates;
	 outside templates the parser can always figure out what is a
	 template and what is not.  In C++11,  per the resolution of DR 468,
	 `template' is allowed in cases where it is not strictly necessary.  */
      if (!processing_template_decl
	  && pedantic && cxx_dialect == cxx98)
	{
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  pedwarn (token->location, OPT_Wpedantic,
		   "in C++98 %<template%> (as a disambiguator) is only "
		   "allowed within templates");
	  /* If this part of the token stream is rescanned, the same
	     error message would be generated.  So, we purge the token
	     from the stream.  */
	  cp_lexer_purge_token (parser->lexer);
	  return false;
	}
      else
	{
	  /* Consume the `template' keyword.  */
	  cp_lexer_consume_token (parser->lexer);
	  return true;
	}
    }
  return false;
}

/* The next token is a CPP_NESTED_NAME_SPECIFIER.  Consume the token,
   set PARSER->SCOPE, and perform other related actions.  */

static void
cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
{
  struct tree_check *check_value;

  /* Get the stored value.  */
  check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
  /* Set the scope from the stored value.  */
  parser->scope = saved_checks_value (check_value);
  parser->qualifying_scope = check_value->qualifying_scope;
  parser->object_scope = parser->context->object_type;
  parser->context->object_type = NULL_TREE;
}

/* Consume tokens up through a non-nested END token.  Returns TRUE if we
   encounter the end of a block before what we were looking for.  */

static bool
cp_parser_cache_group (cp_parser *parser,
		       enum cpp_ttype end,
		       unsigned depth)
{
  while (true)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      /* Abort a parenthesized expression if we encounter a semicolon.  */
      if ((end == CPP_CLOSE_PAREN || depth == 0)
	  && token->type == CPP_SEMICOLON)
	return true;
      /* If we've reached the end of the file, stop.  */
      if (token->type == CPP_EOF
	  || (end != CPP_PRAGMA_EOL
	      && token->type == CPP_PRAGMA_EOL))
	return true;
      if (token->type == CPP_CLOSE_BRACE && depth == 0)
	/* We've hit the end of an enclosing block, so there's been some
	   kind of syntax error.  */
	return true;

      /* Consume the token.  */
      cp_lexer_consume_token (parser->lexer);
      /* See if it starts a new group.  */
      if (token->type == CPP_OPEN_BRACE)
	{
	  cp_parser_cache_group (parser, CPP_CLOSE_BRACE, depth + 1);
	  /* In theory this should probably check end == '}', but
	     cp_parser_save_member_function_body needs it to exit
	     after either '}' or ')' when called with ')'.  */
	  if (depth == 0)
	    return false;
	}
      else if (token->type == CPP_OPEN_PAREN)
	{
	  cp_parser_cache_group (parser, CPP_CLOSE_PAREN, depth + 1);
	  if (depth == 0 && end == CPP_CLOSE_PAREN)
	    return false;
	}
      else if (token->type == CPP_PRAGMA)
	cp_parser_cache_group (parser, CPP_PRAGMA_EOL, depth + 1);
      else if (token->type == end)
	return false;
    }
}

/* Like above, for caching a default argument or NSDMI.  Both of these are
   terminated by a non-nested comma, but it can be unclear whether or not a
   comma is nested in a template argument list unless we do more parsing.
   In order to handle this ambiguity, when we encounter a ',' after a '<'
   we try to parse what follows as a parameter-declaration-list (in the
   case of a default argument) or a member-declarator (in the case of an
   NSDMI).  If that succeeds, then we stop caching.  */

static tree
cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
{
  unsigned depth = 0;
  int maybe_template_id = 0;
  cp_token *first_token;
  cp_token *token;
  tree default_argument;

  /* Add tokens until we have processed the entire default
     argument.  We add the range [first_token, token).  */
  first_token = cp_lexer_peek_token (parser->lexer);
  if (first_token->type == CPP_OPEN_BRACE)
    {
      /* For list-initialization, this is straightforward.  */
      cp_parser_cache_group (parser, CPP_CLOSE_BRACE, /*depth=*/0);
      token = cp_lexer_peek_token (parser->lexer);
    }
  else while (true)
    {
      bool done = false;

      /* Peek at the next token.  */
      token = cp_lexer_peek_token (parser->lexer);
      /* What we do depends on what token we have.  */
      switch (token->type)
	{
	  /* In valid code, a default argument must be
	     immediately followed by a `,' `)', or `...'.  */
	case CPP_COMMA:
	  if (depth == 0 && maybe_template_id)
	    {
	      /* If we've seen a '<', we might be in a
		 template-argument-list.  Until Core issue 325 is
		 resolved, we don't know how this situation ought
		 to be handled, so try to DTRT.  We check whether
		 what comes after the comma is a valid parameter
		 declaration list.  If it is, then the comma ends
		 the default argument; otherwise the default
		 argument continues.  */
	      bool error = false;
	      cp_token *peek;

	      /* Set ITALP so cp_parser_parameter_declaration_list
		 doesn't decide to commit to this parse.  */
	      bool saved_italp = parser->in_template_argument_list_p;
	      parser->in_template_argument_list_p = true;

	      cp_parser_parse_tentatively (parser);

	      if (nsdmi)
		{
		  /* Parse declarators until we reach a non-comma or
		     somthing that cannot be an initializer.
		     Just checking whether we're looking at a single
		     declarator is insufficient.  Consider:
		       int var = tuple<T,U>::x;
		     The template parameter 'U' looks exactly like a
		     declarator.  */
		  do
		    {
		      int ctor_dtor_or_conv_p;
		      cp_lexer_consume_token (parser->lexer);
		      cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
					    CP_PARSER_FLAGS_NONE,
					    &ctor_dtor_or_conv_p,
					    /*parenthesized_p=*/NULL,
					    /*member_p=*/true,
					    /*friend_p=*/false,
					    /*static_p=*/false);
		      peek = cp_lexer_peek_token (parser->lexer);
		      if (cp_parser_error_occurred (parser))
			break;
		    }
		  while (peek->type == CPP_COMMA);
		  /* If we met an '=' or ';' then the original comma
		     was the end of the NSDMI.  Otherwise assume
		     we're still in the NSDMI.  */
		  error = (peek->type != CPP_EQ
			   && peek->type != CPP_SEMICOLON);
		}
	      else
		{
		  cp_lexer_consume_token (parser->lexer);
		  begin_scope (sk_function_parms, NULL_TREE);
		  tree t = cp_parser_parameter_declaration_list
			    (parser, CP_PARSER_FLAGS_NONE,
			     /*pending_decls*/nullptr);
		  if (t == error_mark_node)
		    error = true;
		  pop_bindings_and_leave_scope ();
		}
	      if (!cp_parser_error_occurred (parser) && !error)
		done = true;
	      cp_parser_abort_tentative_parse (parser);

	      parser->in_template_argument_list_p = saved_italp;
	      break;
	    }
	  /* FALLTHRU */
	case CPP_CLOSE_PAREN:
	case CPP_ELLIPSIS:
	  /* If we run into a non-nested `;', `}', or `]',
	     then the code is invalid -- but the default
	     argument is certainly over.  */
	case CPP_SEMICOLON:
	case CPP_CLOSE_BRACE:
	case CPP_CLOSE_SQUARE:
	  if (depth == 0
	      /* Handle correctly int n = sizeof ... ( p );  */
	      && token->type != CPP_ELLIPSIS)
	    done = true;
	  /* Update DEPTH, if necessary.  */
	  else if (token->type == CPP_CLOSE_PAREN
		   || token->type == CPP_CLOSE_BRACE
		   || token->type == CPP_CLOSE_SQUARE)
	    --depth;
	  break;

	case CPP_OPEN_PAREN:
	case CPP_OPEN_SQUARE:
	case CPP_OPEN_BRACE:
	  ++depth;
	  break;

	case CPP_LESS:
	  if (depth == 0)
	    /* This might be the comparison operator, or it might
	       start a template argument list.  */
	    ++maybe_template_id;
	  break;

	case CPP_RSHIFT:
	  if (cxx_dialect == cxx98)
	    break;
	  /* Fall through for C++0x, which treats the `>>'
	     operator like two `>' tokens in certain
	     cases.  */
	  gcc_fallthrough ();

	case CPP_GREATER:
	  if (depth == 0)
	    {
	      /* This might be an operator, or it might close a
		 template argument list.  But if a previous '<'
		 started a template argument list, this will have
		 closed it, so we can't be in one anymore.  */
	      maybe_template_id -= 1 + (token->type == CPP_RSHIFT);
	      if (maybe_template_id < 0)
		maybe_template_id = 0;
	    }
	  break;

	  /* If we run out of tokens, issue an error message.  */
	case CPP_EOF:
	case CPP_PRAGMA_EOL:
	  error_at (token->location, "file ends in default argument");
	  return error_mark_node;

	case CPP_NAME:
	case CPP_SCOPE:
	  /* In these cases, we should look for template-ids.
	     For example, if the default argument is
	     `X<int, double>()', we need to do name lookup to
	     figure out whether or not `X' is a template; if
	     so, the `,' does not end the default argument.

	     That is not yet done.  */
	  break;

	default:
	  break;
	}

      /* If we've reached the end, stop.  */
      if (done)
	break;

      /* Add the token to the token block.  */
      token = cp_lexer_consume_token (parser->lexer);
    }

  /* Create a DEFERRED_PARSE to represent the unparsed default
     argument.  */
  default_argument = make_node (DEFERRED_PARSE);
  DEFPARSE_TOKENS (default_argument)
    = cp_token_cache_new (first_token, token);
  DEFPARSE_INSTANTIATIONS (default_argument) = NULL;

  return default_argument;
}

/* A location to use for diagnostics about an unparsed DEFERRED_PARSE.  */

location_t
defparse_location (tree default_argument)
{
  cp_token_cache *tokens = DEFPARSE_TOKENS (default_argument);
  location_t start = tokens->first->location;
  location_t end = tokens->last->location;
  return make_location (start, start, end);
}

/* Begin parsing tentatively.  We always save tokens while parsing
   tentatively so that if the tentative parsing fails we can restore the
   tokens.  */

static void
cp_parser_parse_tentatively (cp_parser* parser)
{
  /* Enter a new parsing context.  */
  parser->context = cp_parser_context_new (parser->context);
  /* Begin saving tokens.  */
  cp_lexer_save_tokens (parser->lexer);
  /* In order to avoid repetitive access control error messages,
     access checks are queued up until we are no longer parsing
     tentatively.  */
  push_deferring_access_checks (dk_deferred);
}

/* Commit to the currently active tentative parse.  */

static void
cp_parser_commit_to_tentative_parse (cp_parser* parser)
{
  cp_parser_context *context;
  cp_lexer *lexer;

  /* Mark all of the levels as committed.  */
  lexer = parser->lexer;
  for (context = parser->context; context->next; context = context->next)
    {
      if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
	break;
      context->status = CP_PARSER_STATUS_KIND_COMMITTED;
      while (!cp_lexer_saving_tokens (lexer))
	lexer = lexer->next;
      cp_lexer_commit_tokens (lexer);
    }
}

/* Commit to the topmost currently active tentative parse.

   Note that this function shouldn't be called when there are
   irreversible side-effects while in a tentative state.  For
   example, we shouldn't create a permanent entry in the symbol
   table, or issue an error message that might not apply if the
   tentative parse is aborted.  */

static void
cp_parser_commit_to_topmost_tentative_parse (cp_parser* parser)
{
  cp_parser_context *context = parser->context;
  cp_lexer *lexer = parser->lexer;

  if (context)
    {
      if (context->status == CP_PARSER_STATUS_KIND_COMMITTED)
	return;
      context->status = CP_PARSER_STATUS_KIND_COMMITTED;

      while (!cp_lexer_saving_tokens (lexer))
	lexer = lexer->next;
      cp_lexer_commit_tokens (lexer);
    }
}

/* Abort the currently active tentative parse.  All consumed tokens
   will be rolled back, and no diagnostics will be issued.  */

static void
cp_parser_abort_tentative_parse (cp_parser* parser)
{
  gcc_assert (parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED
	      || errorcount > 0);
  cp_parser_simulate_error (parser);
  /* Now, pretend that we want to see if the construct was
     successfully parsed.  */
  cp_parser_parse_definitely (parser);
}

/* Stop parsing tentatively.  If a parse error has occurred, restore the
   token stream.  Otherwise, commit to the tokens we have consumed.
   Returns true if no error occurred; false otherwise.  */

static bool
cp_parser_parse_definitely (cp_parser* parser)
{
  bool error_occurred;
  cp_parser_context *context;

  /* Remember whether or not an error occurred, since we are about to
     destroy that information.  */
  error_occurred = cp_parser_error_occurred (parser);
  /* Remove the topmost context from the stack.  */
  context = parser->context;
  parser->context = context->next;
  /* If no parse errors occurred, commit to the tentative parse.  */
  if (!error_occurred)
    {
      /* Commit to the tokens read tentatively, unless that was
	 already done.  */
      if (context->status != CP_PARSER_STATUS_KIND_COMMITTED)
	cp_lexer_commit_tokens (parser->lexer);

      pop_to_parent_deferring_access_checks ();
    }
  /* Otherwise, if errors occurred, roll back our state so that things
     are just as they were before we began the tentative parse.  */
  else
    {
      cp_lexer_rollback_tokens (parser->lexer);
      pop_deferring_access_checks ();
    }
  /* Add the context to the front of the free list.  */
  context->next = cp_parser_context_free_list;
  cp_parser_context_free_list = context;

  return !error_occurred;
}

/* Returns true if we are parsing tentatively and are not committed to
   this tentative parse.  */

static bool
cp_parser_uncommitted_to_tentative_parse_p (cp_parser* parser)
{
  return (cp_parser_parsing_tentatively (parser)
	  && parser->context->status != CP_PARSER_STATUS_KIND_COMMITTED);
}

/* Returns nonzero iff an error has occurred during the most recent
   tentative parse.  */

static bool
cp_parser_error_occurred (cp_parser* parser)
{
  return (cp_parser_parsing_tentatively (parser)
	  && parser->context->status == CP_PARSER_STATUS_KIND_ERROR);
}

/* Returns nonzero if GNU extensions are allowed.  */

static bool
cp_parser_allow_gnu_extensions_p (cp_parser* parser)
{
  return parser->allow_gnu_extensions_p;
}

/* Objective-C++ Productions */


/* Parse an Objective-C expression, which feeds into a primary-expression
   above.

   objc-expression:
     objc-message-expression
     objc-string-literal
     objc-encode-expression
     objc-protocol-expression
     objc-selector-expression

  Returns a tree representation of the expression.  */

static cp_expr
cp_parser_objc_expression (cp_parser* parser)
{
  /* Try to figure out what kind of declaration is present.  */
  cp_token *kwd = cp_lexer_peek_token (parser->lexer);

  switch (kwd->type)
    {
    case CPP_OPEN_SQUARE:
      return cp_parser_objc_message_expression (parser);

    case CPP_OBJC_STRING:
      kwd = cp_lexer_consume_token (parser->lexer);
      return objc_build_string_object (kwd->u.value);

    case CPP_KEYWORD:
      switch (kwd->keyword)
	{
	case RID_AT_ENCODE:
	  return cp_parser_objc_encode_expression (parser);

	case RID_AT_PROTOCOL:
	  return cp_parser_objc_protocol_expression (parser);

	case RID_AT_SELECTOR:
	  return cp_parser_objc_selector_expression (parser);

	default:
	  break;
	}
      /* FALLTHRU */
    default:
      error_at (kwd->location,
		"misplaced %<@%D%> Objective-C++ construct",
		kwd->u.value);
      cp_parser_skip_to_end_of_block_or_statement (parser);
    }

  return error_mark_node;
}

/* Parse an Objective-C message expression.

   objc-message-expression:
     [ objc-message-receiver objc-message-args ]

   Returns a representation of an Objective-C message.  */

static tree
cp_parser_objc_message_expression (cp_parser* parser)
{
  tree receiver, messageargs;

  parser->objective_c_message_context_p = true;
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;
  cp_lexer_consume_token (parser->lexer);  /* Eat '['.  */
  receiver = cp_parser_objc_message_receiver (parser);
  messageargs = cp_parser_objc_message_args (parser);
  location_t end_loc = cp_lexer_peek_token (parser->lexer)->location;
  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);

  tree result = objc_build_message_expr (receiver, messageargs);

  /* Construct a location e.g.
       [self func1:5]
       ^~~~~~~~~~~~~~
     ranging from the '[' to the ']', with the caret at the start.  */
  location_t combined_loc = make_location (start_loc, start_loc, end_loc);
  protected_set_expr_location (result, combined_loc);

  parser->objective_c_message_context_p = false;
  return result;
}

/* Parse an objc-message-receiver.

   objc-message-receiver:
     expression
     simple-type-specifier

  Returns a representation of the type or expression.  */

static tree
cp_parser_objc_message_receiver (cp_parser* parser)
{
  tree rcv;

  /* An Objective-C message receiver may be either (1) a type
     or (2) an expression.  */
  cp_parser_parse_tentatively (parser);
  rcv = cp_parser_expression (parser);

  /* If that worked out, fine.  */
  if (cp_parser_parse_definitely (parser))
    return rcv;

  cp_parser_parse_tentatively (parser);
  rcv = cp_parser_simple_type_specifier (parser,
					 /*decl_specs=*/NULL,
					 CP_PARSER_FLAGS_NONE);

  if (cp_parser_parse_definitely (parser))
    return objc_get_class_reference (rcv);

  cp_parser_error (parser, "objective-c++ message receiver expected");
  return error_mark_node;
}

/* Parse the arguments and selectors comprising an Objective-C message.

   objc-message-args:
     objc-selector
     objc-selector-args
     objc-selector-args , objc-comma-args

   objc-selector-args:
     objc-selector [opt] : assignment-expression
     objc-selector-args objc-selector [opt] : assignment-expression

   objc-comma-args:
     assignment-expression
     objc-comma-args , assignment-expression

   Returns a TREE_LIST, with TREE_PURPOSE containing a list of
   selector arguments and TREE_VALUE containing a list of comma
   arguments.  */

static tree
cp_parser_objc_message_args (cp_parser* parser)
{
  tree sel_args = NULL_TREE, addl_args = NULL_TREE;
  bool maybe_unary_selector_p = true;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
    {
      tree selector = NULL_TREE, arg;

      if (token->type != CPP_COLON)
	selector = cp_parser_objc_selector (parser);

      /* Detect if we have a unary selector.  */
      if (maybe_unary_selector_p
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
	return build_tree_list (selector, NULL_TREE);

      maybe_unary_selector_p = false;
      cp_parser_require (parser, CPP_COLON, RT_COLON);
      arg = cp_parser_assignment_expression (parser);

      sel_args
	= chainon (sel_args,
		   build_tree_list (selector, arg));

      token = cp_lexer_peek_token (parser->lexer);
    }

  /* Handle non-selector arguments, if any. */
  while (token->type == CPP_COMMA)
    {
      tree arg;

      cp_lexer_consume_token (parser->lexer);
      arg = cp_parser_assignment_expression (parser);

      addl_args
	= chainon (addl_args,
		   build_tree_list (NULL_TREE, arg));

      token = cp_lexer_peek_token (parser->lexer);
    }

  if (sel_args == NULL_TREE && addl_args == NULL_TREE)
    {
      cp_parser_error (parser, "objective-c++ message argument(s) are expected");
      return build_tree_list (error_mark_node, error_mark_node);
    }

  return build_tree_list (sel_args, addl_args);
}

/* Parse an Objective-C encode expression.

   objc-encode-expression:
     @encode objc-typename

   Returns an encoded representation of the type argument.  */

static cp_expr
cp_parser_objc_encode_expression (cp_parser* parser)
{
  tree type;
  cp_token *token;
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@encode'.  */
  matching_parens parens;
  parens.require_open (parser);
  token = cp_lexer_peek_token (parser->lexer);
  type = complete_type (cp_parser_type_id (parser));
  parens.require_close (parser);

  if (!type)
    {
      error_at (token->location,
		"%<@encode%> must specify a type as an argument");
      return error_mark_node;
    }

  /* This happens if we find @encode(T) (where T is a template
     typename or something dependent on a template typename) when
     parsing a template.  In that case, we can't compile it
     immediately, but we rather create an AT_ENCODE_EXPR which will
     need to be instantiated when the template is used.
  */
  if (dependent_type_p (type))
    {
      tree value = build_min (AT_ENCODE_EXPR, size_type_node, type);
      TREE_READONLY (value) = 1;
      return value;
    }


  /* Build a location of the form:
       @encode(int)
       ^~~~~~~~~~~~
     with caret==start at the @ token, finishing at the close paren.  */
  location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);

  return cp_expr (objc_build_encode_expr (type), combined_loc);
}

/* Parse an Objective-C @defs expression.  */

static tree
cp_parser_objc_defs_expression (cp_parser *parser)
{
  tree name;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@defs'.  */
  matching_parens parens;
  parens.require_open (parser);
  name = cp_parser_identifier (parser);
  parens.require_close (parser);

  return objc_get_class_ivars (name);
}

/* Parse an Objective-C protocol expression.

  objc-protocol-expression:
    @protocol ( identifier )

  Returns a representation of the protocol expression.  */

static tree
cp_parser_objc_protocol_expression (cp_parser* parser)
{
  tree proto;
  location_t start_loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@protocol'.  */
  matching_parens parens;
  parens.require_open (parser);
  proto = cp_parser_identifier (parser);
  parens.require_close (parser);

  /* Build a location of the form:
       @protocol(prot)
       ^~~~~~~~~~~~~~~
     with caret==start at the @ token, finishing at the close paren.  */
  location_t combined_loc = make_location (start_loc, start_loc, parser->lexer);
  tree result = objc_build_protocol_expr (proto);
  protected_set_expr_location (result, combined_loc);
  return result;
}

/* Parse an Objective-C selector expression.

   objc-selector-expression:
     @selector ( objc-method-signature )

   objc-method-signature:
     objc-selector
     objc-selector-seq

   objc-selector-seq:
     objc-selector :
     objc-selector-seq objc-selector :

  Returns a representation of the method selector.  */

static tree
cp_parser_objc_selector_expression (cp_parser* parser)
{
  tree sel_seq = NULL_TREE;
  bool maybe_unary_selector_p = true;
  cp_token *token;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@selector'.  */
  matching_parens parens;
  parens.require_open (parser);
  token = cp_lexer_peek_token (parser->lexer);

  while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON
	 || token->type == CPP_SCOPE)
    {
      tree selector = NULL_TREE;

      if (token->type != CPP_COLON
	  || token->type == CPP_SCOPE)
	selector = cp_parser_objc_selector (parser);

      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
	{
	  /* Detect if we have a unary selector.  */
	  if (maybe_unary_selector_p)
	    {
	      sel_seq = selector;
	      goto finish_selector;
	    }
	  else
	    {
	      cp_parser_error (parser, "expected %<:%>");
	    }
	}
      maybe_unary_selector_p = false;
      token = cp_lexer_consume_token (parser->lexer);

      if (token->type == CPP_SCOPE)
	{
	  sel_seq
	    = chainon (sel_seq,
		       build_tree_list (selector, NULL_TREE));
	  sel_seq
	    = chainon (sel_seq,
		       build_tree_list (NULL_TREE, NULL_TREE));
	}
      else
	sel_seq
	  = chainon (sel_seq,
		     build_tree_list (selector, NULL_TREE));

      token = cp_lexer_peek_token (parser->lexer);
    }

 finish_selector:
  parens.require_close (parser);


  /* Build a location of the form:
       @selector(func)
       ^~~~~~~~~~~~~~~
     with caret==start at the @ token, finishing at the close paren.  */
  location_t combined_loc = make_location (loc, loc, parser->lexer);
  tree result = objc_build_selector_expr (combined_loc, sel_seq);
  /* TODO: objc_build_selector_expr doesn't always honor the location.  */
  protected_set_expr_location (result, combined_loc);
  return result;
}

/* Parse a list of identifiers.

   objc-identifier-list:
     identifier
     objc-identifier-list , identifier

   Returns a TREE_LIST of identifier nodes.  */

static tree
cp_parser_objc_identifier_list (cp_parser* parser)
{
  tree identifier;
  tree list;
  cp_token *sep;

  identifier = cp_parser_identifier (parser);
  if (identifier == error_mark_node)
    return error_mark_node;

  list = build_tree_list (NULL_TREE, identifier);
  sep = cp_lexer_peek_token (parser->lexer);

  while (sep->type == CPP_COMMA)
    {
      cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
      identifier = cp_parser_identifier (parser);
      if (identifier == error_mark_node)
	return list;

      list = chainon (list, build_tree_list (NULL_TREE,
					     identifier));
      sep = cp_lexer_peek_token (parser->lexer);
    }

  return list;
}

/* Parse an Objective-C alias declaration.

   objc-alias-declaration:
     @compatibility_alias identifier identifier ;

   This function registers the alias mapping with the Objective-C front end.
   It returns nothing.  */

static void
cp_parser_objc_alias_declaration (cp_parser* parser)
{
  tree alias, orig;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@compatibility_alias'.  */
  alias = cp_parser_identifier (parser);
  orig = cp_parser_identifier (parser);
  objc_declare_alias (alias, orig);
  cp_parser_consume_semicolon_at_end_of_statement (parser);
}

/* Parse an Objective-C class forward-declaration.

   objc-class-declaration:
     @class objc-identifier-list ;

   The function registers the forward declarations with the Objective-C
   front end.  It returns nothing.  */

static void
cp_parser_objc_class_declaration (cp_parser* parser)
{
  cp_lexer_consume_token (parser->lexer);  /* Eat '@class'.  */
  while (true)
    {
      tree id;

      id = cp_parser_identifier (parser);
      if (id == error_mark_node)
	break;

      objc_declare_class (id);

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	break;
    }
  cp_parser_consume_semicolon_at_end_of_statement (parser);
}

/* Parse a list of Objective-C protocol references.

   objc-protocol-refs-opt:
     objc-protocol-refs [opt]

   objc-protocol-refs:
     < objc-identifier-list >

   Returns a TREE_LIST of identifiers, if any.  */

static tree
cp_parser_objc_protocol_refs_opt (cp_parser* parser)
{
  tree protorefs = NULL_TREE;

  if(cp_lexer_next_token_is (parser->lexer, CPP_LESS))
    {
      cp_lexer_consume_token (parser->lexer);  /* Eat '<'.  */
      protorefs = cp_parser_objc_identifier_list (parser);
      cp_parser_require (parser, CPP_GREATER, RT_GREATER);
    }

  return protorefs;
}

/* Parse a Objective-C visibility specification.  */

static void
cp_parser_objc_visibility_spec (cp_parser* parser)
{
  cp_token *vis = cp_lexer_peek_token (parser->lexer);

  switch (vis->keyword)
    {
    case RID_AT_PRIVATE:
      objc_set_visibility (OBJC_IVAR_VIS_PRIVATE);
      break;
    case RID_AT_PROTECTED:
      objc_set_visibility (OBJC_IVAR_VIS_PROTECTED);
      break;
    case RID_AT_PUBLIC:
      objc_set_visibility (OBJC_IVAR_VIS_PUBLIC);
      break;
    case RID_AT_PACKAGE:
      objc_set_visibility (OBJC_IVAR_VIS_PACKAGE);
      break;
    default:
      return;
    }

  /* Eat '@private'/'@protected'/'@public'.  */
  cp_lexer_consume_token (parser->lexer);
}

/* Parse an Objective-C method type.  Return 'true' if it is a class
   (+) method, and 'false' if it is an instance (-) method.  */

static inline bool
cp_parser_objc_method_type (cp_parser* parser)
{
  if (cp_lexer_consume_token (parser->lexer)->type == CPP_PLUS)
    return true;
  else
    return false;
}

/* Parse an Objective-C protocol qualifier.  */

static tree
cp_parser_objc_protocol_qualifiers (cp_parser* parser)
{
  tree quals = NULL_TREE, node;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  node = token->u.value;

  while (node && identifier_p (node)
	 && (node == ridpointers [(int) RID_IN]
	     || node == ridpointers [(int) RID_OUT]
	     || node == ridpointers [(int) RID_INOUT]
	     || node == ridpointers [(int) RID_BYCOPY]
	     || node == ridpointers [(int) RID_BYREF]
	     || node == ridpointers [(int) RID_ONEWAY]))
    {
      quals = tree_cons (NULL_TREE, node, quals);
      cp_lexer_consume_token (parser->lexer);
      token = cp_lexer_peek_token (parser->lexer);
      node = token->u.value;
    }

  return quals;
}

/* Parse an Objective-C typename.  */

static tree
cp_parser_objc_typename (cp_parser* parser)
{
  tree type_name = NULL_TREE;

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      tree proto_quals, cp_type = NULL_TREE;

      matching_parens parens;
      parens.consume_open (parser); /* Eat '('.  */
      proto_quals = cp_parser_objc_protocol_qualifiers (parser);

      /* An ObjC type name may consist of just protocol qualifiers, in which
	 case the type shall default to 'id'.  */
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
	{
	  cp_type = cp_parser_type_id (parser);

	  /* If the type could not be parsed, an error has already
	     been produced.  For error recovery, behave as if it had
	     not been specified, which will use the default type
	     'id'.  */
	  if (cp_type == error_mark_node)
	    {
	      cp_type = NULL_TREE;
	      /* We need to skip to the closing parenthesis as
		 cp_parser_type_id() does not seem to do it for
		 us.  */
	      cp_parser_skip_to_closing_parenthesis (parser,
						     /*recovering=*/true,
						     /*or_comma=*/false,
						     /*consume_paren=*/false);
	    }
	}

      parens.require_close (parser);
      type_name = build_tree_list (proto_quals, cp_type);
    }

  return type_name;
}

/* Check to see if TYPE refers to an Objective-C selector name.  */

static bool
cp_parser_objc_selector_p (enum cpp_ttype type)
{
  return (type == CPP_NAME || type == CPP_KEYWORD
	  || type == CPP_AND_AND || type == CPP_AND_EQ || type == CPP_AND
	  || type == CPP_OR || type == CPP_COMPL || type == CPP_NOT
	  || type == CPP_NOT_EQ || type == CPP_OR_OR || type == CPP_OR_EQ
	  || type == CPP_XOR || type == CPP_XOR_EQ);
}

/* Parse an Objective-C selector.  */

static tree
cp_parser_objc_selector (cp_parser* parser)
{
  cp_token *token = cp_lexer_consume_token (parser->lexer);

  if (!cp_parser_objc_selector_p (token->type))
    {
      error_at (token->location, "invalid Objective-C++ selector name");
      return error_mark_node;
    }

  /* C++ operator names are allowed to appear in ObjC selectors.  */
  switch (token->type)
    {
    case CPP_AND_AND: return get_identifier ("and");
    case CPP_AND_EQ: return get_identifier ("and_eq");
    case CPP_AND: return get_identifier ("bitand");
    case CPP_OR: return get_identifier ("bitor");
    case CPP_COMPL: return get_identifier ("compl");
    case CPP_NOT: return get_identifier ("not");
    case CPP_NOT_EQ: return get_identifier ("not_eq");
    case CPP_OR_OR: return get_identifier ("or");
    case CPP_OR_EQ: return get_identifier ("or_eq");
    case CPP_XOR: return get_identifier ("xor");
    case CPP_XOR_EQ: return get_identifier ("xor_eq");
    default: return token->u.value;
    }
}

/* Parse an Objective-C params list.  */

static tree
cp_parser_objc_method_keyword_params (cp_parser* parser, tree* attributes)
{
  tree params = NULL_TREE;
  bool maybe_unary_selector_p = true;
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  while (cp_parser_objc_selector_p (token->type) || token->type == CPP_COLON)
    {
      tree selector = NULL_TREE, type_name, identifier;
      tree parm_attr = NULL_TREE;

      if (token->keyword == RID_ATTRIBUTE)
	break;

      if (token->type != CPP_COLON)
	selector = cp_parser_objc_selector (parser);

      /* Detect if we have a unary selector.  */
      if (maybe_unary_selector_p
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
	{
	  params = selector; /* Might be followed by attributes.  */
	  break;
	}

      maybe_unary_selector_p = false;
      if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
	{
	  /* Something went quite wrong.  There should be a colon
	     here, but there is not.  Stop parsing parameters.  */
	  break;
	}
      type_name = cp_parser_objc_typename (parser);
      /* New ObjC allows attributes on parameters too.  */
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
	parm_attr = cp_parser_attributes_opt (parser);
      identifier = cp_parser_identifier (parser);

      params
	= chainon (params,
		   objc_build_keyword_decl (selector,
					    type_name,
					    identifier,
					    parm_attr));

      token = cp_lexer_peek_token (parser->lexer);
    }

  if (params == NULL_TREE)
    {
      cp_parser_error (parser, "objective-c++ method declaration is expected");
      return error_mark_node;
    }

  /* We allow tail attributes for the method.  */
  if (token->keyword == RID_ATTRIBUTE)
    {
      *attributes = cp_parser_attributes_opt (parser);
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
	  || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	return params;
      cp_parser_error (parser,
		       "method attributes must be specified at the end");
      return error_mark_node;
    }

  if (params == NULL_TREE)
    {
      cp_parser_error (parser, "objective-c++ method declaration is expected");
      return error_mark_node;
    }
  return params;
}

/* Parse the non-keyword Objective-C params.  */

static tree
cp_parser_objc_method_tail_params_opt (cp_parser* parser, bool *ellipsisp,
				       tree* attributes)
{
  tree params = make_node (TREE_LIST);
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  *ellipsisp = false;  /* Initially, assume no ellipsis.  */

  while (token->type == CPP_COMMA)
    {
      cp_parameter_declarator *parmdecl;
      tree parm;

      cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
      token = cp_lexer_peek_token (parser->lexer);

      if (token->type == CPP_ELLIPSIS)
	{
	  cp_lexer_consume_token (parser->lexer);  /* Eat '...'.  */
	  *ellipsisp = true;
	  token = cp_lexer_peek_token (parser->lexer);
	  break;
	}

      /* TODO: parse attributes for tail parameters.  */
      parmdecl = cp_parser_parameter_declaration (parser, CP_PARSER_FLAGS_NONE,
						  false, NULL);
      parm = grokdeclarator (parmdecl->declarator,
			     &parmdecl->decl_specifiers,
			     PARM, /*initialized=*/0,
			     /*attrlist=*/NULL);

      chainon (params, build_tree_list (NULL_TREE, parm));
      token = cp_lexer_peek_token (parser->lexer);
    }

  /* We allow tail attributes for the method.  */
  if (token->keyword == RID_ATTRIBUTE)
    {
      if (*attributes == NULL_TREE)
	{
	  *attributes = cp_parser_attributes_opt (parser);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
	      || cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	    return params;
	}
      else
	/* We have an error, but parse the attributes, so that we can
	   carry on.  */
	*attributes = cp_parser_attributes_opt (parser);

      cp_parser_error (parser,
		       "method attributes must be specified at the end");
      return error_mark_node;
    }

  return params;
}

/* Parse a linkage specification, a pragma, an extra semicolon or a block.  */

static void
cp_parser_objc_interstitial_code (cp_parser* parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  /* If the next token is `extern' and the following token is a string
     literal, then we have a linkage specification.  */
  if (token->keyword == RID_EXTERN
      && cp_parser_is_pure_string_literal
	 (cp_lexer_peek_nth_token (parser->lexer, 2)))
    cp_parser_linkage_specification (parser, NULL_TREE);
  /* Handle #pragma, if any.  */
  else if (token->type == CPP_PRAGMA)
    cp_parser_pragma (parser, pragma_objc_icode, NULL);
  /* Allow stray semicolons.  */
  else if (token->type == CPP_SEMICOLON)
    cp_lexer_consume_token (parser->lexer);
  /* Mark methods as optional or required, when building protocols.  */
  else if (token->keyword == RID_AT_OPTIONAL)
    {
      cp_lexer_consume_token (parser->lexer);
      objc_set_method_opt (true);
    }
  else if (token->keyword == RID_AT_REQUIRED)
    {
      cp_lexer_consume_token (parser->lexer);
      objc_set_method_opt (false);
    }
  else if (token->keyword == RID_NAMESPACE)
    cp_parser_namespace_definition (parser);
  /* Other stray characters must generate errors.  */
  else if (token->type == CPP_OPEN_BRACE || token->type == CPP_CLOSE_BRACE)
    {
      cp_lexer_consume_token (parser->lexer);
      error ("stray %qs between Objective-C++ methods",
	     token->type == CPP_OPEN_BRACE ? "{" : "}");
    }
  /* Finally, try to parse a block-declaration, or a function-definition.  */
  else
    cp_parser_block_declaration (parser, /*statement_p=*/false);
}

/* Parse a method signature.  */

static tree
cp_parser_objc_method_signature (cp_parser* parser, tree* attributes)
{
  tree rettype, kwdparms, optparms;
  bool ellipsis = false;
  bool is_class_method;

  is_class_method = cp_parser_objc_method_type (parser);
  rettype = cp_parser_objc_typename (parser);
  *attributes = NULL_TREE;
  kwdparms = cp_parser_objc_method_keyword_params (parser, attributes);
  if (kwdparms == error_mark_node)
    return error_mark_node;
  optparms = cp_parser_objc_method_tail_params_opt (parser, &ellipsis, attributes);
  if (optparms == error_mark_node)
    return error_mark_node;

  return objc_build_method_signature (is_class_method, rettype, kwdparms, optparms, ellipsis);
}

static bool
cp_parser_objc_method_maybe_bad_prefix_attributes (cp_parser* parser)
{
  tree tattr;
  cp_lexer_save_tokens (parser->lexer);
  tattr = cp_parser_attributes_opt (parser);
  gcc_assert (tattr) ;

  /* If the attributes are followed by a method introducer, this is not allowed.
     Dump the attributes and flag the situation.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_PLUS)
      || cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
    return true;

  /* Otherwise, the attributes introduce some interstitial code, possibly so
     rewind to allow that check.  */
  cp_lexer_rollback_tokens (parser->lexer);
  return false;
}

/* Parse an Objective-C method prototype list.  */

static void
cp_parser_objc_method_prototype_list (cp_parser* parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  while (token->keyword != RID_AT_END && token->type != CPP_EOF)
    {
      if (token->type == CPP_PLUS || token->type == CPP_MINUS)
	{
	  tree attributes, sig;
	  bool is_class_method;
	  if (token->type == CPP_PLUS)
	    is_class_method = true;
	  else
	    is_class_method = false;
	  sig = cp_parser_objc_method_signature (parser, &attributes);
	  if (sig == error_mark_node)
	    {
	      cp_parser_skip_to_end_of_block_or_statement (parser);
	      token = cp_lexer_peek_token (parser->lexer);
	      continue;
	    }
	  objc_add_method_declaration (is_class_method, sig, attributes);
	  cp_parser_consume_semicolon_at_end_of_statement (parser);
	}
      else if (token->keyword == RID_AT_PROPERTY)
	cp_parser_objc_at_property_declaration (parser);
      else if (token->keyword == RID_ATTRIBUTE
      	       && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
	warning_at (cp_lexer_peek_token (parser->lexer)->location,
		    OPT_Wattributes,
		    "prefix attributes are ignored for methods");
      else
	/* Allow for interspersed non-ObjC++ code.  */
	cp_parser_objc_interstitial_code (parser);

      token = cp_lexer_peek_token (parser->lexer);
    }

  if (token->type != CPP_EOF)
    cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
  else
    cp_parser_error (parser, "expected %<@end%>");

  objc_finish_interface ();
}

/* Parse an Objective-C method definition list.  */

static void
cp_parser_objc_method_definition_list (cp_parser* parser)
{
  for (;;)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      if (token->keyword == RID_AT_END)
	{
	  cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
	  break;
	}
      else if (token->type == CPP_EOF)
	{
	  cp_parser_error (parser, "expected %<@end%>");
	  break;
	}
      else if (token->type == CPP_PLUS || token->type == CPP_MINUS)
	{
	  bool is_class_method = token->type == CPP_PLUS;

	  push_deferring_access_checks (dk_deferred);
	  tree attribute;
	  tree sig = cp_parser_objc_method_signature (parser, &attribute);
	  if (sig == error_mark_node)
	    cp_parser_skip_to_end_of_block_or_statement (parser);
	  else
	    {
	      objc_start_method_definition (is_class_method, sig,
					    attribute, NULL_TREE);

	      /* For historical reasons, we accept an optional semicolon.  */
	      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
		cp_lexer_consume_token (parser->lexer);

	      perform_deferred_access_checks (tf_warning_or_error);
	      stop_deferring_access_checks ();
	      tree meth
		= cp_parser_function_definition_after_declarator (parser, false);
	      pop_deferring_access_checks ();
	      objc_finish_method_definition (meth);
	    }
	}
      /* The following case will be removed once @synthesize is
	 completely implemented.  */
      else if (token->keyword == RID_AT_PROPERTY)
	cp_parser_objc_at_property_declaration (parser);
      else if (token->keyword == RID_AT_SYNTHESIZE)
	cp_parser_objc_at_synthesize_declaration (parser);
      else if (token->keyword == RID_AT_DYNAMIC)
	cp_parser_objc_at_dynamic_declaration (parser);
      else if (token->keyword == RID_ATTRIBUTE
      	       && cp_parser_objc_method_maybe_bad_prefix_attributes(parser))
	warning_at (token->location, OPT_Wattributes,
	       	    "prefix attributes are ignored for methods");
      else
	/* Allow for interspersed non-ObjC++ code.  */
	cp_parser_objc_interstitial_code (parser);
    }

  objc_finish_implementation ();
}

/* Parse Objective-C ivars.  */

static void
cp_parser_objc_class_ivars (cp_parser* parser)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  if (token->type != CPP_OPEN_BRACE)
    return;	/* No ivars specified.  */

  cp_lexer_consume_token (parser->lexer);  /* Eat '{'.  */
  token = cp_lexer_peek_token (parser->lexer);

  while (token->type != CPP_CLOSE_BRACE
	&& token->keyword != RID_AT_END && token->type != CPP_EOF)
    {
      cp_decl_specifier_seq declspecs;
      int decl_class_or_enum_p;
      tree prefix_attributes;

      cp_parser_objc_visibility_spec (parser);

      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
	break;

      cp_parser_decl_specifier_seq (parser,
				    CP_PARSER_FLAGS_OPTIONAL,
				    &declspecs,
				    &decl_class_or_enum_p);

      /* auto, register, static, extern, mutable.  */
      if (declspecs.storage_class != sc_none)
	{
	  cp_parser_error (parser, "invalid type for instance variable");
	  declspecs.storage_class = sc_none;
	}

      /* thread_local.  */
      if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
	{
	  cp_parser_error (parser, "invalid type for instance variable");
	  declspecs.locations[ds_thread] = 0;
	}

      /* typedef.  */
      if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
	{
	  cp_parser_error (parser, "invalid type for instance variable");
	  declspecs.locations[ds_typedef] = 0;
	}

      prefix_attributes = declspecs.attributes;
      declspecs.attributes = NULL_TREE;

      /* Keep going until we hit the `;' at the end of the
	 declaration.  */
      while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	{
	  tree width = NULL_TREE, attributes, first_attribute, decl;
	  cp_declarator *declarator = NULL;
	  int ctor_dtor_or_conv_p;

	  /* Check for a (possibly unnamed) bitfield declaration.  */
	  token = cp_lexer_peek_token (parser->lexer);
	  if (token->type == CPP_COLON)
	    goto eat_colon;

	  if (token->type == CPP_NAME
	      && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
		  == CPP_COLON))
	    {
	      /* Get the name of the bitfield.  */
	      declarator = make_id_declarator (NULL_TREE,
					       cp_parser_identifier (parser),
					       sfk_none, token->location);

	     eat_colon:
	      cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
	      /* Get the width of the bitfield.  */
	      width
		= cp_parser_constant_expression (parser);
	    }
	  else
	    {
	      /* Parse the declarator.  */
	      declarator
		= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
					CP_PARSER_FLAGS_NONE,
					&ctor_dtor_or_conv_p,
					/*parenthesized_p=*/NULL,
					/*member_p=*/false,
					/*friend_p=*/false,
					/*static_p=*/false);
	    }

	  /* Look for attributes that apply to the ivar.  */
	  attributes = cp_parser_attributes_opt (parser);
	  /* Remember which attributes are prefix attributes and
	     which are not.  */
	  first_attribute = attributes;
	  /* Combine the attributes.  */
	  attributes = attr_chainon (prefix_attributes, attributes);

	  if (width)
	    /* Create the bitfield declaration.  */
	    decl = grokbitfield (declarator, &declspecs,
				 width, NULL_TREE, attributes);
	  else
	    decl = grokfield (declarator, &declspecs,
			      NULL_TREE, /*init_const_expr_p=*/false,
			      NULL_TREE, attributes);

	  /* Add the instance variable.  */
	  if (decl != error_mark_node && decl != NULL_TREE)
	    objc_add_instance_variable (decl);

	  /* Reset PREFIX_ATTRIBUTES.  */
	  if (attributes != error_mark_node)
	    {
	      while (attributes && TREE_CHAIN (attributes) != first_attribute)
		attributes = TREE_CHAIN (attributes);
	      if (attributes)
		TREE_CHAIN (attributes) = NULL_TREE;
	    }

	  token = cp_lexer_peek_token (parser->lexer);

	  if (token->type == CPP_COMMA)
	    {
	      cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
	      continue;
	    }
	  break;
	}

      cp_parser_consume_semicolon_at_end_of_statement (parser);
      token = cp_lexer_peek_token (parser->lexer);
    }

  if (token->keyword == RID_AT_END)
    cp_parser_error (parser, "expected %<}%>");

  /* Do not consume the RID_AT_END, so it will be read again as terminating
     the @interface of @implementation.  */
  if (token->keyword != RID_AT_END && token->type != CPP_EOF)
    cp_lexer_consume_token (parser->lexer);  /* Eat '}'.  */

  /* For historical reasons, we accept an optional semicolon.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    cp_lexer_consume_token (parser->lexer);
}

/* Parse an Objective-C protocol declaration.  */

static void
cp_parser_objc_protocol_declaration (cp_parser* parser, tree attributes)
{
  tree proto, protorefs;
  cp_token *tok;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@protocol'.  */
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
    {
      tok = cp_lexer_peek_token (parser->lexer);
      error_at (tok->location, "identifier expected after %<@protocol%>");
      cp_parser_consume_semicolon_at_end_of_statement (parser);
      return;
    }

  /* See if we have a forward declaration or a definition.  */
  tok = cp_lexer_peek_nth_token (parser->lexer, 2);

  /* Try a forward declaration first.  */
  if (tok->type == CPP_COMMA || tok->type == CPP_SEMICOLON)
    {
      while (true)
	{
	  tree id;

	  id = cp_parser_identifier (parser);
	  if (id == error_mark_node)
	    break;

	  objc_declare_protocol (id, attributes);

	  if(cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	    cp_lexer_consume_token (parser->lexer);
	  else
	    break;
	}
      cp_parser_consume_semicolon_at_end_of_statement (parser);
    }

  /* Ok, we got a full-fledged definition (or at least should).  */
  else
    {
      proto = cp_parser_identifier (parser);
      protorefs = cp_parser_objc_protocol_refs_opt (parser);
      objc_start_protocol (proto, protorefs, attributes);
      cp_parser_objc_method_prototype_list (parser);
    }
}

/* Parse an Objective-C superclass or category.  */

static void
cp_parser_objc_superclass_or_category (cp_parser *parser,
				       bool iface_p,
				       tree *super,
				       tree *categ, bool *is_class_extension)
{
  cp_token *next = cp_lexer_peek_token (parser->lexer);

  *super = *categ = NULL_TREE;
  *is_class_extension = false;
  if (next->type == CPP_COLON)
    {
      cp_lexer_consume_token (parser->lexer);  /* Eat ':'.  */
      *super = cp_parser_identifier (parser);
    }
  else if (next->type == CPP_OPEN_PAREN)
    {
      matching_parens parens;
      parens.consume_open (parser);  /* Eat '('.  */

      /* If there is no category name, and this is an @interface, we
	 have a class extension.  */
      if (iface_p && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
	{
	  *categ = NULL_TREE;
	  *is_class_extension = true;
	}
      else
	*categ = cp_parser_identifier (parser);

      parens.require_close (parser);
    }
}

/* Parse an Objective-C class interface.  */

static void
cp_parser_objc_class_interface (cp_parser* parser, tree attributes)
{
  tree name, super, categ, protos;
  bool is_class_extension;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@interface'.  */
  location_t nam_loc = cp_lexer_peek_token (parser->lexer)->location;
  name = cp_parser_identifier (parser);
  if (name == error_mark_node)
    {
      /* It's hard to recover because even if valid @interface stuff
	 is to follow, we can't compile it (or validate it) if we
	 don't even know which class it refers to.  Let's assume this
	 was a stray '@interface' token in the stream and skip it.
      */
      return;
    }
  cp_parser_objc_superclass_or_category (parser, true, &super, &categ,
					 &is_class_extension);
  protos = cp_parser_objc_protocol_refs_opt (parser);

  /* We have either a class or a category on our hands.  */
  if (categ || is_class_extension)
    objc_start_category_interface (name, categ, protos, attributes);
  else
    {
      objc_start_class_interface (name, nam_loc, super, protos, attributes);
      /* Handle instance variable declarations, if any.  */
      cp_parser_objc_class_ivars (parser);
      objc_continue_interface ();
    }

  cp_parser_objc_method_prototype_list (parser);
}

/* Parse an Objective-C class implementation.  */

static void
cp_parser_objc_class_implementation (cp_parser* parser)
{
  tree name, super, categ;
  bool is_class_extension;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@implementation'.  */
  name = cp_parser_identifier (parser);
  if (name == error_mark_node)
    {
      /* It's hard to recover because even if valid @implementation
	 stuff is to follow, we can't compile it (or validate it) if
	 we don't even know which class it refers to.  Let's assume
	 this was a stray '@implementation' token in the stream and
	 skip it.
      */
      return;
    }
  cp_parser_objc_superclass_or_category (parser, false, &super, &categ,
					 &is_class_extension);

  /* We have either a class or a category on our hands.  */
  if (categ)
    objc_start_category_implementation (name, categ);
  else
    {
      objc_start_class_implementation (name, super);
      /* Handle instance variable declarations, if any.  */
      cp_parser_objc_class_ivars (parser);
      objc_continue_implementation ();
    }

  cp_parser_objc_method_definition_list (parser);
}

/* Consume the @end token and finish off the implementation.  */

static void
cp_parser_objc_end_implementation (cp_parser* parser)
{
  cp_lexer_consume_token (parser->lexer);  /* Eat '@end'.  */
  objc_finish_implementation ();
}

/* Parse an Objective-C declaration.  */

static void
cp_parser_objc_declaration (cp_parser* parser, tree attributes)
{
  /* Try to figure out what kind of declaration is present.  */
  cp_token *kwd = cp_lexer_peek_token (parser->lexer);

  if (attributes)
    switch (kwd->keyword)
      {
	case RID_AT_ALIAS:
	case RID_AT_CLASS:
	case RID_AT_END:
	  error_at (kwd->location, "attributes may not be specified before"
	            " the %<@%D%> Objective-C++ keyword",
		    kwd->u.value);
	  attributes = NULL;
	  break;
	case RID_AT_IMPLEMENTATION:
	  warning_at (kwd->location, OPT_Wattributes,
		      "prefix attributes are ignored before %<@%D%>",
		      kwd->u.value);
	  attributes = NULL;
	default:
	  break;
      }

  switch (kwd->keyword)
    {
    case RID_AT_ALIAS:
      cp_parser_objc_alias_declaration (parser);
      break;
    case RID_AT_CLASS:
      cp_parser_objc_class_declaration (parser);
      break;
    case RID_AT_PROTOCOL:
      cp_parser_objc_protocol_declaration (parser, attributes);
      break;
    case RID_AT_INTERFACE:
      cp_parser_objc_class_interface (parser, attributes);
      break;
    case RID_AT_IMPLEMENTATION:
      cp_parser_objc_class_implementation (parser);
      break;
    case RID_AT_END:
      cp_parser_objc_end_implementation (parser);
      break;
    default:
      error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
		kwd->u.value);
      cp_parser_skip_to_end_of_block_or_statement (parser);
    }
}

/* Parse an Objective-C try-catch-finally statement.

   objc-try-catch-finally-stmt:
     @try compound-statement objc-catch-clause-seq [opt]
       objc-finally-clause [opt]

   objc-catch-clause-seq:
     objc-catch-clause objc-catch-clause-seq [opt]

   objc-catch-clause:
     @catch ( objc-exception-declaration ) compound-statement

   objc-finally-clause:
     @finally compound-statement

   objc-exception-declaration:
     parameter-declaration
     '...'

   where '...' is to be interpreted literally, that is, it means CPP_ELLIPSIS.

   Returns NULL_TREE.

   PS: This function is identical to c_parser_objc_try_catch_finally_statement
   for C.  Keep them in sync.  */

static tree
cp_parser_objc_try_catch_finally_statement (cp_parser *parser)
{
  location_t location;
  tree stmt;

  cp_parser_require_keyword (parser, RID_AT_TRY, RT_AT_TRY);
  location = cp_lexer_peek_token (parser->lexer)->location;
  objc_maybe_warn_exceptions (location);
  /* NB: The @try block needs to be wrapped in its own STATEMENT_LIST
     node, lest it get absorbed into the surrounding block.  */
  stmt = push_stmt_list ();
  cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
  objc_begin_try_stmt (location, pop_stmt_list (stmt));

  while (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_CATCH))
    {
      cp_parameter_declarator *parm;
      tree parameter_declaration = error_mark_node;
      bool seen_open_paren = false;
      matching_parens parens;

      cp_lexer_consume_token (parser->lexer);
      if (parens.require_open (parser))
	seen_open_paren = true;
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	{
	  /* We have "@catch (...)" (where the '...' are literally
	     what is in the code).  Skip the '...'.
	     parameter_declaration is set to NULL_TREE, and
	     objc_being_catch_clauses() knows that that means
	     '...'.  */
	  cp_lexer_consume_token (parser->lexer);
	  parameter_declaration = NULL_TREE;
	}
      else
	{
	  /* We have "@catch (NSException *exception)" or something
	     like that.  Parse the parameter declaration.  */
	  parm = cp_parser_parameter_declaration (parser, CP_PARSER_FLAGS_NONE,
						  false, NULL);
	  if (parm == NULL)
	    parameter_declaration = error_mark_node;
	  else
	    parameter_declaration = grokdeclarator (parm->declarator,
						    &parm->decl_specifiers,
						    PARM, /*initialized=*/0,
						    /*attrlist=*/NULL);
	}
      if (seen_open_paren)
	parens.require_close (parser);
      else
	{
	  /* If there was no open parenthesis, we are recovering from
	     an error, and we are trying to figure out what mistake
	     the user has made.  */

	  /* If there is an immediate closing parenthesis, the user
	     probably forgot the opening one (ie, they typed "@catch
	     NSException *e)".  Parse the closing parenthesis and keep
	     going.  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
	    cp_lexer_consume_token (parser->lexer);

	  /* If these is no immediate closing parenthesis, the user
	     probably doesn't know that parenthesis are required at
	     all (ie, they typed "@catch NSException *e").  So, just
	     forget about the closing parenthesis and keep going.  */
	}
      objc_begin_catch_clause (parameter_declaration);
      cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
      objc_finish_catch_clause ();
    }
  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AT_FINALLY))
    {
      cp_lexer_consume_token (parser->lexer);
      location = cp_lexer_peek_token (parser->lexer)->location;
      /* NB: The @finally block needs to be wrapped in its own STATEMENT_LIST
	 node, lest it get absorbed into the surrounding block.  */
      stmt = push_stmt_list ();
      cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);
      objc_build_finally_clause (location, pop_stmt_list (stmt));
    }

  return objc_finish_try_stmt ();
}

/* Parse an Objective-C synchronized statement.

   objc-synchronized-stmt:
     @synchronized ( expression ) compound-statement

   Returns NULL_TREE.  */

static tree
cp_parser_objc_synchronized_statement (cp_parser *parser)
{
  location_t location;
  tree lock, stmt;

  cp_parser_require_keyword (parser, RID_AT_SYNCHRONIZED, RT_AT_SYNCHRONIZED);

  location = cp_lexer_peek_token (parser->lexer)->location;
  objc_maybe_warn_exceptions (location);
  matching_parens parens;
  parens.require_open (parser);
  lock = cp_parser_expression (parser);
  parens.require_close (parser);

  /* NB: The @synchronized block needs to be wrapped in its own STATEMENT_LIST
     node, lest it get absorbed into the surrounding block.  */
  stmt = push_stmt_list ();
  cp_parser_compound_statement (parser, NULL, BCS_NORMAL, false);

  return objc_build_synchronized (location, lock, pop_stmt_list (stmt));
}

/* Parse an Objective-C throw statement.

   objc-throw-stmt:
     @throw assignment-expression [opt] ;

   Returns a constructed '@throw' statement.  */

static tree
cp_parser_objc_throw_statement (cp_parser *parser)
{
  tree expr = NULL_TREE;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_parser_require_keyword (parser, RID_AT_THROW, RT_AT_THROW);

  if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    expr = cp_parser_expression (parser);

  cp_parser_consume_semicolon_at_end_of_statement (parser);

  return objc_build_throw_stmt (loc, expr);
}

/* Parse an Objective-C statement.  */

static tree
cp_parser_objc_statement (cp_parser * parser)
{
  /* Try to figure out what kind of declaration is present.  */
  cp_token *kwd = cp_lexer_peek_token (parser->lexer);

  switch (kwd->keyword)
    {
    case RID_AT_TRY:
      return cp_parser_objc_try_catch_finally_statement (parser);
    case RID_AT_SYNCHRONIZED:
      return cp_parser_objc_synchronized_statement (parser);
    case RID_AT_THROW:
      return cp_parser_objc_throw_statement (parser);
    default:
      error_at (kwd->location, "misplaced %<@%D%> Objective-C++ construct",
	       kwd->u.value);
      cp_parser_skip_to_end_of_block_or_statement (parser);
    }

  return error_mark_node;
}

/* If we are compiling ObjC++ and we see an __attribute__ we neeed to
   look ahead to see if an objc keyword follows the attributes.  This
   is to detect the use of prefix attributes on ObjC @interface and
   @protocol.  */

static bool
cp_parser_objc_valid_prefix_attributes (cp_parser* parser, tree *attrib)
{
  cp_lexer_save_tokens (parser->lexer);
  tree addon = cp_parser_attributes_opt (parser);
  if (addon
      && OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
    {
      cp_lexer_commit_tokens (parser->lexer);
      if (*attrib)
	TREE_CHAIN (*attrib) = addon;
      else
	*attrib = addon;
      return true;
    }
  cp_lexer_rollback_tokens (parser->lexer);
  return false;
}

/* This routine is a minimal replacement for
   c_parser_struct_declaration () used when parsing the list of
   types/names or ObjC++ properties.  For example, when parsing the
   code

   @property (readonly) int a, b, c;

   this function is responsible for parsing "int a, int b, int c" and
   returning the declarations as CHAIN of DECLs.

   TODO: Share this code with cp_parser_objc_class_ivars.  It's very
   similar parsing.  */
static tree
cp_parser_objc_struct_declaration (cp_parser *parser)
{
  tree decls = NULL_TREE;
  cp_decl_specifier_seq declspecs;
  int decl_class_or_enum_p;
  tree prefix_attributes;

  cp_parser_decl_specifier_seq (parser,
				CP_PARSER_FLAGS_NONE,
				&declspecs,
				&decl_class_or_enum_p);

  if (declspecs.type == error_mark_node)
    return error_mark_node;

  /* auto, register, static, extern, mutable.  */
  if (declspecs.storage_class != sc_none)
    {
      cp_parser_error (parser, "invalid type for property");
      declspecs.storage_class = sc_none;
    }

  /* thread_local.  */
  if (decl_spec_seq_has_spec_p (&declspecs, ds_thread))
    {
      cp_parser_error (parser, "invalid type for property");
      declspecs.locations[ds_thread] = 0;
    }

  /* typedef.  */
  if (decl_spec_seq_has_spec_p (&declspecs, ds_typedef))
    {
      cp_parser_error (parser, "invalid type for property");
      declspecs.locations[ds_typedef] = 0;
    }

  prefix_attributes = declspecs.attributes;
  declspecs.attributes = NULL_TREE;

  /* Keep going until we hit the `;' at the end of the declaration. */
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    {
      tree attributes, first_attribute, decl;
      cp_declarator *declarator;
      cp_token *token;

      /* Parse the declarator.  */
      declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
					 CP_PARSER_FLAGS_NONE,
					 NULL, NULL, false, false, false);

      /* Look for attributes that apply to the ivar.  */
      attributes = cp_parser_attributes_opt (parser);
      /* Remember which attributes are prefix attributes and
	 which are not.  */
      first_attribute = attributes;
      /* Combine the attributes.  */
      attributes = attr_chainon (prefix_attributes, attributes);

      decl = grokfield (declarator, &declspecs,
			NULL_TREE, /*init_const_expr_p=*/false,
			NULL_TREE, attributes);

      if (decl == error_mark_node || decl == NULL_TREE)
	return error_mark_node;

      /* Reset PREFIX_ATTRIBUTES.  */
      if (attributes != error_mark_node)
	{
	  while (attributes && TREE_CHAIN (attributes) != first_attribute)
	    attributes = TREE_CHAIN (attributes);
	  if (attributes)
	    TREE_CHAIN (attributes) = NULL_TREE;
	}

      DECL_CHAIN (decl) = decls;
      decls = decl;

      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_COMMA)
	{
	  cp_lexer_consume_token (parser->lexer);  /* Eat ','.  */
	  continue;
	}
      else
	break;
    }
  return decls;
}

/* Parse an Objective-C @property declaration.  The syntax is:

   objc-property-declaration:
     '@property' objc-property-attributes[opt] struct-declaration ;

   objc-property-attributes:
    '(' objc-property-attribute-list ')'

   objc-property-attribute-list:
     objc-property-attribute
     objc-property-attribute-list, objc-property-attribute

   objc-property-attribute
     'getter' = identifier
     'setter' = identifier
     'readonly'
     'readwrite'
     'assign'
     'retain'
     'copy'
     'nonatomic'

  For example:
    @property NSString *name;
    @property (readonly) id object;
    @property (retain, nonatomic, getter=getTheName) id name;
    @property int a, b, c;

   PS: This function is identical to
   c_parser_objc_at_property_declaration for C.  Keep them in sync.  */
static void
cp_parser_objc_at_property_declaration (cp_parser *parser)
{
  /* Parse the optional attribute list.

     A list of parsed, but not verified, attributes.  */
  auto_delete_vec<property_attribute_info> prop_attr_list;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@property'.  */

  /* Parse the optional attribute list...  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      /* Eat the '('.  */
      matching_parens parens;
      location_t attr_start = cp_lexer_peek_token (parser->lexer)->location;
      parens.consume_open (parser);
      bool syntax_error = false;

      /* Allow empty @property attribute lists, but with a warning.  */
      location_t attr_end = cp_lexer_peek_token (parser->lexer)->location;
      location_t attr_comb;
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
	{
	  attr_comb = make_location (attr_end, attr_start, attr_end);
	  warning_at (attr_comb, OPT_Wattributes,
		      "empty property attribute list");
	}
      else
	while (true)
	  {
	    cp_token *token = cp_lexer_peek_token (parser->lexer);
	    attr_start = token->location;
	    attr_end = get_finish (token->location);
	    attr_comb = make_location (attr_start, attr_start, attr_end);

	    if (token->type == CPP_CLOSE_PAREN || token->type == CPP_COMMA)
	      {
		warning_at (attr_comb, OPT_Wattributes,
			    "missing property attribute");
		if (token->type == CPP_CLOSE_PAREN)
		  break;
		cp_lexer_consume_token (parser->lexer);
		continue;
	      }

	    tree attr_name = NULL_TREE;
	    if (identifier_p (token->u.value))
	      attr_name = token->u.value;

	    enum rid keyword;
	    if (token->type == CPP_NAME)
	      keyword = C_RID_CODE (token->u.value);
	    else if (token->type == CPP_KEYWORD
		     && token->keyword == RID_CLASS)
	      /* Account for accepting the 'class' keyword in this context.  */
	      keyword = RID_CLASS;
	    else
	      keyword = RID_MAX; /* By definition, an unknown property.  */
	    cp_lexer_consume_token (parser->lexer);

	    enum objc_property_attribute_kind prop_kind
	      = objc_prop_attr_kind_for_rid (keyword);
	    property_attribute_info *prop
	      = new property_attribute_info (attr_name, attr_comb, prop_kind);
	    prop_attr_list.safe_push (prop);

	    tree meth_name;
	    switch (prop->prop_kind)
	      {
	      default: break;
	      case OBJC_PROPERTY_ATTR_UNKNOWN:
		if (attr_name)
		  error_at (attr_start, "unknown property attribute %qE",
			    attr_name);
		else
		  error_at (attr_start, "unknown property attribute");
		prop->parse_error = syntax_error = true;
		break;

	      case OBJC_PROPERTY_ATTR_GETTER:
	      case OBJC_PROPERTY_ATTR_SETTER:
		if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
		  {
		    attr_comb = make_location (attr_end, attr_start, attr_end);
		    error_at (attr_comb, "expected %<=%> after Objective-C %qE",
			      attr_name);
		    prop->parse_error = syntax_error = true;
		    break;
		  }

		token = cp_lexer_peek_token (parser->lexer);
		attr_end = token->location;
		cp_lexer_consume_token (parser->lexer); /* eat the = */

		if (!cp_parser_objc_selector_p
		     (cp_lexer_peek_token (parser->lexer)->type))
		  {
		    attr_comb = make_location (attr_end, attr_start, attr_end);
		    error_at (attr_comb, "expected %qE selector name",
			      attr_name);
		    prop->parse_error = syntax_error = true;
		    break;
		  }

		/* Get the end of the method name, and consume the name.  */
		token = cp_lexer_peek_token (parser->lexer);
		attr_end = get_finish (token->location);
		/* Because method names may contain C++ keywords, we have a
		   routine to fetch them (this also consumes the token).  */
		meth_name = cp_parser_objc_selector (parser);

		if (prop->prop_kind == OBJC_PROPERTY_ATTR_SETTER)
		  {
		    if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
		      {
			attr_comb = make_location (attr_end, attr_start,
						   attr_end);
			error_at (attr_comb, "setter method names must"
				  " terminate with %<:%>");
			prop->parse_error = syntax_error = true;
		      }
		    else
		      {
			attr_end = get_finish (cp_lexer_peek_token
					       (parser->lexer)->location);
			cp_lexer_consume_token (parser->lexer);
		      }
		    attr_comb = make_location (attr_start, attr_start,
					       attr_end);
		  }
		else
		  attr_comb = make_location (attr_start, attr_start,
					     attr_end);
		prop->ident = meth_name;
		/* Updated location including all that was successfully
		   parsed.  */
		prop->prop_loc = attr_comb;
		break;
	      }

	    /* If we see a comma here, then keep going - even if we already
	       saw a syntax error.  For simple mistakes e.g. (asign, getter=x)
	       this makes a more useful output and avoid spurious warnings
	       about missing attributes that are, in fact, specified after the
	       one with the syntax error.  */
	    if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	      cp_lexer_consume_token (parser->lexer);
	    else
	      break;
	  }

      if (syntax_error || !parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);
    }

  /* 'properties' is the list of properties that we read.  Usually a
     single one, but maybe more (eg, in "@property int a, b, c;" there
     are three).
     TODO: Update this parsing so that it accepts (erroneous) bitfields so
     that we can issue a meaningful and consistent (between C/C++) error
     message from objc_add_property_declaration ().  */
  tree properties = cp_parser_objc_struct_declaration (parser);

  if (properties == error_mark_node)
    cp_parser_skip_to_end_of_statement (parser);
  else if (properties == NULL_TREE)
    cp_parser_error (parser, "expected identifier");
  else
    {
      /* Comma-separated properties are chained together in reverse order;
	 add them one by one.  */
      properties = nreverse (properties);
      for (; properties; properties = TREE_CHAIN (properties))
	objc_add_property_declaration (loc, copy_node (properties),
				       prop_attr_list);
    }

  cp_parser_consume_semicolon_at_end_of_statement (parser);
}

/* Parse an Objective-C++ @synthesize declaration.  The syntax is:

   objc-synthesize-declaration:
     @synthesize objc-synthesize-identifier-list ;

   objc-synthesize-identifier-list:
     objc-synthesize-identifier
     objc-synthesize-identifier-list, objc-synthesize-identifier

   objc-synthesize-identifier
     identifier
     identifier = identifier

  For example:
    @synthesize MyProperty;
    @synthesize OneProperty, AnotherProperty=MyIvar, YetAnotherProperty;

  PS: This function is identical to c_parser_objc_at_synthesize_declaration
  for C.  Keep them in sync.
*/
static void
cp_parser_objc_at_synthesize_declaration (cp_parser *parser)
{
  tree list = NULL_TREE;
  location_t loc;
  loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@synthesize'.  */
  while (true)
    {
      tree property, ivar;
      property = cp_parser_identifier (parser);
      if (property == error_mark_node)
	{
	  cp_parser_consume_semicolon_at_end_of_statement (parser);
	  return;
	}
      if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	{
	  cp_lexer_consume_token (parser->lexer);
	  ivar = cp_parser_identifier (parser);
	  if (ivar == error_mark_node)
	    {
	      cp_parser_consume_semicolon_at_end_of_statement (parser);
	      return;
	    }
	}
      else
	ivar = NULL_TREE;
      list = chainon (list, build_tree_list (ivar, property));
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	break;
    }
  cp_parser_consume_semicolon_at_end_of_statement (parser);
  objc_add_synthesize_declaration (loc, list);
}

/* Parse an Objective-C++ @dynamic declaration.  The syntax is:

   objc-dynamic-declaration:
     @dynamic identifier-list ;

   For example:
     @dynamic MyProperty;
     @dynamic MyProperty, AnotherProperty;

  PS: This function is identical to c_parser_objc_at_dynamic_declaration
  for C.  Keep them in sync.
*/
static void
cp_parser_objc_at_dynamic_declaration (cp_parser *parser)
{
  tree list = NULL_TREE;
  location_t loc;
  loc = cp_lexer_peek_token (parser->lexer)->location;

  cp_lexer_consume_token (parser->lexer);  /* Eat '@dynamic'.  */
  while (true)
    {
      tree property;
      property = cp_parser_identifier (parser);
      if (property == error_mark_node)
	{
	  cp_parser_consume_semicolon_at_end_of_statement (parser);
	  return;
	}
      list = chainon (list, build_tree_list (NULL, property));
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	break;
    }
  cp_parser_consume_semicolon_at_end_of_statement (parser);
  objc_add_dynamic_declaration (loc, list);
}


/* OpenMP 2.5 / 3.0 / 3.1 / 4.0 / 4.5 / 5.0 parsing routines.  */

/* Returns name of the next clause.
   If the clause is not recognized PRAGMA_OMP_CLAUSE_NONE is returned and
   the token is not consumed.  Otherwise appropriate pragma_omp_clause is
   returned and the token is consumed.  */

static pragma_omp_clause
cp_parser_omp_clause_name (cp_parser *parser)
{
  pragma_omp_clause result = PRAGMA_OMP_CLAUSE_NONE;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
    result = PRAGMA_OACC_CLAUSE_AUTO;
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
    result = PRAGMA_OMP_CLAUSE_IF;
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
    result = PRAGMA_OMP_CLAUSE_DEFAULT;
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DELETE))
    result = PRAGMA_OACC_CLAUSE_DELETE;
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_PRIVATE))
    result = PRAGMA_OMP_CLAUSE_PRIVATE;
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
    result = PRAGMA_OMP_CLAUSE_FOR;
  else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      switch (p[0])
	{
	case 'a':
	  if (!strcmp ("affinity", p))
	    result = PRAGMA_OMP_CLAUSE_AFFINITY;
	  else if (!strcmp ("aligned", p))
	    result = PRAGMA_OMP_CLAUSE_ALIGNED;
	  else if (!strcmp ("allocate", p))
	    result = PRAGMA_OMP_CLAUSE_ALLOCATE;
	  else if (!strcmp ("async", p))
	    result = PRAGMA_OACC_CLAUSE_ASYNC;
	  else if (!strcmp ("attach", p))
	    result = PRAGMA_OACC_CLAUSE_ATTACH;
	  break;
	case 'b':
	  if (!strcmp ("bind", p))
	    result = PRAGMA_OMP_CLAUSE_BIND;
	  break;
	case 'c':
	  if (!strcmp ("collapse", p))
	    result = PRAGMA_OMP_CLAUSE_COLLAPSE;
	  else if (!strcmp ("copy", p))
	    result = PRAGMA_OACC_CLAUSE_COPY;
	  else if (!strcmp ("copyin", p))
	    result = PRAGMA_OMP_CLAUSE_COPYIN;
	  else if (!strcmp ("copyout", p))
	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
	  else if (!strcmp ("copyprivate", p))
	    result = PRAGMA_OMP_CLAUSE_COPYPRIVATE;
	  else if (!strcmp ("create", p))
	    result = PRAGMA_OACC_CLAUSE_CREATE;
	  break;
	case 'd':
	  if (!strcmp ("defaultmap", p))
	    result = PRAGMA_OMP_CLAUSE_DEFAULTMAP;
	  else if (!strcmp ("depend", p))
	    result = PRAGMA_OMP_CLAUSE_DEPEND;
	  else if (!strcmp ("detach", p))
	    result = PRAGMA_OACC_CLAUSE_DETACH;
	  else if (!strcmp ("device", p))
	    result = PRAGMA_OMP_CLAUSE_DEVICE;
	  else if (!strcmp ("deviceptr", p))
	    result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
	  else if (!strcmp ("device_resident", p))
	    result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
	  else if (!strcmp ("device_type", p))
	    result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
	  else if (!strcmp ("dist_schedule", p))
	    result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
	  else if (!strcmp ("doacross", p))
	    result = PRAGMA_OMP_CLAUSE_DOACROSS;
	  break;
	case 'e':
	  if (!strcmp ("enter", p))
	    result = PRAGMA_OMP_CLAUSE_ENTER;
	  break;
	case 'f':
	  if (!strcmp ("filter", p))
	    result = PRAGMA_OMP_CLAUSE_FILTER;
	  else if (!strcmp ("final", p))
	    result = PRAGMA_OMP_CLAUSE_FINAL;
	  else if (!strcmp ("finalize", p))
	    result = PRAGMA_OACC_CLAUSE_FINALIZE;
	  else if (!strcmp ("firstprivate", p))
	    result = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE;
	  else if (!strcmp ("from", p))
	    result = PRAGMA_OMP_CLAUSE_FROM;
	  break;
	case 'g':
	  if (!strcmp ("gang", p))
	    result = PRAGMA_OACC_CLAUSE_GANG;
	  else if (!strcmp ("grainsize", p))
	    result = PRAGMA_OMP_CLAUSE_GRAINSIZE;
	  break;
	case 'h':
	  if (!strcmp ("has_device_addr", p))
	    result = PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR;
	  else if (!strcmp ("hint", p))
	    result = PRAGMA_OMP_CLAUSE_HINT;
	  else if (!strcmp ("host", p))
	    result = PRAGMA_OACC_CLAUSE_HOST;
	  break;
	case 'i':
	  if (!strcmp ("if_present", p))
	    result = PRAGMA_OACC_CLAUSE_IF_PRESENT;
	  else if (!strcmp ("in_reduction", p))
	    result = PRAGMA_OMP_CLAUSE_IN_REDUCTION;
	  else if (!strcmp ("inbranch", p))
	    result = PRAGMA_OMP_CLAUSE_INBRANCH;
	  else if (!strcmp ("independent", p))
	    result = PRAGMA_OACC_CLAUSE_INDEPENDENT;
	  else if (!strcmp ("is_device_ptr", p))
	    result = PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR;
	  break;
	case 'l':
	  if (!strcmp ("lastprivate", p))
	    result = PRAGMA_OMP_CLAUSE_LASTPRIVATE;
	  else if (!strcmp ("linear", p))
	    result = PRAGMA_OMP_CLAUSE_LINEAR;
	  else if (!strcmp ("link", p))
	    result = PRAGMA_OMP_CLAUSE_LINK;
	  break;
	case 'm':
	  if (!strcmp ("map", p))
	    result = PRAGMA_OMP_CLAUSE_MAP;
	  else if (!strcmp ("mergeable", p))
	    result = PRAGMA_OMP_CLAUSE_MERGEABLE;
	  break;
	case 'n':
	  if (!strcmp ("no_create", p))
	    result = PRAGMA_OACC_CLAUSE_NO_CREATE;
	  else if (!strcmp ("nogroup", p))
	    result = PRAGMA_OMP_CLAUSE_NOGROUP;
	  else if (!strcmp ("nohost", p))
	    result = PRAGMA_OACC_CLAUSE_NOHOST;
	  else if (!strcmp ("nontemporal", p))
	    result = PRAGMA_OMP_CLAUSE_NONTEMPORAL;
	  else if (!strcmp ("notinbranch", p))
	    result = PRAGMA_OMP_CLAUSE_NOTINBRANCH;
	  else if (!strcmp ("nowait", p))
	    result = PRAGMA_OMP_CLAUSE_NOWAIT;
	  else if (!strcmp ("num_gangs", p))
	    result = PRAGMA_OACC_CLAUSE_NUM_GANGS;
	  else if (!strcmp ("num_tasks", p))
	    result = PRAGMA_OMP_CLAUSE_NUM_TASKS;
	  else if (!strcmp ("num_teams", p))
	    result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
	  else if (!strcmp ("num_threads", p))
	    result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
	  else if (!strcmp ("num_workers", p))
	    result = PRAGMA_OACC_CLAUSE_NUM_WORKERS;
	  break;
	case 'o':
	  if (!strcmp ("ordered", p))
	    result = PRAGMA_OMP_CLAUSE_ORDERED;
	  else if (!strcmp ("order", p))
	    result = PRAGMA_OMP_CLAUSE_ORDER;
	  break;
	case 'p':
	  if (!strcmp ("parallel", p))
	    result = PRAGMA_OMP_CLAUSE_PARALLEL;
	  else if (!strcmp ("present", p))
	    result = PRAGMA_OACC_CLAUSE_PRESENT;
	  else if (!strcmp ("present_or_copy", p)
		   || !strcmp ("pcopy", p))
	    result = PRAGMA_OACC_CLAUSE_COPY;
	  else if (!strcmp ("present_or_copyin", p)
		   || !strcmp ("pcopyin", p))
	    result = PRAGMA_OACC_CLAUSE_COPYIN;
	  else if (!strcmp ("present_or_copyout", p)
		   || !strcmp ("pcopyout", p))
	    result = PRAGMA_OACC_CLAUSE_COPYOUT;
	  else if (!strcmp ("present_or_create", p)
		   || !strcmp ("pcreate", p))
	    result = PRAGMA_OACC_CLAUSE_CREATE;
	  else if (!strcmp ("priority", p))
	    result = PRAGMA_OMP_CLAUSE_PRIORITY;
	  else if (!strcmp ("proc_bind", p))
	    result = PRAGMA_OMP_CLAUSE_PROC_BIND;
	  break;
	case 'r':
	  if (!strcmp ("reduction", p))
	    result = PRAGMA_OMP_CLAUSE_REDUCTION;
	  break;
	case 's':
	  if (!strcmp ("safelen", p))
	    result = PRAGMA_OMP_CLAUSE_SAFELEN;
	  else if (!strcmp ("schedule", p))
	    result = PRAGMA_OMP_CLAUSE_SCHEDULE;
	  else if (!strcmp ("sections", p))
	    result = PRAGMA_OMP_CLAUSE_SECTIONS;
	  else if (!strcmp ("self", p)) /* "self" is a synonym for "host".  */
	    result = PRAGMA_OACC_CLAUSE_HOST;
	  else if (!strcmp ("seq", p))
	    result = PRAGMA_OACC_CLAUSE_SEQ;
	  else if (!strcmp ("shared", p))
	    result = PRAGMA_OMP_CLAUSE_SHARED;
	  else if (!strcmp ("simd", p))
	    result = PRAGMA_OMP_CLAUSE_SIMD;
	  else if (!strcmp ("simdlen", p))
	    result = PRAGMA_OMP_CLAUSE_SIMDLEN;
	  break;
	case 't':
	  if (!strcmp ("task_reduction", p))
	    result = PRAGMA_OMP_CLAUSE_TASK_REDUCTION;
	  else if (!strcmp ("taskgroup", p))
	    result = PRAGMA_OMP_CLAUSE_TASKGROUP;
	  else if (!strcmp ("thread_limit", p))
	    result = PRAGMA_OMP_CLAUSE_THREAD_LIMIT;
	  else if (!strcmp ("threads", p))
	    result = PRAGMA_OMP_CLAUSE_THREADS;
	  else if (!strcmp ("tile", p))
	    result = PRAGMA_OACC_CLAUSE_TILE;
	  else if (!strcmp ("to", p))
	    result = PRAGMA_OMP_CLAUSE_TO;
	  break;
	case 'u':
	  if (!strcmp ("uniform", p))
	    result = PRAGMA_OMP_CLAUSE_UNIFORM;
	  else if (!strcmp ("untied", p))
	    result = PRAGMA_OMP_CLAUSE_UNTIED;
	  else if (!strcmp ("use_device", p))
	    result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
	  else if (!strcmp ("use_device_addr", p))
	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
	  else if (!strcmp ("use_device_ptr", p))
	    result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
	  break;
	case 'v':
	  if (!strcmp ("vector", p))
	    result = PRAGMA_OACC_CLAUSE_VECTOR;
	  else if (!strcmp ("vector_length", p))
	    result = PRAGMA_OACC_CLAUSE_VECTOR_LENGTH;
	  break;
	case 'w':
	  if (!strcmp ("wait", p))
	    result = PRAGMA_OACC_CLAUSE_WAIT;
	  else if (!strcmp ("worker", p))
	    result = PRAGMA_OACC_CLAUSE_WORKER;
	  break;
	}
    }

  if (result != PRAGMA_OMP_CLAUSE_NONE)
    cp_lexer_consume_token (parser->lexer);

  return result;
}

/* Validate that a clause of the given type does not already exist.  */

static void
check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
			   const char *name, location_t location)
{
  if (omp_find_clause (clauses, code))
    error_at (location, "too many %qs clauses", name);
}

/* OpenMP 2.5:
   variable-list:
     identifier
     variable-list , identifier

   In addition, we match a closing parenthesis (or, if COLON is non-NULL,
   colon).  An opening parenthesis will have been consumed by the caller.

   If KIND is nonzero, create the appropriate node and install the decl
   in OMP_CLAUSE_DECL and add the node to the head of the list.

   If KIND is zero, create a TREE_LIST with the decl in TREE_PURPOSE;
   return the list created.

   COLON can be NULL if only closing parenthesis should end the list,
   or pointer to bool which will receive false if the list is terminated
   by closing parenthesis or true if the list is terminated by colon.

   The optional ALLOW_DEREF argument is true if list items can use the deref
   (->) operator.  */

struct omp_dim
{
  tree low_bound, length;
  location_t loc;
  bool no_colon;
  omp_dim (tree lb, tree len, location_t lo, bool nc)
    : low_bound (lb), length (len), loc (lo), no_colon (nc) {}
};

static tree
cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
				tree list, bool *colon,
				bool allow_deref = false)
{
  auto_vec<omp_dim> dims;
  bool array_section_p;
  cp_token *token;
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
  if (colon)
    {
      parser->colon_corrects_to_scope_p = false;
      *colon = false;
    }
  while (1)
    {
      tree name, decl;

      if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
	cp_parser_parse_tentatively (parser);
      token = cp_lexer_peek_token (parser->lexer);
      if (kind != 0
	  && cp_parser_is_keyword (token, RID_THIS))
	{
	  decl = finish_this_expr ();
	  if (TREE_CODE (decl) == NON_LVALUE_EXPR
	      || CONVERT_EXPR_P (decl))
	    decl = TREE_OPERAND (decl, 0);
	  cp_lexer_consume_token (parser->lexer);
	}
      else if (cp_parser_is_keyword (token, RID_FUNCTION_NAME)
	       || cp_parser_is_keyword (token, RID_PRETTY_FUNCTION_NAME)
	       || cp_parser_is_keyword (token, RID_C99_FUNCTION_NAME))
	{
	  cp_id_kind idk;
	  decl = cp_parser_primary_expression (parser, false, false, false,
					       &idk);
	}
      else if (kind == OMP_CLAUSE_DEPEND
	       && cp_parser_is_keyword (token, RID_OMP_ALL_MEMORY)
	       && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
		   || cp_lexer_nth_token_is (parser->lexer, 2,
					     CPP_CLOSE_PAREN)))
	{
	  decl = ridpointers[RID_OMP_ALL_MEMORY];
	  cp_lexer_consume_token (parser->lexer);
	}
      else
	{
	  name = cp_parser_id_expression (parser, /*template_p=*/false,
					  /*check_dependency_p=*/true,
					  /*template_p=*/NULL,
					  /*declarator_p=*/false,
					  /*optional_p=*/false);
	  if (name == error_mark_node)
	    {
	      if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
		  && cp_parser_simulate_error (parser))
		goto depend_lvalue;
	      goto skip_comma;
	    }

	  if (identifier_p (name))
	    decl = cp_parser_lookup_name_simple (parser, name, token->location);
	  else
	    decl = name;
	  if (decl == error_mark_node)
	    {
	      if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
		  && cp_parser_simulate_error (parser))
		goto depend_lvalue;
	      cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
					   token->location);
	    }
	}
      if (outer_automatic_var_p (decl))
	decl = process_outer_var_ref (decl, tf_warning_or_error);
      if (decl == error_mark_node)
	;
      else if (kind != 0)
	{
	  switch (kind)
	    {
	    case OMP_CLAUSE__CACHE_:
	      /* The OpenACC cache directive explicitly only allows "array
		 elements or subarrays".  */
	      if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_SQUARE)
		{
		  error_at (token->location, "expected %<[%>");
		  decl = error_mark_node;
		  break;
		}
	      /* FALLTHROUGH.  */
	    case OMP_CLAUSE_MAP:
	    case OMP_CLAUSE_FROM:
	    case OMP_CLAUSE_TO:
	    start_component_ref:
	      while (cp_lexer_next_token_is (parser->lexer, CPP_DOT)
		     || (allow_deref
			 && cp_lexer_next_token_is (parser->lexer, CPP_DEREF)))
		{
		  cpp_ttype ttype
		    = cp_lexer_next_token_is (parser->lexer, CPP_DOT)
		      ? CPP_DOT : CPP_DEREF;
		  location_t loc
		    = cp_lexer_peek_token (parser->lexer)->location;
		  cp_id_kind idk = CP_ID_KIND_NONE;
		  cp_lexer_consume_token (parser->lexer);
		  decl = convert_from_reference (decl);
		  decl = (cp_parser_postfix_dot_deref_expression
			  (parser, ttype, cp_expr (decl, token->location),
			   false, &idk, loc));
		}
	      /* FALLTHROUGH.  */
	    case OMP_CLAUSE_AFFINITY:
	    case OMP_CLAUSE_DEPEND:
	    case OMP_CLAUSE_REDUCTION:
	    case OMP_CLAUSE_IN_REDUCTION:
	    case OMP_CLAUSE_TASK_REDUCTION:
	    case OMP_CLAUSE_HAS_DEVICE_ADDR:
	      array_section_p = false;
	      dims.truncate (0);
	      while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
		{
		  location_t loc = UNKNOWN_LOCATION;
		  tree low_bound = NULL_TREE, length = NULL_TREE;
		  bool no_colon = false;

		  parser->colon_corrects_to_scope_p = false;
		  cp_lexer_consume_token (parser->lexer);
		  if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON))
		    {
		      loc = cp_lexer_peek_token (parser->lexer)->location;
		      low_bound = cp_parser_expression (parser);
		      /* Later handling is not prepared to see through these.  */
		      gcc_checking_assert (!location_wrapper_p (low_bound));
		    }
		  if (!colon)
		    parser->colon_corrects_to_scope_p
		      = saved_colon_corrects_to_scope_p;
		  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_SQUARE))
		    {
		      length = integer_one_node;
		      no_colon = true;
		    }
		  else
		    {
		      /* Look for `:'.  */
		      if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
			{
			  if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
			      && cp_parser_simulate_error (parser))
			    goto depend_lvalue;
			  goto skip_comma;
			}
		      if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
			cp_parser_commit_to_tentative_parse (parser);
		      else
			array_section_p = true;
		      if (!cp_lexer_next_token_is (parser->lexer,
						   CPP_CLOSE_SQUARE))
			{
			  length = cp_parser_expression (parser);
			  /* Later handling is not prepared to see through these.  */
			  gcc_checking_assert (!location_wrapper_p (length));
			}
		    }
		  /* Look for the closing `]'.  */
		  if (!cp_parser_require (parser, CPP_CLOSE_SQUARE,
					  RT_CLOSE_SQUARE))
		    {
		      if ((kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
			  && cp_parser_simulate_error (parser))
			goto depend_lvalue;
		      goto skip_comma;
		    }

		  dims.safe_push (omp_dim (low_bound, length, loc, no_colon));
		}

	      if ((kind == OMP_CLAUSE_MAP
		   || kind == OMP_CLAUSE_FROM
		   || kind == OMP_CLAUSE_TO)
		  && !array_section_p
		  && (cp_lexer_next_token_is (parser->lexer, CPP_DOT)
		      || (allow_deref
			  && cp_lexer_next_token_is (parser->lexer,
						     CPP_DEREF))))
		{
		  for (unsigned i = 0; i < dims.length (); i++)
		    {
		      gcc_assert (dims[i].length == integer_one_node);
		      decl = build_array_ref (dims[i].loc,
					      decl, dims[i].low_bound);
		    }
		  goto start_component_ref;
		}
	      else
		for (unsigned i = 0; i < dims.length (); i++)
		  decl = tree_cons (dims[i].low_bound, dims[i].length, decl);

	      break;
	    default:
	      break;
	    }

	  if (kind == OMP_CLAUSE_DEPEND || kind == OMP_CLAUSE_AFFINITY)
	    {
	      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
		  && cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN)
		  && cp_parser_simulate_error (parser))
		{
		depend_lvalue:
		  cp_parser_abort_tentative_parse (parser);
		  decl = cp_parser_assignment_expression (parser, NULL,
							  false, false);
		}
	      else
		cp_parser_parse_definitely (parser);
	    }

	  tree u = build_omp_clause (token->location, kind);
	  OMP_CLAUSE_DECL (u) = decl;
	  OMP_CLAUSE_CHAIN (u) = list;
	  list = u;
	}
      else
	list = tree_cons (decl, NULL_TREE, list);

    get_comma:
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	break;
      cp_lexer_consume_token (parser->lexer);
    }

  if (colon)
    parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;

  if (colon != NULL && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      *colon = true;
      cp_parser_require (parser, CPP_COLON, RT_COLON);
      return list;
    }

  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
    {
      int ending;

      /* Try to resync to an unnested comma.  Copied from
	 cp_parser_parenthesized_expression_list.  */
    skip_comma:
      if (colon)
	parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
      ending = cp_parser_skip_to_closing_parenthesis (parser,
						      /*recovering=*/true,
						      /*or_comma=*/true,
						      /*consume_paren=*/true);
      if (ending < 0)
	goto get_comma;
    }

  return list;
}

/* Similarly, but expect leading and trailing parenthesis.  This is a very
   common case for omp clauses.  */

static tree
cp_parser_omp_var_list (cp_parser *parser, enum omp_clause_code kind, tree list,
			bool allow_deref = false)
{
  if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return cp_parser_omp_var_list_no_open (parser, kind, list, NULL,
					   allow_deref);
  return list;
}

/* OpenACC 2.0:
   copy ( variable-list )
   copyin ( variable-list )
   copyout ( variable-list )
   create ( variable-list )
   delete ( variable-list )
   present ( variable-list )

   OpenACC 2.6:
   no_create ( variable-list )
   attach ( variable-list )
   detach ( variable-list ) */

static tree
cp_parser_oacc_data_clause (cp_parser *parser, pragma_omp_clause c_kind,
			    tree list)
{
  enum gomp_map_kind kind;
  switch (c_kind)
    {
    case PRAGMA_OACC_CLAUSE_ATTACH:
      kind = GOMP_MAP_ATTACH;
      break;
    case PRAGMA_OACC_CLAUSE_COPY:
      kind = GOMP_MAP_TOFROM;
      break;
    case PRAGMA_OACC_CLAUSE_COPYIN:
      kind = GOMP_MAP_TO;
      break;
    case PRAGMA_OACC_CLAUSE_COPYOUT:
      kind = GOMP_MAP_FROM;
      break;
    case PRAGMA_OACC_CLAUSE_CREATE:
      kind = GOMP_MAP_ALLOC;
      break;
    case PRAGMA_OACC_CLAUSE_DELETE:
      kind = GOMP_MAP_RELEASE;
      break;
    case PRAGMA_OACC_CLAUSE_DETACH:
      kind = GOMP_MAP_DETACH;
      break;
    case PRAGMA_OACC_CLAUSE_DEVICE:
      kind = GOMP_MAP_FORCE_TO;
      break;
    case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
      kind = GOMP_MAP_DEVICE_RESIDENT;
      break;
    case PRAGMA_OACC_CLAUSE_HOST:
      kind = GOMP_MAP_FORCE_FROM;
      break;
    case PRAGMA_OACC_CLAUSE_LINK:
      kind = GOMP_MAP_LINK;
      break;
    case PRAGMA_OACC_CLAUSE_NO_CREATE:
      kind = GOMP_MAP_IF_PRESENT;
      break;
    case PRAGMA_OACC_CLAUSE_PRESENT:
      kind = GOMP_MAP_FORCE_PRESENT;
      break;
    default:
      gcc_unreachable ();
    }
  tree nl, c;
  nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_MAP, list, true);

  for (c = nl; c != list; c = OMP_CLAUSE_CHAIN (c))
    OMP_CLAUSE_SET_MAP_KIND (c, kind);

  return nl;
}

/* OpenACC 2.0:
   deviceptr ( variable-list ) */

static tree
cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list)
{
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
  tree vars, t;

  /* Can't use OMP_CLAUSE_MAP here (that is, can't use the generic
     cp_parser_oacc_data_clause), as for PRAGMA_OACC_CLAUSE_DEVICEPTR,
     variable-list must only allow for pointer variables.  */
  vars = cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
  for (t = vars; t; t = TREE_CHAIN (t))
    {
      tree v = TREE_PURPOSE (t);
      tree u = build_omp_clause (loc, OMP_CLAUSE_MAP);
      OMP_CLAUSE_SET_MAP_KIND (u, GOMP_MAP_FORCE_DEVICEPTR);
      OMP_CLAUSE_DECL (u) = v;
      OMP_CLAUSE_CHAIN (u) = list;
      list = u;
    }

  return list;
}

/* OpenACC 2.5:
   auto
   finalize
   independent
   nohost
   seq */

static tree
cp_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
			      tree list)
{
  check_no_duplicate_clause (list, code, omp_clause_code_name[code], loc);

  tree c = build_omp_clause (loc, code);
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

 /* OpenACC:
   num_gangs ( expression )
   num_workers ( expression )
   vector_length ( expression )  */

static tree
cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
				  const char *str, tree list)
{
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  tree t = cp_parser_assignment_expression (parser, NULL, false, false);

  if (t == error_mark_node
      || !parens.require_close (parser))
    {
      cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					     /*or_comma=*/false,
					     /*consume_paren=*/true);
      return list;
    }

  check_no_duplicate_clause (list, code, str, loc);

  tree c = build_omp_clause (loc, code);
  OMP_CLAUSE_OPERAND (c, 0) = t;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenACC:

    gang [( gang-arg-list )]
    worker [( [num:] int-expr )]
    vector [( [length:] int-expr )]

  where gang-arg is one of:

    [num:] int-expr
    static: size-expr

  and size-expr may be:

    *
    int-expr
*/

static tree
cp_parser_oacc_shape_clause (cp_parser *parser, location_t loc,
			     omp_clause_code kind,
			     const char *str, tree list)
{
  const char *id = "num";
  cp_lexer *lexer = parser->lexer;
  tree ops[2] = { NULL_TREE, NULL_TREE }, c;

  if (kind == OMP_CLAUSE_VECTOR)
    id = "length";

  if (cp_lexer_next_token_is (lexer, CPP_OPEN_PAREN))
    {
      matching_parens parens;
      parens.consume_open (parser);

      do
	{
	  cp_token *next = cp_lexer_peek_token (lexer);
	  int idx = 0;

	  /* Gang static argument.  */
	  if (kind == OMP_CLAUSE_GANG
	      && cp_lexer_next_token_is_keyword (lexer, RID_STATIC))
	    {
	      cp_lexer_consume_token (lexer);

	      if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
		goto cleanup_error;

	      idx = 1;
	      if (ops[idx] != NULL)
		{
		  cp_parser_error (parser, "too many %<static%> arguments");
		  goto cleanup_error;
		}

	      /* Check for the '*' argument.  */
	      if (cp_lexer_next_token_is (lexer, CPP_MULT)
		  && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
		      || cp_lexer_nth_token_is (parser->lexer, 2,
						CPP_CLOSE_PAREN)))
		{
		  cp_lexer_consume_token (lexer);
		  ops[idx] = integer_minus_one_node;

		  if (cp_lexer_next_token_is (lexer, CPP_COMMA))
		    {
		      cp_lexer_consume_token (lexer);
		      continue;
		    }
		  else break;
		}
	    }
	  /* Worker num: argument and vector length: arguments.  */
	  else if (cp_lexer_next_token_is (lexer, CPP_NAME)
		   && id_equal (next->u.value, id)
		   && cp_lexer_nth_token_is (lexer, 2, CPP_COLON))
	    {
	      cp_lexer_consume_token (lexer);  /* id  */
	      cp_lexer_consume_token (lexer);  /* ':'  */
	    }

	  /* Now collect the actual argument.  */
	  if (ops[idx] != NULL_TREE)
	    {
	      cp_parser_error (parser, "unexpected argument");
	      goto cleanup_error;
	    }

	  tree expr = cp_parser_assignment_expression (parser, NULL, false,
						       false);
	  if (expr == error_mark_node)
	    goto cleanup_error;

	  mark_exp_read (expr);
	  ops[idx] = expr;

	  if (kind == OMP_CLAUSE_GANG
	      && cp_lexer_next_token_is (lexer, CPP_COMMA))
	    {
	      cp_lexer_consume_token (lexer);
	      continue;
	    }
	  break;
	}
      while (1);

      if (!parens.require_close (parser))
	goto cleanup_error;
    }

  check_no_duplicate_clause (list, kind, str, loc);

  c = build_omp_clause (loc, kind);

  if (ops[1])
    OMP_CLAUSE_OPERAND (c, 1) = ops[1];

  OMP_CLAUSE_OPERAND (c, 0) = ops[0];
  OMP_CLAUSE_CHAIN (c) = list;

  return c;

 cleanup_error:
  cp_parser_skip_to_closing_parenthesis (parser, false, false, true);
  return list;
}

/* OpenACC 2.0:
   tile ( size-expr-list ) */

static tree
cp_parser_oacc_clause_tile (cp_parser *parser, location_t clause_loc, tree list)
{
  tree c, expr = error_mark_node;
  tree tile = NULL_TREE;

  /* Collapse and tile are mutually exclusive.  (The spec doesn't say
     so, but the spec authors never considered such a case and have
     differing opinions on what it might mean, including 'not
     allowed'.)  */
  check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile", clause_loc);
  check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse",
			     clause_loc);

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return list;

  do
    {
      if (tile && !cp_parser_require (parser, CPP_COMMA, RT_COMMA))
	return list;

      if (cp_lexer_next_token_is (parser->lexer, CPP_MULT)
	  && (cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA)
	      || cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN)))
	{
	  cp_lexer_consume_token (parser->lexer);
	  expr = integer_zero_node;
	}
      else
	expr = cp_parser_constant_expression (parser);

      tile = tree_cons (NULL_TREE, expr, tile);
    }
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN));

  /* Consume the trailing ')'.  */
  cp_lexer_consume_token (parser->lexer);

  c = build_omp_clause (clause_loc, OMP_CLAUSE_TILE);
  tile = nreverse (tile);
  OMP_CLAUSE_TILE_LIST (c) = tile;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenACC 2.0
   Parse wait clause or directive parameters.  */

static tree
cp_parser_oacc_wait_list (cp_parser *parser, location_t clause_loc, tree list)
{
  vec<tree, va_gc> *args;
  tree t, args_tree;

  args = cp_parser_parenthesized_expression_list (parser, non_attr,
						  /*cast_p=*/false,
						  /*allow_expansion_p=*/true,
						  /*non_constant_p=*/NULL);

  if (args == NULL || args->length () == 0)
    {
      if (args != NULL)
	{
	  cp_parser_error (parser, "expected integer expression list");
	  release_tree_vector (args);
	}
      return list;
    }

  args_tree = build_tree_list_vec (args);

  release_tree_vector (args);

  for (t = args_tree; t; t = TREE_CHAIN (t))
    {
      tree targ = TREE_VALUE (t);

      if (targ != error_mark_node)
	{
	  if (!INTEGRAL_TYPE_P (TREE_TYPE (targ)))
	    error ("%<wait%> expression must be integral");
	  else
	    {
	      tree c = build_omp_clause (clause_loc, OMP_CLAUSE_WAIT);

	      targ = mark_rvalue_use (targ);
	      OMP_CLAUSE_DECL (c) = targ;
	      OMP_CLAUSE_CHAIN (c) = list;
	      list = c;
	    }
	}
    }

  return list;
}

/* OpenACC:
   wait [( int-expr-list )] */

static tree
cp_parser_oacc_clause_wait (cp_parser *parser, tree list)
{
  location_t location = cp_lexer_peek_token (parser->lexer)->location;

  if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
    list = cp_parser_oacc_wait_list (parser, location, list);
  else
    {
      tree c = build_omp_clause (location, OMP_CLAUSE_WAIT);

      OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
      OMP_CLAUSE_CHAIN (c) = list;
      list = c;
    }

  return list;
}

/* OpenMP 3.0:
   collapse ( constant-expression ) */

static tree
cp_parser_omp_clause_collapse (cp_parser *parser, tree list, location_t location)
{
  tree c, num;
  location_t loc;
  HOST_WIDE_INT n;

  loc = cp_lexer_peek_token (parser->lexer)->location;
  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  num = cp_parser_constant_expression (parser);

  if (!parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  if (num == error_mark_node)
    return list;
  num = fold_non_dependent_expr (num);
  if (!tree_fits_shwi_p (num)
      || !INTEGRAL_TYPE_P (TREE_TYPE (num))
      || (n = tree_to_shwi (num)) <= 0
      || (int) n != n)
    {
      error_at (loc, "collapse argument needs positive constant integer expression");
      return list;
    }

  check_no_duplicate_clause (list, OMP_CLAUSE_COLLAPSE, "collapse", location);
  check_no_duplicate_clause (list, OMP_CLAUSE_TILE, "tile", location);
  c = build_omp_clause (loc, OMP_CLAUSE_COLLAPSE);
  OMP_CLAUSE_CHAIN (c) = list;
  OMP_CLAUSE_COLLAPSE_EXPR (c) = num;

  return c;
}

/* OpenMP 2.5:
   default ( none | shared )

   OpenMP 5.1:
   default ( private | firstprivate )

   OpenACC:
   default ( none | present ) */

static tree
cp_parser_omp_clause_default (cp_parser *parser, tree list,
			      location_t location, bool is_oacc)
{
  enum omp_clause_default_kind kind = OMP_CLAUSE_DEFAULT_UNSPECIFIED;
  tree c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;
  if (!is_oacc && cp_lexer_next_token_is_keyword (parser->lexer, RID_PRIVATE))
    {
      kind = OMP_CLAUSE_DEFAULT_PRIVATE;
      cp_lexer_consume_token (parser->lexer);
    }
  else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      switch (p[0])
	{
	case 'n':
	  if (strcmp ("none", p) != 0)
	    goto invalid_kind;
	  kind = OMP_CLAUSE_DEFAULT_NONE;
	  break;

	case 'p':
	  if (strcmp ("present", p) != 0 || !is_oacc)
	    goto invalid_kind;
	  kind = OMP_CLAUSE_DEFAULT_PRESENT;
	  break;

	case 'f':
	  if (strcmp ("firstprivate", p) != 0 || is_oacc)
	    goto invalid_kind;
	  kind = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
	  break;

	case 's':
	  if (strcmp ("shared", p) != 0 || is_oacc)
	    goto invalid_kind;
	  kind = OMP_CLAUSE_DEFAULT_SHARED;
	  break;

	default:
	  goto invalid_kind;
	}

      cp_lexer_consume_token (parser->lexer);
    }
  else
    {
    invalid_kind:
      if (is_oacc)
	cp_parser_error (parser, "expected %<none%> or %<present%>");
      else
	cp_parser_error (parser, "expected %<none%>, %<shared%>, "
				 "%<private%> or %<firstprivate%>");
    }

  if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  if (kind == OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    return list;

  check_no_duplicate_clause (list, OMP_CLAUSE_DEFAULT, "default", location);
  c = build_omp_clause (location, OMP_CLAUSE_DEFAULT);
  OMP_CLAUSE_CHAIN (c) = list;
  OMP_CLAUSE_DEFAULT_KIND (c) = kind;

  return c;
}

/* OpenMP 3.1:
   final ( expression ) */

static tree
cp_parser_omp_clause_final (cp_parser *parser, tree list, location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_FINAL, "final", location);

  c = build_omp_clause (location, OMP_CLAUSE_FINAL);
  OMP_CLAUSE_FINAL_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 2.5:
   if ( expression )

   OpenMP 4.5:
   if ( directive-name-modifier : expression )

   directive-name-modifier:
     parallel | task | taskloop | target data | target | target update
     | target enter data | target exit data

   OpenMP 5.0:
   directive-name-modifier:
     ... | simd | cancel  */

static tree
cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
			 bool is_omp)
{
  tree t, c;
  enum tree_code if_modifier = ERROR_MARK;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (is_omp && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      int n = 2;

      if (strcmp ("cancel", p) == 0)
	if_modifier = VOID_CST;
      else if (strcmp ("parallel", p) == 0)
	if_modifier = OMP_PARALLEL;
      else if (strcmp ("simd", p) == 0)
	if_modifier = OMP_SIMD;
      else if (strcmp ("task", p) == 0)
	if_modifier = OMP_TASK;
      else if (strcmp ("taskloop", p) == 0)
	if_modifier = OMP_TASKLOOP;
      else if (strcmp ("target", p) == 0)
	{
	  if_modifier = OMP_TARGET;
	  if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	    {
	      id = cp_lexer_peek_nth_token (parser->lexer, 2)->u.value;
	      p = IDENTIFIER_POINTER (id);
	      if (strcmp ("data", p) == 0)
		if_modifier = OMP_TARGET_DATA;
	      else if (strcmp ("update", p) == 0)
		if_modifier = OMP_TARGET_UPDATE;
	      else if (strcmp ("enter", p) == 0)
		if_modifier = OMP_TARGET_ENTER_DATA;
	      else if (strcmp ("exit", p) == 0)
		if_modifier = OMP_TARGET_EXIT_DATA;
	      if (if_modifier != OMP_TARGET)
		n = 3;
	      else
		{
		  location_t loc
		    = cp_lexer_peek_nth_token (parser->lexer, 2)->location;
		  error_at (loc, "expected %<data%>, %<update%>, %<enter%> "
				 "or %<exit%>");
		  if_modifier = ERROR_MARK;
		}
	      if (if_modifier == OMP_TARGET_ENTER_DATA
		  || if_modifier == OMP_TARGET_EXIT_DATA)
		{
		  if (cp_lexer_nth_token_is (parser->lexer, 3, CPP_NAME))
		    {
		      id = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value;
		      p = IDENTIFIER_POINTER (id);
		      if (strcmp ("data", p) == 0)
			n = 4;
		    }
		  if (n != 4)
		    {
		      location_t loc
			= cp_lexer_peek_nth_token (parser->lexer, 3)->location;
		      error_at (loc, "expected %<data%>");
		      if_modifier = ERROR_MARK;
		    }
		}
	    }
	}
      if (if_modifier != ERROR_MARK)
	{
	  if (cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON))
	    {
	      while (n-- > 0)
		cp_lexer_consume_token (parser->lexer);
	    }
	  else
	    {
	      if (n > 2)
		{
		  location_t loc
		    = cp_lexer_peek_nth_token (parser->lexer, n)->location;
		  error_at (loc, "expected %<:%>");
		}
	      if_modifier = ERROR_MARK;
	    }
	}
    }

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IF)
      {
	if (if_modifier != ERROR_MARK
	    && OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
	  {
	    const char *p = NULL;
	    switch (if_modifier)
	      {
	      case VOID_CST: p = "cancel"; break;
	      case OMP_PARALLEL: p = "parallel"; break;
	      case OMP_SIMD: p = "simd"; break;
	      case OMP_TASK: p = "task"; break;
	      case OMP_TASKLOOP: p = "taskloop"; break;
	      case OMP_TARGET_DATA: p = "target data"; break;
	      case OMP_TARGET: p = "target"; break;
	      case OMP_TARGET_UPDATE: p = "target update"; break;
	      case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
	      case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
	      default: gcc_unreachable ();
	      }
	    error_at (location, "too many %<if%> clauses with %qs modifier",
		      p);
	    return list;
	  }
	else if (OMP_CLAUSE_IF_MODIFIER (c) == if_modifier)
	  {
	    if (!is_omp)
	      error_at (location, "too many %<if%> clauses");
	    else
	      error_at (location, "too many %<if%> clauses without modifier");
	    return list;
	  }
	else if (if_modifier == ERROR_MARK
		 || OMP_CLAUSE_IF_MODIFIER (c) == ERROR_MARK)
	  {
	    error_at (location, "if any %<if%> clause has modifier, then all "
				"%<if%> clauses have to use modifier");
	    return list;
	  }
      }

  c = build_omp_clause (location, OMP_CLAUSE_IF);
  OMP_CLAUSE_IF_MODIFIER (c) = if_modifier;
  OMP_CLAUSE_IF_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 3.1:
   mergeable */

static tree
cp_parser_omp_clause_mergeable (cp_parser * /*parser*/,
				tree list, location_t location)
{
  tree c;

  check_no_duplicate_clause (list, OMP_CLAUSE_MERGEABLE, "mergeable",
			     location);

  c = build_omp_clause (location, OMP_CLAUSE_MERGEABLE);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 2.5:
   nowait */

static tree
cp_parser_omp_clause_nowait (cp_parser * /*parser*/,
			     tree list, location_t location)
{
  tree c;

  check_no_duplicate_clause (list, OMP_CLAUSE_NOWAIT, "nowait", location);

  c = build_omp_clause (location, OMP_CLAUSE_NOWAIT);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 2.5:
   num_threads ( expression ) */

static tree
cp_parser_omp_clause_num_threads (cp_parser *parser, tree list,
				  location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_NUM_THREADS,
			     "num_threads", location);

  c = build_omp_clause (location, OMP_CLAUSE_NUM_THREADS);
  OMP_CLAUSE_NUM_THREADS_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   num_tasks ( expression )

   OpenMP 5.1:
   num_tasks ( strict : expression ) */

static tree
cp_parser_omp_clause_num_tasks (cp_parser *parser, tree list,
				location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  bool strict = false;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      if (!strcmp (IDENTIFIER_POINTER (id), "strict"))
	{
	  strict = true;
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	}
    }

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TASKS,
			     "num_tasks", location);

  c = build_omp_clause (location, OMP_CLAUSE_NUM_TASKS);
  OMP_CLAUSE_NUM_TASKS_EXPR (c) = t;
  OMP_CLAUSE_NUM_TASKS_STRICT (c) = strict;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   grainsize ( expression )

   OpenMP 5.1:
   grainsize ( strict : expression ) */

static tree
cp_parser_omp_clause_grainsize (cp_parser *parser, tree list,
				location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  bool strict = false;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      if (!strcmp (IDENTIFIER_POINTER (id), "strict"))
	{
	  strict = true;
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	}
    }

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_GRAINSIZE,
			     "grainsize", location);

  c = build_omp_clause (location, OMP_CLAUSE_GRAINSIZE);
  OMP_CLAUSE_GRAINSIZE_EXPR (c) = t;
  OMP_CLAUSE_GRAINSIZE_STRICT (c) = strict;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   priority ( expression ) */

static tree
cp_parser_omp_clause_priority (cp_parser *parser, tree list,
			       location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_PRIORITY,
			     "priority", location);

  c = build_omp_clause (location, OMP_CLAUSE_PRIORITY);
  OMP_CLAUSE_PRIORITY_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   hint ( expression ) */

static tree
cp_parser_omp_clause_hint (cp_parser *parser, tree list, location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_assignment_expression (parser);

  if (t != error_mark_node)
    {
      t = fold_non_dependent_expr (t);
      if (!value_dependent_expression_p (t)
	  && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
	      || !tree_fits_shwi_p (t)
	      || tree_int_cst_sgn (t) == -1))
	error_at (location, "expected constant integer expression with "
			    "valid sync-hint value");
    }
  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);
  check_no_duplicate_clause (list, OMP_CLAUSE_HINT, "hint", location);

  c = build_omp_clause (location, OMP_CLAUSE_HINT);
  OMP_CLAUSE_HINT_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 5.1:
   filter ( integer-expression ) */

static tree
cp_parser_omp_clause_filter (cp_parser *parser, tree list, location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);
  check_no_duplicate_clause (list, OMP_CLAUSE_FILTER, "filter", location);

  c = build_omp_clause (location, OMP_CLAUSE_FILTER);
  OMP_CLAUSE_FILTER_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   defaultmap ( tofrom : scalar )

   OpenMP 5.0:
   defaultmap ( implicit-behavior [ : variable-category ] ) */

static tree
cp_parser_omp_clause_defaultmap (cp_parser *parser, tree list,
				 location_t location)
{
  tree c, id;
  const char *p;
  enum omp_clause_defaultmap_kind behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
  enum omp_clause_defaultmap_kind category
    = OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT))
    p = "default";
  else if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
    invalid_behavior:
      cp_parser_error (parser, "expected %<alloc%>, %<to%>, %<from%>, "
			       "%<tofrom%>, %<firstprivate%>, %<none%> "
			       "or %<default%>");
      goto out_err;
    }
  else
    {
      id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
    }

  switch (p[0])
    {
    case 'a':
      if (strcmp ("alloc", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_ALLOC;
      else
	goto invalid_behavior;
      break;

    case 'd':
      if (strcmp ("default", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_DEFAULT;
      else
	goto invalid_behavior;
      break;

    case 'f':
      if (strcmp ("firstprivate", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
      else if (strcmp ("from", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_FROM;
      else
	goto invalid_behavior;
      break;

    case 'n':
      if (strcmp ("none", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_NONE;
      else
	goto invalid_behavior;
      break;

    case 't':
      if (strcmp ("tofrom", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_TOFROM;
      else if (strcmp ("to", p) == 0)
	behavior = OMP_CLAUSE_DEFAULTMAP_TO;
      else
	goto invalid_behavior;
      break;

    default:
      goto invalid_behavior;
    }
  cp_lexer_consume_token (parser->lexer);

  if (!cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
    {
      if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
	goto out_err;

      if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	invalid_category:
	  cp_parser_error (parser, "expected %<scalar%>, %<aggregate%> or "
				   "%<pointer%>");
	  goto out_err;
	}
      id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);

      switch (p[0])
	{
	case 'a':
	  if (strcmp ("aggregate", p) == 0)
	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE;
	  else
	    goto invalid_category;
	  break;

	case 'p':
	  if (strcmp ("pointer", p) == 0)
	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER;
	  else
	    goto invalid_category;
	  break;

	case 's':
	  if (strcmp ("scalar", p) == 0)
	    category = OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR;
	  else
	    goto invalid_category;
	  break;

	default:
	  goto invalid_category;
	}

      cp_lexer_consume_token (parser->lexer);
    }
  if (!parens.require_close (parser))
    goto out_err;

  for (c = list; c ; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEFAULTMAP
	&& (category == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED
	    || OMP_CLAUSE_DEFAULTMAP_CATEGORY (c) == category
	    || (OMP_CLAUSE_DEFAULTMAP_CATEGORY (c)
		== OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)))
      {
	enum omp_clause_defaultmap_kind cat = category;
	location_t loc = OMP_CLAUSE_LOCATION (c);
	if (cat == OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED)
	  cat = OMP_CLAUSE_DEFAULTMAP_CATEGORY (c);
	p = NULL;
	switch (cat)
	  {
	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED:
	    p = NULL;
	    break;
	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_AGGREGATE:
	    p = "aggregate";
	    break;
	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_POINTER:
	    p = "pointer";
	    break;
	  case OMP_CLAUSE_DEFAULTMAP_CATEGORY_SCALAR:
	    p = "scalar";
	    break;
	  default:
	    gcc_unreachable ();
	  }
	if (p)
	  error_at (loc, "too many %<defaultmap%> clauses with %qs category",
		    p);
	else
	  error_at (loc, "too many %<defaultmap%> clauses with unspecified "
			 "category");
	break;
      }

  c = build_omp_clause (location, OMP_CLAUSE_DEFAULTMAP);
  OMP_CLAUSE_DEFAULTMAP_SET_KIND (c, behavior, category);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 out_err:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 5.0:
   order ( concurrent )

   OpenMP 5.1:
   order ( order-modifier : concurrent )

   order-modifier:
     reproducible
     unconstrained  */

static tree
cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location)
{
  tree c, id;
  const char *p;
  bool unconstrained = false;
  bool reproducible = false;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
    {
      id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
      if (strcmp (p, "unconstrained") == 0)
	unconstrained = true;
      else if (strcmp (p, "reproducible") == 0)
	reproducible = true;
      else
	{
	  cp_parser_error (parser, "expected %<reproducible%> or "
				   "%<unconstrained%>");
	  goto out_err;
	}
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
    }
  if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      cp_parser_error (parser, "expected %<concurrent%>");
      goto out_err;
    }
  else
    {
      id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
    }
  if (strcmp (p, "concurrent") != 0)
    {
      cp_parser_error (parser, "expected %<concurrent%>");
      goto out_err;
    }
  cp_lexer_consume_token (parser->lexer);
  if (!parens.require_close (parser))
    goto out_err;

  check_no_duplicate_clause (list, OMP_CLAUSE_ORDER, "order", location);
  c = build_omp_clause (location, OMP_CLAUSE_ORDER);
  OMP_CLAUSE_ORDER_UNCONSTRAINED (c) = unconstrained;
  OMP_CLAUSE_ORDER_REPRODUCIBLE (c) = reproducible;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 out_err:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 5.0:
   bind ( teams | parallel | thread ) */

static tree
cp_parser_omp_clause_bind (cp_parser *parser, tree list,
			   location_t location)
{
  tree c;
  const char *p;
  enum omp_clause_bind_kind kind = OMP_CLAUSE_BIND_THREAD;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
    invalid:
      cp_parser_error (parser,
		       "expected %<teams%>, %<parallel%> or %<thread%>");
      goto out_err;
    }
  else
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
    }
  if (strcmp (p, "teams") == 0)
    kind = OMP_CLAUSE_BIND_TEAMS;
  else if (strcmp (p, "parallel") == 0)
    kind = OMP_CLAUSE_BIND_PARALLEL;
  else if (strcmp (p, "thread") != 0)
    goto invalid;
  cp_lexer_consume_token (parser->lexer);
  if (!parens.require_close (parser))
    goto out_err;

  /* check_no_duplicate_clause (list, OMP_CLAUSE_BIND, "bind", location); */
  c = build_omp_clause (location, OMP_CLAUSE_BIND);
  OMP_CLAUSE_BIND_KIND (c) = kind;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 out_err:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 2.5:
   ordered

   OpenMP 4.5:
   ordered ( constant-expression ) */

static tree
cp_parser_omp_clause_ordered (cp_parser *parser,
			      tree list, location_t location)
{
  tree c, num = NULL_TREE;
  HOST_WIDE_INT n;

  check_no_duplicate_clause (list, OMP_CLAUSE_ORDERED,
			     "ordered", location);

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      matching_parens parens;
      parens.consume_open (parser);

      num = cp_parser_constant_expression (parser);

      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);

      if (num == error_mark_node)
	return list;
      num = fold_non_dependent_expr (num);
      if (!tree_fits_shwi_p (num)
	  || !INTEGRAL_TYPE_P (TREE_TYPE (num))
	  || (n = tree_to_shwi (num)) <= 0
	  || (int) n != n)
	{
	  error_at (location,
		    "ordered argument needs positive constant integer "
		    "expression");
	  return list;
	}
    }

  c = build_omp_clause (location, OMP_CLAUSE_ORDERED);
  OMP_CLAUSE_ORDERED_EXPR (c) = num;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 2.5:
   reduction ( reduction-operator : variable-list )

   reduction-operator:
     One of: + * - & ^ | && ||

   OpenMP 3.1:

   reduction-operator:
     One of: + * - & ^ | && || min max

   OpenMP 4.0:

   reduction-operator:
     One of: + * - & ^ | && ||
     id-expression

   OpenMP 5.0:
   reduction ( reduction-modifier, reduction-operator : variable-list )
   in_reduction ( reduction-operator : variable-list )
   task_reduction ( reduction-operator : variable-list )  */

static tree
cp_parser_omp_clause_reduction (cp_parser *parser, enum omp_clause_code kind,
				bool is_omp, tree list)
{
  enum tree_code code = ERROR_MARK;
  tree nlist, c, id = NULL_TREE;
  bool task = false;
  bool inscan = false;

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return list;

  if (kind == OMP_CLAUSE_REDUCTION && is_omp)
    {
      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DEFAULT)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	}
      else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COMMA))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  const char *p = IDENTIFIER_POINTER (id);
	  if (strcmp (p, "task") == 0)
	    task = true;
	  else if (strcmp (p, "inscan") == 0)
	    inscan = true;
	  if (task || inscan)
	    {
	      cp_lexer_consume_token (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	    }
	}
    }

  switch (cp_lexer_peek_token (parser->lexer)->type)
    {
    case CPP_PLUS: code = PLUS_EXPR; break;
    case CPP_MULT: code = MULT_EXPR; break;
    case CPP_MINUS: code = MINUS_EXPR; break;
    case CPP_AND: code = BIT_AND_EXPR; break;
    case CPP_XOR: code = BIT_XOR_EXPR; break;
    case CPP_OR: code = BIT_IOR_EXPR; break;
    case CPP_AND_AND: code = TRUTH_ANDIF_EXPR; break;
    case CPP_OR_OR: code = TRUTH_ORIF_EXPR; break;
    default: break;
    }

  if (code != ERROR_MARK)
    cp_lexer_consume_token (parser->lexer);
  else
    {
      bool saved_colon_corrects_to_scope_p;
      saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
      parser->colon_corrects_to_scope_p = false;
      id = cp_parser_id_expression (parser, /*template_p=*/false,
				    /*check_dependency_p=*/true,
				    /*template_p=*/NULL,
				    /*declarator_p=*/false,
				    /*optional_p=*/false);
      parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
      if (identifier_p (id))
	{
	  const char *p = IDENTIFIER_POINTER (id);

	  if (strcmp (p, "min") == 0)
	    code = MIN_EXPR;
	  else if (strcmp (p, "max") == 0)
	    code = MAX_EXPR;
	  else if (id == ovl_op_identifier (false, PLUS_EXPR))
	    code = PLUS_EXPR;
	  else if (id == ovl_op_identifier (false, MULT_EXPR))
	    code = MULT_EXPR;
	  else if (id == ovl_op_identifier (false, MINUS_EXPR))
	    code = MINUS_EXPR;
	  else if (id == ovl_op_identifier (false, BIT_AND_EXPR))
	    code = BIT_AND_EXPR;
	  else if (id == ovl_op_identifier (false, BIT_IOR_EXPR))
	    code = BIT_IOR_EXPR;
	  else if (id == ovl_op_identifier (false, BIT_XOR_EXPR))
	    code = BIT_XOR_EXPR;
	  else if (id == ovl_op_identifier (false, TRUTH_ANDIF_EXPR))
	    code = TRUTH_ANDIF_EXPR;
	  else if (id == ovl_op_identifier (false, TRUTH_ORIF_EXPR))
	    code = TRUTH_ORIF_EXPR;
	  id = omp_reduction_id (code, id, NULL_TREE);
	  tree scope = parser->scope;
	  if (scope)
	    id = build_qualified_name (NULL_TREE, scope, id, false);
	  parser->scope = NULL_TREE;
	  parser->qualifying_scope = NULL_TREE;
	  parser->object_scope = NULL_TREE;
	}
      else
	{
	  error ("invalid reduction-identifier");
	 resync_fail:
	  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
						 /*or_comma=*/false,
						 /*consume_paren=*/true);
	  return list;
	}
    }

  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
    goto resync_fail;

  nlist = cp_parser_omp_var_list_no_open (parser, kind, list,
					  NULL);
  for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
    {
      OMP_CLAUSE_REDUCTION_CODE (c) = code;
      if (task)
	OMP_CLAUSE_REDUCTION_TASK (c) = 1;
      else if (inscan)
	OMP_CLAUSE_REDUCTION_INSCAN (c) = 1;
      OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = id;
    }

  return nlist;
}

/* OpenMP 2.5:
   schedule ( schedule-kind )
   schedule ( schedule-kind , expression )

   schedule-kind:
     static | dynamic | guided | runtime | auto

   OpenMP 4.5:
   schedule ( schedule-modifier : schedule-kind )
   schedule ( schedule-modifier [ , schedule-modifier ] : schedule-kind , expression )

   schedule-modifier:
     simd
     monotonic
     nonmonotonic  */

static tree
cp_parser_omp_clause_schedule (cp_parser *parser, tree list, location_t location)
{
  tree c, t;
  int modifiers = 0, nmodifiers = 0;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  c = build_omp_clause (location, OMP_CLAUSE_SCHEDULE);

  location_t comma = UNKNOWN_LOCATION;
  while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      if (strcmp ("simd", p) == 0)
	OMP_CLAUSE_SCHEDULE_SIMD (c) = 1;
      else if (strcmp ("monotonic", p) == 0)
	modifiers |= OMP_CLAUSE_SCHEDULE_MONOTONIC;
      else if (strcmp ("nonmonotonic", p) == 0)
	modifiers |= OMP_CLAUSE_SCHEDULE_NONMONOTONIC;
      else
	break;
      comma = UNKNOWN_LOCATION;
      cp_lexer_consume_token (parser->lexer);
      if (nmodifiers++ == 0
	  && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	{
	  comma = cp_lexer_peek_token (parser->lexer)->location;
	  cp_lexer_consume_token (parser->lexer);
	}
      else
	{
	  cp_parser_require (parser, CPP_COLON, RT_COLON);
	  break;
	}
    }
  if (comma != UNKNOWN_LOCATION)
    error_at (comma, "expected %<:%>");

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      switch (p[0])
	{
	case 'd':
	  if (strcmp ("dynamic", p) != 0)
	    goto invalid_kind;
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_DYNAMIC;
	  break;

	case 'g':
	  if (strcmp ("guided", p) != 0)
	    goto invalid_kind;
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_GUIDED;
	  break;

	case 'r':
	  if (strcmp ("runtime", p) != 0)
	    goto invalid_kind;
	  OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_RUNTIME;
	  break;

	default:
	  goto invalid_kind;
	}
    }
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
    OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_STATIC;
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
    OMP_CLAUSE_SCHEDULE_KIND (c) = OMP_CLAUSE_SCHEDULE_AUTO;
  else
    goto invalid_kind;
  cp_lexer_consume_token (parser->lexer);

  if ((modifiers & (OMP_CLAUSE_SCHEDULE_MONOTONIC
		    | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
      == (OMP_CLAUSE_SCHEDULE_MONOTONIC
	  | OMP_CLAUSE_SCHEDULE_NONMONOTONIC))
    {
      error_at (location, "both %<monotonic%> and %<nonmonotonic%> modifiers "
			  "specified");
      modifiers = 0;
    }

  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
    {
      cp_token *token;
      cp_lexer_consume_token (parser->lexer);

      token = cp_lexer_peek_token (parser->lexer);
      t = cp_parser_assignment_expression (parser);

      if (t == error_mark_node)
	goto resync_fail;
      else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_RUNTIME)
	error_at (token->location, "schedule %<runtime%> does not take "
		  "a %<chunk_size%> parameter");
      else if (OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_AUTO)
	error_at (token->location, "schedule %<auto%> does not take "
		  "a %<chunk_size%> parameter");
      else
	OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (c) = t;

      if (!parens.require_close (parser))
	goto resync_fail;
    }
  else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
    goto resync_fail;

  OMP_CLAUSE_SCHEDULE_KIND (c)
    = (enum omp_clause_schedule_kind)
      (OMP_CLAUSE_SCHEDULE_KIND (c) | modifiers);

  check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule", location);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 invalid_kind:
  cp_parser_error (parser, "invalid schedule kind");
 resync_fail:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 3.0:
   untied */

static tree
cp_parser_omp_clause_untied (cp_parser * /*parser*/,
			     tree list, location_t location)
{
  tree c;

  check_no_duplicate_clause (list, OMP_CLAUSE_UNTIED, "untied", location);

  c = build_omp_clause (location, OMP_CLAUSE_UNTIED);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 4.0:
   inbranch
   notinbranch */

static tree
cp_parser_omp_clause_branch (cp_parser * /*parser*/, enum omp_clause_code code,
			     tree list, location_t location)
{
  check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
  tree c = build_omp_clause (location, code);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 4.0:
   parallel
   for
   sections
   taskgroup */

static tree
cp_parser_omp_clause_cancelkind (cp_parser * /*parser*/,
				 enum omp_clause_code code,
				 tree list, location_t location)
{
  tree c = build_omp_clause (location, code);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 4.5:
   nogroup */

static tree
cp_parser_omp_clause_nogroup (cp_parser * /*parser*/,
			      tree list, location_t location)
{
  check_no_duplicate_clause (list, OMP_CLAUSE_NOGROUP, "nogroup", location);
  tree c = build_omp_clause (location, OMP_CLAUSE_NOGROUP);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 4.5:
   simd
   threads */

static tree
cp_parser_omp_clause_orderedkind (cp_parser * /*parser*/,
				  enum omp_clause_code code,
				  tree list, location_t location)
{
  check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
  tree c = build_omp_clause (location, code);
  OMP_CLAUSE_CHAIN (c) = list;
  return c;
}

/* OpenMP 4.0:
   num_teams ( expression )

   OpenMP 5.1:
   num_teams ( expression : expression ) */

static tree
cp_parser_omp_clause_num_teams (cp_parser *parser, tree list,
				location_t location)
{
  tree upper, lower = NULL_TREE, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
  parser->colon_corrects_to_scope_p = false;
  upper = cp_parser_assignment_expression (parser);
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;

  if (upper != error_mark_node
      && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      lower = upper;
      cp_lexer_consume_token (parser->lexer);
      upper = cp_parser_assignment_expression (parser);
    }

  if (upper == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_NUM_TEAMS,
			     "num_teams", location);

  c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS);
  OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c) = upper;
  OMP_CLAUSE_NUM_TEAMS_LOWER_EXPR (c) = lower;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.0:
   thread_limit ( expression ) */

static tree
cp_parser_omp_clause_thread_limit (cp_parser *parser, tree list,
				   location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_THREAD_LIMIT,
			     "thread_limit", location);

  c = build_omp_clause (location, OMP_CLAUSE_THREAD_LIMIT);
  OMP_CLAUSE_THREAD_LIMIT_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.0:
   aligned ( variable-list )
   aligned ( variable-list : constant-expression )  */

static tree
cp_parser_omp_clause_aligned (cp_parser *parser, tree list)
{
  tree nlist, c, alignment = NULL_TREE;
  bool colon;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALIGNED, list,
					  &colon);

  if (colon)
    {
      alignment = cp_parser_constant_expression (parser);

      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);

      if (alignment == error_mark_node)
	alignment = NULL_TREE;
    }

  for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
    OMP_CLAUSE_ALIGNED_ALIGNMENT (c) = alignment;

  return nlist;
}

/* OpenMP 5.0:
   allocate ( variable-list )
   allocate ( expression : variable-list )

   OpenMP 5.1:
   allocate ( allocator-modifier : variable-list )
   allocate ( allocator-modifier , allocator-modifier : variable-list )

   allocator-modifier:
   allocator ( expression )
   align ( expression )  */

static tree
cp_parser_omp_clause_allocate (cp_parser *parser, tree list)
{
  tree nlist, c, allocator = NULL_TREE, align = NULL_TREE;
  bool colon, has_modifiers = false;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  cp_parser_parse_tentatively (parser);
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
  parser->colon_corrects_to_scope_p = false;
  for (int mod = 0; mod < 2; mod++)
    if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
      {
	tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	const char *p = IDENTIFIER_POINTER (id);
	if (strcmp (p, "allocator") != 0 && strcmp (p, "align") != 0)
	  break;
	cp_lexer_consume_token (parser->lexer);
	matching_parens parens2;
	if (!parens2.require_open (parser))
	  break;
	if (strcmp (p, "allocator") == 0)
	  {
	    if (allocator != NULL_TREE)
	      break;
	    allocator = cp_parser_assignment_expression (parser);
	  }
	else
	  {
	    if (align != NULL_TREE)
	      break;
	    align = cp_parser_assignment_expression (parser);
	  }
	if (!parens2.require_close (parser))
	  break;
	if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
	  {
	    has_modifiers = true;
	    break;
	  }
	if (mod != 0 || cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA))
	  break;
	cp_lexer_consume_token (parser->lexer);
      }
    else
      break;
  if (!has_modifiers)
    {
      cp_parser_abort_tentative_parse (parser);
      align = NULL_TREE;
      allocator = NULL_TREE;
      cp_parser_parse_tentatively (parser);
      allocator = cp_parser_assignment_expression (parser);
    }
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
  if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      cp_parser_parse_definitely (parser);
      cp_lexer_consume_token (parser->lexer);
      if (allocator == error_mark_node)
	allocator = NULL_TREE;
      if (align == error_mark_node)
	align = NULL_TREE;
    }
  else
    {
      cp_parser_abort_tentative_parse (parser);
      allocator = NULL_TREE;
      align = NULL_TREE;
    }

  nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALLOCATE, list,
					  &colon);

  if (allocator || align)
    for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
      {
	OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;
	OMP_CLAUSE_ALLOCATE_ALIGN (c) = align;
      }

  return nlist;
}

/* OpenMP 2.5:
   lastprivate ( variable-list )

   OpenMP 5.0:
   lastprivate ( [ lastprivate-modifier : ] variable-list )  */

static tree
cp_parser_omp_clause_lastprivate (cp_parser *parser, tree list)
{
  bool conditional = false;

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp ("conditional", p) == 0)
	{
	  conditional = true;
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	}
    }

  tree nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LASTPRIVATE,
					       list, NULL);

  if (conditional)
    for (tree c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
      OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) = 1;
  return nlist;
}

/* OpenMP 4.0:
   linear ( variable-list )
   linear ( variable-list : expression )

   OpenMP 4.5:
   linear ( modifier ( variable-list ) )
   linear ( modifier ( variable-list ) : expression )

   modifier:
     val
     ref
     uval

   OpenMP 5.2:
   linear ( variable-list : modifiers-list )

   modifiers:
     val
     ref
     uval
     step ( expression )  */

static tree
cp_parser_omp_clause_linear (cp_parser *parser, tree list,
			     bool declare_simd)
{
  tree nlist, c, step = integer_one_node;
  bool colon;
  enum omp_clause_linear_kind kind = OMP_CLAUSE_LINEAR_DEFAULT;
  bool old_linear_modifier = false;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp ("ref", p) == 0)
	kind = OMP_CLAUSE_LINEAR_REF;
      else if (strcmp ("val", p) == 0)
	kind = OMP_CLAUSE_LINEAR_VAL;
      else if (strcmp ("uval", p) == 0)
	kind = OMP_CLAUSE_LINEAR_UVAL;
      if (cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
	{
	  cp_lexer_consume_token (parser->lexer);
	  old_linear_modifier = true;
	}
      else
	kind = OMP_CLAUSE_LINEAR_DEFAULT;
    }

  if (kind == OMP_CLAUSE_LINEAR_DEFAULT)
    nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_LINEAR, list,
					    &colon);
  else
    {
      nlist = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINEAR, list);
      colon = cp_lexer_next_token_is (parser->lexer, CPP_COLON);
      if (colon)
	cp_parser_require (parser, CPP_COLON, RT_COLON);
      else if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);
    }

  if (colon)
    {
      bool has_modifiers = false;
      if (kind == OMP_CLAUSE_LINEAR_DEFAULT
	  && cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  const char *p = IDENTIFIER_POINTER (id);
	  size_t pos = 0;
	  if (strcmp ("ref", p) == 0
	      || strcmp ("val", p) == 0
	      || strcmp ("uval", p) == 0)
	    pos = 2;
	  else if (strcmp ("step", p) == 0
		   && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
	    {
	      pos = cp_parser_skip_balanced_tokens (parser, 2);
	      if (pos == 2)
		pos = 0;
	    }
	  if (pos != 0
	      && (cp_lexer_nth_token_is (parser->lexer, pos, CPP_COMMA)
		  || cp_lexer_nth_token_is (parser->lexer, pos,
					    CPP_CLOSE_PAREN)))
	    has_modifiers = true;
	}

      step = NULL_TREE;
      if (has_modifiers)
	{
	  while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	    {
	      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	      const char *p = IDENTIFIER_POINTER (id);
	      enum omp_clause_linear_kind nkind = OMP_CLAUSE_LINEAR_DEFAULT;
	      if (strcmp ("ref", p) == 0)
		nkind = OMP_CLAUSE_LINEAR_REF;
	      else if (strcmp ("val", p) == 0)
		nkind = OMP_CLAUSE_LINEAR_VAL;
	      else if (strcmp ("uval", p) == 0)
		nkind = OMP_CLAUSE_LINEAR_UVAL;
	      if (nkind != OMP_CLAUSE_LINEAR_DEFAULT)
		{
		  if (kind != OMP_CLAUSE_LINEAR_DEFAULT)
		    error_at (cp_lexer_peek_token (parser->lexer)->location,
			      "multiple linear modifiers");
		  kind = nkind;
		  cp_lexer_consume_token (parser->lexer);
		}
	      else if (strcmp ("step", p) == 0)
		{
		  location_t step_loc
		    = cp_lexer_peek_token (parser->lexer)->location;
		  cp_lexer_consume_token (parser->lexer);
		  matching_parens parens2;
		  if (parens2.require_open (parser))
		    {
		      if (step)
			error_at (step_loc, "multiple %<step%> modifiers");
		      if (declare_simd
			  && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
			  && cp_lexer_nth_token_is (parser->lexer, 2,
						    CPP_CLOSE_PAREN))
			{
			  cp_token *token
			    = cp_lexer_peek_token (parser->lexer);
			  location_t tok_loc = token->location;
			  cp_parser_parse_tentatively (parser);
			  step = cp_parser_id_expression (parser, false, true,
							  NULL, false, false);
			  if (step != error_mark_node)
			    step = cp_parser_lookup_name_simple (parser, step,
								 tok_loc);
			  if (step == error_mark_node)
			    {
			      step = NULL_TREE;
			      cp_parser_abort_tentative_parse (parser);
			    }
			  else if (!cp_parser_parse_definitely (parser))
			    step = NULL_TREE;
			}
		      if (!step)
			step = cp_parser_assignment_expression (parser);
		      if (!parens2.require_close (parser))
			cp_parser_skip_to_closing_parenthesis (parser, true,
							       false, true);
		    }
		  else
		    break;
		}
	      else
		break;
	      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
		{
		  cp_lexer_consume_token (parser->lexer);
		  continue;
		}
	      break;
	    }
	  if (!step)
	    step = integer_one_node;
	}
      else if (declare_simd
	       && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	       && cp_lexer_nth_token_is (parser->lexer, 2, CPP_CLOSE_PAREN))
	{
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  cp_parser_parse_tentatively (parser);
	  step = cp_parser_id_expression (parser, /*template_p=*/false,
					  /*check_dependency_p=*/true,
					  /*template_p=*/NULL,
					  /*declarator_p=*/false,
					  /*optional_p=*/false);
	  if (step != error_mark_node)
	    step = cp_parser_lookup_name_simple (parser, step, token->location);
	  if (step == error_mark_node)
	    {
	      step = NULL_TREE;
	      cp_parser_abort_tentative_parse (parser);
	    }
	  else if (!cp_parser_parse_definitely (parser))
	    step = NULL_TREE;
	}
      if (!step)
	step = cp_parser_assignment_expression (parser);

      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);

      if (step == error_mark_node)
	return list;
    }

  for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
    {
      OMP_CLAUSE_LINEAR_STEP (c) = step;
      OMP_CLAUSE_LINEAR_KIND (c) = kind;
      OMP_CLAUSE_LINEAR_OLD_LINEAR_MODIFIER (c) = old_linear_modifier;
    }

  return nlist;
}

/* OpenMP 4.0:
   safelen ( constant-expression )  */

static tree
cp_parser_omp_clause_safelen (cp_parser *parser, tree list,
			      location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_constant_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_SAFELEN, "safelen", location);

  c = build_omp_clause (location, OMP_CLAUSE_SAFELEN);
  OMP_CLAUSE_SAFELEN_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.0:
   simdlen ( constant-expression )  */

static tree
cp_parser_omp_clause_simdlen (cp_parser *parser, tree list,
			      location_t location)
{
  tree t, c;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  t = cp_parser_constant_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_SIMDLEN, "simdlen", location);

  c = build_omp_clause (location, OMP_CLAUSE_SIMDLEN);
  OMP_CLAUSE_SIMDLEN_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   vec:
     identifier [+/- integer]
     vec , identifier [+/- integer]
*/

static tree
cp_parser_omp_clause_doacross_sink (cp_parser *parser, location_t clause_loc,
				    tree list, bool depend_p)
{
  tree vec = NULL;

  if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
    {
      cp_parser_error (parser, "expected identifier");
      return list;
    }

  if (!depend_p)
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      if (strcmp (IDENTIFIER_POINTER (id), "omp_cur_iteration") == 0
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_MINUS)
	  && cp_lexer_nth_token_is (parser->lexer, 3, CPP_NUMBER)
	  && cp_lexer_nth_token_is (parser->lexer, 4, CPP_CLOSE_PAREN))
	{
	  tree val = cp_lexer_peek_nth_token (parser->lexer, 3)->u.value;
	  if (integer_onep (val))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	      tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
	      OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
	      OMP_CLAUSE_CHAIN (u) = list;
	      return u;
	    }
	}
    }

  while (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      location_t id_loc = cp_lexer_peek_token (parser->lexer)->location;
      tree t, identifier = cp_parser_identifier (parser);
      tree addend = NULL;

      if (identifier == error_mark_node)
	t = error_mark_node;
      else
	{
	  t = cp_parser_lookup_name_simple
		(parser, identifier,
		 cp_lexer_peek_token (parser->lexer)->location);
	  if (t == error_mark_node)
	    cp_parser_name_lookup_error (parser, identifier, t, NLE_NULL,
					 id_loc);
	}

      bool neg = false;
      if (cp_lexer_next_token_is (parser->lexer, CPP_MINUS))
	neg = true;
      else if (!cp_lexer_next_token_is (parser->lexer, CPP_PLUS))
	{
	  addend = integer_zero_node;
	  goto add_to_vector;
	}
      cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is_not (parser->lexer, CPP_NUMBER))
	{
	  cp_parser_error (parser, "expected integer");
	  return list;
	}

      addend = cp_lexer_peek_token (parser->lexer)->u.value;
      if (TREE_CODE (addend) != INTEGER_CST)
	{
	  cp_parser_error (parser, "expected integer");
	  return list;
	}
      cp_lexer_consume_token (parser->lexer);

    add_to_vector:
      if (t != error_mark_node)
	{
	  vec = tree_cons (addend, t, vec);
	  if (neg)
	    OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (vec) = 1;
	}

      if (cp_lexer_next_token_is_not (parser->lexer, CPP_COMMA)
	  || !cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	break;

      cp_lexer_consume_token (parser->lexer);
    }

  if (vec)
    {
      tree u = build_omp_clause (clause_loc, OMP_CLAUSE_DOACROSS);
      OMP_CLAUSE_DOACROSS_KIND (u) = OMP_CLAUSE_DOACROSS_SINK;
      OMP_CLAUSE_DOACROSS_DEPEND (u) = depend_p;
      OMP_CLAUSE_DECL (u) = nreverse (vec);
      OMP_CLAUSE_CHAIN (u) = list;
      return u;
    }
  return list;
}

/* OpenMP 5.0:
   detach ( event-handle ) */

static tree
cp_parser_omp_clause_detach (cp_parser *parser, tree list)
{
  matching_parens parens;

  if (!parens.require_open (parser))
    return list;

  cp_token *token;
  tree name, decl;

  token = cp_lexer_peek_token (parser->lexer);
  name = cp_parser_id_expression (parser, /*template_p=*/false,
					  /*check_dependency_p=*/true,
					  /*template_p=*/NULL,
					  /*declarator_p=*/false,
					  /*optional_p=*/false);
  if (name == error_mark_node)
    decl = error_mark_node;
  else
    {
      if (identifier_p (name))
	decl = cp_parser_lookup_name_simple (parser, name, token->location);
      else
	decl = name;
      if (decl == error_mark_node)
	cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
				     token->location);
    }

  if (decl == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  tree u = build_omp_clause (token->location, OMP_CLAUSE_DETACH);
  OMP_CLAUSE_DECL (u) = decl;
  OMP_CLAUSE_CHAIN (u) = list;

  return u;
}

/* OpenMP 5.0:
   iterators ( iterators-definition )

   iterators-definition:
     iterator-specifier
     iterator-specifier , iterators-definition

   iterator-specifier:
     identifier = range-specification
     iterator-type identifier = range-specification

   range-specification:
     begin : end
     begin : end : step  */

static tree
cp_parser_omp_iterators (cp_parser *parser)
{
  tree ret = NULL_TREE, *last = &ret;
  cp_lexer_consume_token (parser->lexer);

  matching_parens parens;
  if (!parens.require_open (parser))
    return error_mark_node;

  bool saved_colon_corrects_to_scope_p
    = parser->colon_corrects_to_scope_p;
  bool saved_colon_doesnt_start_class_def_p
    = parser->colon_doesnt_start_class_def_p;

  do
    {
      tree iter_type;
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_EQ))
	iter_type = integer_type_node;
      else
	{
	  const char *saved_message
	    = parser->type_definition_forbidden_message;
	  parser->type_definition_forbidden_message
	    = G_("types may not be defined in iterator type");

	  iter_type = cp_parser_type_id (parser);

	  parser->type_definition_forbidden_message = saved_message;
	}

      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
	{
	  cp_parser_error (parser, "expected identifier");
	  break;
	}

      tree id = cp_parser_identifier (parser);
      if (id == error_mark_node)
	break;

      if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
	break;

      parser->colon_corrects_to_scope_p = false;
      parser->colon_doesnt_start_class_def_p = true;
      tree begin = cp_parser_assignment_expression (parser);

      if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
	break;

      tree end = cp_parser_assignment_expression (parser);

      tree step = integer_one_node;
      if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
	{
	  cp_lexer_consume_token (parser->lexer);
	  step = cp_parser_assignment_expression (parser);
	}

      tree iter_var = build_decl (loc, VAR_DECL, id, iter_type);
      DECL_ARTIFICIAL (iter_var) = 1;
      DECL_CONTEXT (iter_var) = current_function_decl;
      pushdecl (iter_var);

      *last = make_tree_vec (6);
      TREE_VEC_ELT (*last, 0) = iter_var;
      TREE_VEC_ELT (*last, 1) = begin;
      TREE_VEC_ELT (*last, 2) = end;
      TREE_VEC_ELT (*last, 3) = step;
      last = &TREE_CHAIN (*last);

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	{
	  cp_lexer_consume_token (parser->lexer);
	  continue;
	}
      break;
    }
  while (1);

  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
  parser->colon_doesnt_start_class_def_p
    = saved_colon_doesnt_start_class_def_p;

  if (!parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser,
					   /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  return ret ? ret : error_mark_node;
}

/* OpenMP 5.0:
   affinity ( [aff-modifier :] variable-list )
   aff-modifier:
     iterator ( iterators-definition )  */

static tree
cp_parser_omp_clause_affinity (cp_parser *parser, tree list)
{
  tree nlist, c, iterators = NULL_TREE;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      bool parse_iter = ((strcmp ("iterator", p) == 0)
			 && (cp_lexer_nth_token_is (parser->lexer, 2,
						    CPP_OPEN_PAREN)));
      if (parse_iter)
	{
	  size_t n = cp_parser_skip_balanced_tokens (parser, 2);
	  parse_iter = cp_lexer_nth_token_is (parser->lexer, n, CPP_COLON);
	}
      if (parse_iter)
	{
	  begin_scope (sk_omp, NULL);
	  iterators = cp_parser_omp_iterators (parser);
	  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
	    {
	      if (iterators)
		poplevel (0, 1, 0);
	      cp_parser_skip_to_closing_parenthesis (parser,
						     /*recovering=*/true,
						     /*or_comma=*/false,
						     /*consume_paren=*/true);
	      return list;
	    }
	}
    }
  nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_AFFINITY,
					  list, NULL);
  if (iterators)
    {
      tree block = poplevel (1, 1, 0);
      if (iterators != error_mark_node)
	{
	  TREE_VEC_ELT (iterators, 5) = block;
	  for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
	    OMP_CLAUSE_DECL (c) = build_tree_list (iterators,
						   OMP_CLAUSE_DECL (c));
	}
    }
  return nlist;
}

/* OpenMP 4.0:
   depend ( depend-kind : variable-list )

   depend-kind:
     in | out | inout

   OpenMP 4.5:
   depend ( source )

   depend ( sink : vec )

   OpenMP 5.0:
   depend ( depend-modifier , depend-kind: variable-list )

   depend-kind:
     in | out | inout | mutexinoutset | depobj

   depend-modifier:
     iterator ( iterators-definition )  */

static tree
cp_parser_omp_clause_depend (cp_parser *parser, tree list, location_t loc)
{
  tree nlist, c, iterators = NULL_TREE;
  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_LAST;
  enum omp_clause_doacross_kind dkind = OMP_CLAUSE_DOACROSS_LAST;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  do
    {
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
	goto invalid_kind;

      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp ("iterator", p) == 0 && iterators == NULL_TREE)
	{
	  begin_scope (sk_omp, NULL);
	  iterators = cp_parser_omp_iterators (parser);
	  cp_parser_require (parser, CPP_COMMA, RT_COMMA);
	  continue;
	}
      if (strcmp ("in", p) == 0)
	kind = OMP_CLAUSE_DEPEND_IN;
      else if (strcmp ("inout", p) == 0)
	kind = OMP_CLAUSE_DEPEND_INOUT;
      else if (strcmp ("inoutset", p) == 0)
	kind = OMP_CLAUSE_DEPEND_INOUTSET;
      else if (strcmp ("mutexinoutset", p) == 0)
	kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
      else if (strcmp ("out", p) == 0)
	kind = OMP_CLAUSE_DEPEND_OUT;
      else if (strcmp ("depobj", p) == 0)
	kind = OMP_CLAUSE_DEPEND_DEPOBJ;
      else if (strcmp ("sink", p) == 0)
	dkind = OMP_CLAUSE_DOACROSS_SINK;
      else if (strcmp ("source", p) == 0)
	dkind = OMP_CLAUSE_DOACROSS_SOURCE;
      else
	goto invalid_kind;
      break;
    }
  while (1);

  cp_lexer_consume_token (parser->lexer);

  if (iterators
      && (dkind == OMP_CLAUSE_DOACROSS_SOURCE
	  || dkind == OMP_CLAUSE_DOACROSS_SINK))
    {
      poplevel (0, 1, 0);
      error_at (loc, "%<iterator%> modifier incompatible with %qs",
		dkind == OMP_CLAUSE_DOACROSS_SOURCE ? "source" : "sink");
      iterators = NULL_TREE;
    }

  if (dkind == OMP_CLAUSE_DOACROSS_SOURCE)
    {
      c = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
      OMP_CLAUSE_DOACROSS_KIND (c) = dkind;
      OMP_CLAUSE_DOACROSS_DEPEND (c) = 1;
      OMP_CLAUSE_DECL (c) = NULL_TREE;
      OMP_CLAUSE_CHAIN (c) = list;
      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);
      return c;
    }

  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
    goto resync_fail;

  if (dkind == OMP_CLAUSE_DOACROSS_SINK)
    {
      nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, true);
      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);
    }
  else
    {
      nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_DEPEND,
					      list, NULL);

      if (iterators)
	{
	  tree block = poplevel (1, 1, 0);
	  if (iterators == error_mark_node)
	    iterators = NULL_TREE;
	  else
	    TREE_VEC_ELT (iterators, 5) = block;
	}

      for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
	{
	  OMP_CLAUSE_DEPEND_KIND (c) = kind;
	  if (iterators)
	    OMP_CLAUSE_DECL (c)
	      = build_tree_list (iterators, OMP_CLAUSE_DECL (c));
	}
    }
  return nlist;

 invalid_kind:
  cp_parser_error (parser, "invalid depend kind");
 resync_fail:
  if (iterators)
    poplevel (0, 1, 0);
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 5.2:
   doacross ( source : )
   doacross ( source : omp_cur_iteration )

   doacross ( sink : vec )
   doacross ( sink : omp_cur_iteration - logical_iteration )  */

static tree
cp_parser_omp_clause_doacross (cp_parser *parser, tree list, location_t loc)
{
  tree nlist;
  enum omp_clause_doacross_kind kind = OMP_CLAUSE_DOACROSS_LAST;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
    {
    invalid_kind:
      cp_parser_error (parser, "invalid doacross kind");
    resync_fail:
      cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					     /*or_comma=*/false,
					     /*consume_paren=*/true);
      return list;
    }

  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
  const char *p = IDENTIFIER_POINTER (id);

  if (strcmp ("sink", p) == 0)
    kind = OMP_CLAUSE_DOACROSS_SINK;
  else if (strcmp ("source", p) == 0)
    kind = OMP_CLAUSE_DOACROSS_SOURCE;
  else
    goto invalid_kind;

  cp_lexer_consume_token (parser->lexer);

  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
    goto resync_fail;

  if (kind == OMP_CLAUSE_DOACROSS_SOURCE)
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  id = cp_lexer_peek_token (parser->lexer)->u.value;
	  p = IDENTIFIER_POINTER (id);
	  if (strcmp (p, "omp_cur_iteration") == 0)
	    cp_lexer_consume_token (parser->lexer);
	}
      nlist = build_omp_clause (loc, OMP_CLAUSE_DOACROSS);
      OMP_CLAUSE_DOACROSS_KIND (nlist) = OMP_CLAUSE_DOACROSS_SOURCE;
      OMP_CLAUSE_DECL (nlist) = NULL_TREE;
      OMP_CLAUSE_CHAIN (nlist) = list;
    }
  else
    nlist = cp_parser_omp_clause_doacross_sink (parser, loc, list, false);

  if (!parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);
  return nlist;
}

/* OpenMP 4.0:
   map ( map-kind : variable-list )
   map ( variable-list )

   map-kind:
     alloc | to | from | tofrom

   OpenMP 4.5:
   map-kind:
     alloc | to | from | tofrom | release | delete

   map ( always [,] map-kind: variable-list )

   OpenMP 5.0:
   map ( [map-type-modifier[,] ...] map-kind: variable-list )

   map-type-modifier:
     always | close */

static tree
cp_parser_omp_clause_map (cp_parser *parser, tree list)
{
  tree nlist, c;
  enum gomp_map_kind kind = GOMP_MAP_TOFROM;

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return list;

  int pos = 1;
  int map_kind_pos = 0;
  while (cp_lexer_peek_nth_token (parser->lexer, pos)->type == CPP_NAME
	 || cp_lexer_peek_nth_token (parser->lexer, pos)->keyword == RID_DELETE)
    {
      if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COLON)
	{
	  map_kind_pos = pos;
	  break;
	}

      if (cp_lexer_peek_nth_token (parser->lexer, pos + 1)->type == CPP_COMMA)
	pos++;
      pos++;
    }

  bool always_modifier = false;
  bool close_modifier = false;
  for (int pos = 1; pos < map_kind_pos; ++pos)
    {
      cp_token *tok = cp_lexer_peek_token (parser->lexer);
      if (tok->type == CPP_COMMA)
	{
	  cp_lexer_consume_token (parser->lexer);
	  continue;
	}

      const char *p = IDENTIFIER_POINTER (tok->u.value);
      if (strcmp ("always", p) == 0)
	{
	  if (always_modifier)
	    {
	      cp_parser_error (parser, "too many %<always%> modifiers");
	      cp_parser_skip_to_closing_parenthesis (parser,
						     /*recovering=*/true,
						     /*or_comma=*/false,
						     /*consume_paren=*/true);
	      return list;
	    }
	  always_modifier = true;
	}
      else if (strcmp ("close", p) == 0)
	{
	  if (close_modifier)
	    {
	      cp_parser_error (parser, "too many %<close%> modifiers");
	      cp_parser_skip_to_closing_parenthesis (parser,
						     /*recovering=*/true,
						     /*or_comma=*/false,
						     /*consume_paren=*/true);
	      return list;
	    }
	  close_modifier = true;
	}
      else
	{
	  cp_parser_error (parser, "%<#pragma omp target%> with "
				   "modifier other than %<always%> or "
				   "%<close%> on %<map%> clause");
	  cp_parser_skip_to_closing_parenthesis (parser,
						 /*recovering=*/true,
						 /*or_comma=*/false,
						 /*consume_paren=*/true);
	  return list;
	}

	cp_lexer_consume_token (parser->lexer);
    }

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp ("alloc", p) == 0)
	kind = GOMP_MAP_ALLOC;
      else if (strcmp ("to", p) == 0)
	kind = always_modifier ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
      else if (strcmp ("from", p) == 0)
	kind = always_modifier ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
      else if (strcmp ("tofrom", p) == 0)
	kind = always_modifier ? GOMP_MAP_ALWAYS_TOFROM : GOMP_MAP_TOFROM;
      else if (strcmp ("release", p) == 0)
	kind = GOMP_MAP_RELEASE;
      else
	{
	  cp_parser_error (parser, "invalid map kind");
	  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
						 /*or_comma=*/false,
						 /*consume_paren=*/true);
	  return list;
	}
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
    }
  else if (cp_lexer_next_token_is_keyword (parser->lexer, RID_DELETE)
	   && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COLON)
    {
      kind = GOMP_MAP_DELETE;
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
    }

  nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_MAP, list,
					  NULL, true);

  for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
    OMP_CLAUSE_SET_MAP_KIND (c, kind);

  return nlist;
}

/* OpenMP 4.0:
   device ( expression )

   OpenMP 5.0:
   device ( [device-modifier :] integer-expression )

   device-modifier:
     ancestor | device_num */

static tree
cp_parser_omp_clause_device (cp_parser *parser, tree list,
			     location_t location)
{
  tree t, c;
  bool ancestor = false;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_COLON))
    {
      cp_token *tok = cp_lexer_peek_token (parser->lexer);
      const char *p = IDENTIFIER_POINTER (tok->u.value);
      if (strcmp ("ancestor", p) == 0)
	{
	  ancestor = true;

	  /* A requires directive with the reverse_offload clause must be
	  specified.  */
	  if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0)
	    {
	      error_at (tok->location, "%<ancestor%> device modifier not "
				       "preceded by %<requires%> directive "
				       "with %<reverse_offload%> clause");
	      cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
	      return list;
	    }
	}
      else if (strcmp ("device_num", p) == 0)
	;
      else
	{
	  error_at (tok->location, "expected %<ancestor%> or %<device_num%>");
	  cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
	  return list;
	}
      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);
    }

  t = cp_parser_assignment_expression (parser);

  if (t == error_mark_node
      || !parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE,
			     "device", location);

  c = build_omp_clause (location, OMP_CLAUSE_DEVICE);
  OMP_CLAUSE_DEVICE_ID (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;
  OMP_CLAUSE_DEVICE_ANCESTOR (c) = ancestor;

  return c;
}

/* OpenMP 4.0:
   dist_schedule ( static )
   dist_schedule ( static , expression )  */

static tree
cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
				    location_t location)
{
  tree c, t;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

  c = build_omp_clause (location, OMP_CLAUSE_DIST_SCHEDULE);

  if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_STATIC))
    goto invalid_kind;
  cp_lexer_consume_token (parser->lexer);

  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
    {
      cp_lexer_consume_token (parser->lexer);

      t = cp_parser_assignment_expression (parser);

      if (t == error_mark_node)
	goto resync_fail;
      OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (c) = t;

      if (!parens.require_close (parser))
	goto resync_fail;
    }
  else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
    goto resync_fail;

  /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
				"dist_schedule", location); */
  if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
    warning_at (location, 0, "too many %qs clauses", "dist_schedule");
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 invalid_kind:
  cp_parser_error (parser, "invalid dist_schedule kind");
 resync_fail:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 4.0:
   proc_bind ( proc-bind-kind )

   proc-bind-kind:
     primary | master | close | spread
   where OpenMP 5.1 added 'primary' and deprecated the alias 'master'.  */

static tree
cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
				location_t location)
{
  tree c;
  enum omp_clause_proc_bind_kind kind;

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp ("primary", p) == 0)
	kind = OMP_CLAUSE_PROC_BIND_PRIMARY;
      else if (strcmp ("master", p) == 0)
	kind = OMP_CLAUSE_PROC_BIND_MASTER;
      else if (strcmp ("close", p) == 0)
	kind = OMP_CLAUSE_PROC_BIND_CLOSE;
      else if (strcmp ("spread", p) == 0)
	kind = OMP_CLAUSE_PROC_BIND_SPREAD;
      else
	goto invalid_kind;
    }
  else
    goto invalid_kind;

  cp_lexer_consume_token (parser->lexer);
  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
    goto resync_fail;

  c = build_omp_clause (location, OMP_CLAUSE_PROC_BIND);
  check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind",
			     location);
  OMP_CLAUSE_PROC_BIND_KIND (c) = kind;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 invalid_kind:
  cp_parser_error (parser, "invalid depend kind");
 resync_fail:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenMP 5.0:
   device_type ( host | nohost | any )  */

static tree
cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
				  location_t location)
{
  tree c;
  enum omp_clause_device_type_kind kind;

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return list;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp ("host", p) == 0)
	kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
      else if (strcmp ("nohost", p) == 0)
	kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
      else if (strcmp ("any", p) == 0)
	kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
      else
	goto invalid_kind;
    }
  else
    goto invalid_kind;

  cp_lexer_consume_token (parser->lexer);
  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
    goto resync_fail;

  c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
  check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
			     location);
  OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
  OMP_CLAUSE_CHAIN (c) = list;
  return c;

 invalid_kind:
  cp_parser_error (parser, "invalid depend kind");
 resync_fail:
  cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					 /*or_comma=*/false,
					 /*consume_paren=*/true);
  return list;
}

/* OpenACC:
   async [( int-expr )] */

static tree
cp_parser_oacc_clause_async (cp_parser *parser, tree list)
{
  tree c, t;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  t = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);

  if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
    {
      matching_parens parens;
      parens.consume_open (parser);

      t = cp_parser_assignment_expression (parser);
      if (t == error_mark_node
	  || !parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
						/*or_comma=*/false,
						/*consume_paren=*/true);
    }

  check_no_duplicate_clause (list, OMP_CLAUSE_ASYNC, "async", loc);

  c = build_omp_clause (loc, OMP_CLAUSE_ASYNC);
  OMP_CLAUSE_ASYNC_EXPR (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;
  list = c;

  return list;
}

/* Parse all OpenACC clauses.  The set clauses allowed by the directive
   is a bitmask in MASK.  Return the list of clauses found.  */

static tree
cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
			    const char *where, cp_token *pragma_tok,
			    bool finish_p = true)
{
  tree clauses = NULL;
  bool first = true;

  /* Don't create location wrapper nodes within OpenACC clauses.  */
  auto_suppress_location_wrappers sentinel;

  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      location_t here;
      pragma_omp_clause c_kind;
      omp_clause_code code;
      const char *c_name;
      tree prev = clauses;

      if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);

      here = cp_lexer_peek_token (parser->lexer)->location;
      c_kind = cp_parser_omp_clause_name (parser);

      switch (c_kind)
	{
	case PRAGMA_OACC_CLAUSE_ASYNC:
	  clauses = cp_parser_oacc_clause_async (parser, clauses);
	  c_name = "async";
	  break;
	case PRAGMA_OACC_CLAUSE_AUTO:
	  clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
						  clauses);
	  c_name = "auto";
	  break;
	case PRAGMA_OACC_CLAUSE_ATTACH:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "attach";
	  break;
	case PRAGMA_OACC_CLAUSE_COLLAPSE:
	  clauses = cp_parser_omp_clause_collapse (parser, clauses, here);
	  c_name = "collapse";
	  break;
	case PRAGMA_OACC_CLAUSE_COPY:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "copy";
	  break;
	case PRAGMA_OACC_CLAUSE_COPYIN:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "copyin";
	  break;
	case PRAGMA_OACC_CLAUSE_COPYOUT:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "copyout";
	  break;
	case PRAGMA_OACC_CLAUSE_CREATE:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "create";
	  break;
	case PRAGMA_OACC_CLAUSE_DELETE:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "delete";
	  break;
	case PRAGMA_OMP_CLAUSE_DEFAULT:
	  clauses = cp_parser_omp_clause_default (parser, clauses, here, true);
	  c_name = "default";
	  break;
	case PRAGMA_OACC_CLAUSE_DETACH:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "detach";
	  break;
	case PRAGMA_OACC_CLAUSE_DEVICE:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "device";
	  break;
	case PRAGMA_OACC_CLAUSE_DEVICEPTR:
	  clauses = cp_parser_oacc_data_clause_deviceptr (parser, clauses);
	  c_name = "deviceptr";
	  break;
	case PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "device_resident";
	  break;
	case PRAGMA_OACC_CLAUSE_FINALIZE:
	  clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
						  clauses);
	  c_name = "finalize";
	  break;
	case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
					    clauses);
	  c_name = "firstprivate";
	  break;
	case PRAGMA_OACC_CLAUSE_GANG:
	  c_name = "gang";
	  clauses = cp_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
						 c_name, clauses);
	  break;
	case PRAGMA_OACC_CLAUSE_HOST:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "host";
	  break;
	case PRAGMA_OACC_CLAUSE_IF:
	  clauses = cp_parser_omp_clause_if (parser, clauses, here, false);
	  c_name = "if";
	  break;
	case PRAGMA_OACC_CLAUSE_IF_PRESENT:
	  clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
						  clauses);
	  c_name = "if_present";
	  break;
	case PRAGMA_OACC_CLAUSE_INDEPENDENT:
	  clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
						  clauses);
	  c_name = "independent";
	  break;
	case PRAGMA_OACC_CLAUSE_LINK:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "link";
	  break;
	case PRAGMA_OACC_CLAUSE_NO_CREATE:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "no_create";
	  break;
	case PRAGMA_OACC_CLAUSE_NOHOST:
	  clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_NOHOST,
						  clauses);
	  c_name = "nohost";
	  break;
	case PRAGMA_OACC_CLAUSE_NUM_GANGS:
	  code = OMP_CLAUSE_NUM_GANGS;
	  c_name = "num_gangs";
	  clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
						      clauses);
	  break;
	case PRAGMA_OACC_CLAUSE_NUM_WORKERS:
	  c_name = "num_workers";
	  code = OMP_CLAUSE_NUM_WORKERS;
	  clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
						      clauses);
	  break;
	case PRAGMA_OACC_CLAUSE_PRESENT:
	  clauses = cp_parser_oacc_data_clause (parser, c_kind, clauses);
	  c_name = "present";
	  break;
	case PRAGMA_OACC_CLAUSE_PRIVATE:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
					    clauses);
	  c_name = "private";
	  break;
	case PRAGMA_OACC_CLAUSE_REDUCTION:
	  clauses
	    = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
					      false, clauses);
	  c_name = "reduction";
	  break;
	case PRAGMA_OACC_CLAUSE_SEQ:
	  clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
						  clauses);
	  c_name = "seq";
	  break;
	case PRAGMA_OACC_CLAUSE_TILE:
	  clauses = cp_parser_oacc_clause_tile (parser, here, clauses);
	  c_name = "tile";
	  break;
	case PRAGMA_OACC_CLAUSE_USE_DEVICE:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_PTR,
					    clauses);
	  c_name = "use_device";
	  break;
	case PRAGMA_OACC_CLAUSE_VECTOR:
	  c_name = "vector";
	  clauses = cp_parser_oacc_shape_clause (parser, here,
						 OMP_CLAUSE_VECTOR,
						 c_name, clauses);
	  break;
	case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
	  c_name = "vector_length";
	  code = OMP_CLAUSE_VECTOR_LENGTH;
	  clauses = cp_parser_oacc_single_int_clause (parser, code, c_name,
						      clauses);
	  break;
	case PRAGMA_OACC_CLAUSE_WAIT:
	  clauses = cp_parser_oacc_clause_wait (parser, clauses);
	  c_name = "wait";
	  break;
	case PRAGMA_OACC_CLAUSE_WORKER:
	  c_name = "worker";
	  clauses = cp_parser_oacc_shape_clause (parser, here,
						 OMP_CLAUSE_WORKER,
						 c_name, clauses);
	  break;
	default:
	  cp_parser_error (parser, "expected %<#pragma acc%> clause");
	  goto saw_error;
	}

      first = false;

      if (((mask >> c_kind) & 1) == 0)
	{
	  /* Remove the invalid clause(s) from the list to avoid
	     confusing the rest of the compiler.  */
	  clauses = prev;
	  error_at (here, "%qs is not valid for %qs", c_name, where);
	}
    }

 saw_error:
  cp_parser_skip_to_pragma_eol (parser, pragma_tok);

  if (finish_p)
    return finish_omp_clauses (clauses, C_ORT_ACC);

  return clauses;
}

/* Parse all OpenMP clauses.  The set clauses allowed by the directive
   is a bitmask in MASK.  Return the list of clauses found.
   FINISH_P set if finish_omp_clauses should be called.
   NESTED non-zero if clauses should be terminated by closing paren instead
   of end of pragma.  If it is 2, additionally commas are required in between
   the clauses.  */

static tree
cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
			   const char *where, cp_token *pragma_tok,
			   bool finish_p = true, int nested = 0)
{
  tree clauses = NULL;
  bool first = true;
  cp_token *token = NULL;

  /* Don't create location wrapper nodes within OpenMP clauses.  */
  auto_suppress_location_wrappers sentinel;

  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      pragma_omp_clause c_kind;
      const char *c_name;
      tree prev = clauses;

      if (nested && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN))
	break;

      if (!first || nested != 2)
	{
	  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	    cp_lexer_consume_token (parser->lexer);
	  else if (nested == 2)
	    error_at (cp_lexer_peek_token (parser->lexer)->location,
		      "clauses in %<simd%> trait should be separated "
                      "by %<,%>");
	}

      token = cp_lexer_peek_token (parser->lexer);
      c_kind = cp_parser_omp_clause_name (parser);

      switch (c_kind)
	{
	case PRAGMA_OMP_CLAUSE_BIND:
	  clauses = cp_parser_omp_clause_bind (parser, clauses,
					       token->location);
	  c_name = "bind";
	  break;
	case PRAGMA_OMP_CLAUSE_COLLAPSE:
	  clauses = cp_parser_omp_clause_collapse (parser, clauses,
						   token->location);
	  c_name = "collapse";
	  break;
	case PRAGMA_OMP_CLAUSE_COPYIN:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_COPYIN, clauses);
	  c_name = "copyin";
	  break;
	case PRAGMA_OMP_CLAUSE_COPYPRIVATE:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_COPYPRIVATE,
					    clauses);
	  c_name = "copyprivate";
	  break;
	case PRAGMA_OMP_CLAUSE_DEFAULT:
	  clauses = cp_parser_omp_clause_default (parser, clauses,
						  token->location, false);
	  c_name = "default";
	  break;
	case PRAGMA_OMP_CLAUSE_FILTER:
	  clauses = cp_parser_omp_clause_filter (parser, clauses,
						 token->location);
	  c_name = "filter";
	  break;
	case PRAGMA_OMP_CLAUSE_FINAL:
	  clauses = cp_parser_omp_clause_final (parser, clauses, token->location);
	  c_name = "final";
	  break;
	case PRAGMA_OMP_CLAUSE_FIRSTPRIVATE:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FIRSTPRIVATE,
					    clauses);
	  c_name = "firstprivate";
	  break;
	case PRAGMA_OMP_CLAUSE_GRAINSIZE:
	  clauses = cp_parser_omp_clause_grainsize (parser, clauses,
						    token->location);
	  c_name = "grainsize";
	  break;
	case PRAGMA_OMP_CLAUSE_HINT:
	  clauses = cp_parser_omp_clause_hint (parser, clauses,
					       token->location);
	  c_name = "hint";
	  break;
	case PRAGMA_OMP_CLAUSE_DEFAULTMAP:
	  clauses = cp_parser_omp_clause_defaultmap (parser, clauses,
						     token->location);
	  c_name = "defaultmap";
	  break;
	case PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_PTR,
					    clauses);
	  c_name = "use_device_ptr";
	  break;
	case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
					    clauses);
	  c_name = "use_device_addr";
	  break;
	case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_IS_DEVICE_PTR,
					    clauses);
	  c_name = "is_device_ptr";
	  break;
	case PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_HAS_DEVICE_ADDR,
					    clauses);
	  c_name = "has_device_addr";
	  break;
	case PRAGMA_OMP_CLAUSE_IF:
	  clauses = cp_parser_omp_clause_if (parser, clauses, token->location,
					     true);
	  c_name = "if";
	  break;
	case PRAGMA_OMP_CLAUSE_IN_REDUCTION:
	  clauses
	    = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_IN_REDUCTION,
					      true, clauses);
	  c_name = "in_reduction";
	  break;
	case PRAGMA_OMP_CLAUSE_LASTPRIVATE:
	  clauses = cp_parser_omp_clause_lastprivate (parser, clauses);
	  c_name = "lastprivate";
	  break;
	case PRAGMA_OMP_CLAUSE_MERGEABLE:
	  clauses = cp_parser_omp_clause_mergeable (parser, clauses,
						    token->location);
	  c_name = "mergeable";
	  break;
	case PRAGMA_OMP_CLAUSE_NOWAIT:
	  clauses = cp_parser_omp_clause_nowait (parser, clauses,
						 token->location);
	  c_name = "nowait";
	  break;
	case PRAGMA_OMP_CLAUSE_NUM_TASKS:
	  clauses = cp_parser_omp_clause_num_tasks (parser, clauses,
						    token->location);
	  c_name = "num_tasks";
	  break;
	case PRAGMA_OMP_CLAUSE_NUM_THREADS:
	  clauses = cp_parser_omp_clause_num_threads (parser, clauses,
						      token->location);
	  c_name = "num_threads";
	  break;
	case PRAGMA_OMP_CLAUSE_ORDER:
	  clauses = cp_parser_omp_clause_order (parser, clauses,
						token->location);
	  c_name = "order";
	  break;
	case PRAGMA_OMP_CLAUSE_ORDERED:
	  clauses = cp_parser_omp_clause_ordered (parser, clauses,
						  token->location);
	  c_name = "ordered";
	  break;
	case PRAGMA_OMP_CLAUSE_PRIORITY:
	  clauses = cp_parser_omp_clause_priority (parser, clauses,
						   token->location);
	  c_name = "priority";
	  break;
	case PRAGMA_OMP_CLAUSE_PRIVATE:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_PRIVATE,
					    clauses);
	  c_name = "private";
	  break;
	case PRAGMA_OMP_CLAUSE_REDUCTION:
	  clauses
	    = cp_parser_omp_clause_reduction (parser, OMP_CLAUSE_REDUCTION,
					      true, clauses);
	  c_name = "reduction";
	  break;
	case PRAGMA_OMP_CLAUSE_SCHEDULE:
	  clauses = cp_parser_omp_clause_schedule (parser, clauses,
						   token->location);
	  c_name = "schedule";
	  break;
	case PRAGMA_OMP_CLAUSE_SHARED:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_SHARED,
					    clauses);
	  c_name = "shared";
	  break;
	case PRAGMA_OMP_CLAUSE_TASK_REDUCTION:
	  clauses
	    = cp_parser_omp_clause_reduction (parser,
					      OMP_CLAUSE_TASK_REDUCTION,
					      true, clauses);
	  c_name = "task_reduction";
	  break;
	case PRAGMA_OMP_CLAUSE_UNTIED:
	  clauses = cp_parser_omp_clause_untied (parser, clauses,
						 token->location);
	  c_name = "untied";
	  break;
	case PRAGMA_OMP_CLAUSE_INBRANCH:
	  clauses = cp_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
						 clauses, token->location);
	  c_name = "inbranch";
	  break;
	case PRAGMA_OMP_CLAUSE_NONTEMPORAL:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_NONTEMPORAL,
					    clauses);
	  c_name = "nontemporal";
	  break;
	case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
	  clauses = cp_parser_omp_clause_branch (parser,
						 OMP_CLAUSE_NOTINBRANCH,
						 clauses, token->location);
	  c_name = "notinbranch";
	  break;
	case PRAGMA_OMP_CLAUSE_PARALLEL:
	  clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_PARALLEL,
						     clauses, token->location);
	  c_name = "parallel";
	  if (!first)
	    {
	     clause_not_first:
	      error_at (token->location, "%qs must be the first clause of %qs",
			c_name, where);
	      clauses = prev;
	    }
	  break;
	case PRAGMA_OMP_CLAUSE_FOR:
	  clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_FOR,
						     clauses, token->location);
	  c_name = "for";
	  if (!first)
	    goto clause_not_first;
	  break;
	case PRAGMA_OMP_CLAUSE_SECTIONS:
	  clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_SECTIONS,
						     clauses, token->location);
	  c_name = "sections";
	  if (!first)
	    goto clause_not_first;
	  break;
	case PRAGMA_OMP_CLAUSE_TASKGROUP:
	  clauses = cp_parser_omp_clause_cancelkind (parser, OMP_CLAUSE_TASKGROUP,
						     clauses, token->location);
	  c_name = "taskgroup";
	  if (!first)
	    goto clause_not_first;
	  break;
	case PRAGMA_OMP_CLAUSE_LINK:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_LINK, clauses);
	  c_name = "link";
	  break;
	case PRAGMA_OMP_CLAUSE_TO:
	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
	    {
	      tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
						clauses);
	      for (tree c = nl; c != clauses; c = OMP_CLAUSE_CHAIN (c))
		OMP_CLAUSE_ENTER_TO (c) = 1;
	      clauses = nl;
	    }
	  else
	    clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, clauses,
					      true);
	  c_name = "to";
	  break;
	case PRAGMA_OMP_CLAUSE_FROM:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, clauses,
					    true);
	  c_name = "from";
	  break;
	case PRAGMA_OMP_CLAUSE_UNIFORM:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_UNIFORM,
					    clauses);
	  c_name = "uniform";
	  break;
	case PRAGMA_OMP_CLAUSE_NUM_TEAMS:
	  clauses = cp_parser_omp_clause_num_teams (parser, clauses,
						    token->location);
	  c_name = "num_teams";
	  break;
	case PRAGMA_OMP_CLAUSE_THREAD_LIMIT:
	  clauses = cp_parser_omp_clause_thread_limit (parser, clauses,
						       token->location);
	  c_name = "thread_limit";
	  break;
	case PRAGMA_OMP_CLAUSE_ALIGNED:
	  clauses = cp_parser_omp_clause_aligned (parser, clauses);
	  c_name = "aligned";
	  break;
	case PRAGMA_OMP_CLAUSE_ALLOCATE:
	  clauses = cp_parser_omp_clause_allocate (parser, clauses);
	  c_name = "allocate";
	  break;
	case PRAGMA_OMP_CLAUSE_LINEAR:
	  {
	    bool declare_simd = false;
	    if (((mask >> PRAGMA_OMP_CLAUSE_UNIFORM) & 1) != 0)
	      declare_simd = true;
	    clauses = cp_parser_omp_clause_linear (parser, clauses, declare_simd);
	  }
	  c_name = "linear";
	  break;
	case PRAGMA_OMP_CLAUSE_AFFINITY:
	  clauses = cp_parser_omp_clause_affinity (parser, clauses);
	  c_name = "affinity";
	  break;
	case PRAGMA_OMP_CLAUSE_DEPEND:
	  clauses = cp_parser_omp_clause_depend (parser, clauses,
						 token->location);
	  c_name = "depend";
	  break;
	case PRAGMA_OMP_CLAUSE_DOACROSS:
	  clauses = cp_parser_omp_clause_doacross (parser, clauses,
						   token->location);
	  c_name = "doacross";
	  break;
	case PRAGMA_OMP_CLAUSE_DETACH:
	  clauses = cp_parser_omp_clause_detach (parser, clauses);
	  c_name = "detach";
	  break;
	case PRAGMA_OMP_CLAUSE_MAP:
	  clauses = cp_parser_omp_clause_map (parser, clauses);
	  c_name = "map";
	  break;
	case PRAGMA_OMP_CLAUSE_DEVICE:
	  clauses = cp_parser_omp_clause_device (parser, clauses,
						 token->location);
	  c_name = "device";
	  break;
	case PRAGMA_OMP_CLAUSE_DIST_SCHEDULE:
	  clauses = cp_parser_omp_clause_dist_schedule (parser, clauses,
							token->location);
	  c_name = "dist_schedule";
	  break;
	case PRAGMA_OMP_CLAUSE_PROC_BIND:
	  clauses = cp_parser_omp_clause_proc_bind (parser, clauses,
						    token->location);
	  c_name = "proc_bind";
	  break;
	case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
	  clauses = cp_parser_omp_clause_device_type (parser, clauses,
						      token->location);
	  c_name = "device_type";
	  break;
	case PRAGMA_OMP_CLAUSE_SAFELEN:
	  clauses = cp_parser_omp_clause_safelen (parser, clauses,
						  token->location);
	  c_name = "safelen";
	  break;
	case PRAGMA_OMP_CLAUSE_SIMDLEN:
	  clauses = cp_parser_omp_clause_simdlen (parser, clauses,
						  token->location);
	  c_name = "simdlen";
	  break;
	case PRAGMA_OMP_CLAUSE_NOGROUP:
	  clauses = cp_parser_omp_clause_nogroup (parser, clauses,
						  token->location);
	  c_name = "nogroup";
	  break;
	case PRAGMA_OMP_CLAUSE_THREADS:
	  clauses
	    = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_THREADS,
						clauses, token->location);
	  c_name = "threads";
	  break;
	case PRAGMA_OMP_CLAUSE_SIMD:
	  clauses
	    = cp_parser_omp_clause_orderedkind (parser, OMP_CLAUSE_SIMD,
						clauses, token->location);
	  c_name = "simd";
	  break;
	case PRAGMA_OMP_CLAUSE_ENTER:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
					    clauses);
	  c_name = "enter";
	  break;
	default:
	  cp_parser_error (parser, "expected %<#pragma omp%> clause");
	  goto saw_error;
	}

      first = false;

      if (((mask >> c_kind) & 1) == 0)
	{
	  /* Remove the invalid clause(s) from the list to avoid
	     confusing the rest of the compiler.  */
	  clauses = prev;
	  error_at (token->location, "%qs is not valid for %qs", c_name, where);
	}
    }
 saw_error:
  if (!nested)
    cp_parser_skip_to_pragma_eol (parser, pragma_tok);
  if (finish_p)
    {
      if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
	return finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
      else
	return finish_omp_clauses (clauses, C_ORT_OMP);
    }
  return clauses;
}

/* OpenMP 2.5:
   structured-block:
     statement

   In practice, we're also interested in adding the statement to an
   outer node.  So it is convenient if we work around the fact that
   cp_parser_statement calls add_stmt.  */

static unsigned
cp_parser_begin_omp_structured_block (cp_parser *parser)
{
  unsigned save = parser->in_statement;

  /* Only move the values to IN_OMP_BLOCK if they weren't false.
     This preserves the "not within loop or switch" style error messages
     for nonsense cases like
	void foo() {
	#pragma omp single
	  break;
	}
  */
  if (parser->in_statement)
    parser->in_statement = IN_OMP_BLOCK;

  return save;
}

static void
cp_parser_end_omp_structured_block (cp_parser *parser, unsigned save)
{
  parser->in_statement = save;
}

static tree
cp_parser_omp_structured_block (cp_parser *parser, bool *if_p)
{
  tree stmt = begin_omp_structured_block ();
  unsigned int save = cp_parser_begin_omp_structured_block (parser);

  parser->omp_attrs_forbidden_p = true;
  cp_parser_statement (parser, NULL_TREE, false, if_p);

  cp_parser_end_omp_structured_block (parser, save);
  return finish_omp_structured_block (stmt);
}

/* OpenMP 5.0:
   # pragma omp allocate (list)  [allocator(allocator)]  */

static void
cp_parser_omp_allocate (cp_parser *parser, cp_token *pragma_tok)
{
  tree allocator = NULL_TREE;
  location_t loc = pragma_tok->location;
  tree nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_ALLOCATE, NULL_TREE);

  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
    cp_lexer_consume_token (parser->lexer);

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      matching_parens parens;
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
      cp_lexer_consume_token (parser->lexer);
      if (strcmp (p, "allocator") != 0)
	error_at (cloc, "expected %<allocator%>");
      else if (parens.require_open (parser))
	{
	  allocator = cp_parser_assignment_expression (parser);
	  if (allocator == error_mark_node)
	    allocator = NULL_TREE;
	  parens.require_close (parser);
	}
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);

  if (allocator)
    for (tree c = nl; c != NULL_TREE; c = OMP_CLAUSE_CHAIN (c))
      OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;

  sorry_at (loc, "%<#pragma omp allocate%> not yet supported");
}

/* OpenMP 2.5:
   # pragma omp atomic new-line
     expression-stmt

   expression-stmt:
     x binop= expr | x++ | ++x | x-- | --x
   binop:
     +, *, -, /, &, ^, |, <<, >>

  where x is an lvalue expression with scalar type.

   OpenMP 3.1:
   # pragma omp atomic new-line
     update-stmt

   # pragma omp atomic read new-line
     read-stmt

   # pragma omp atomic write new-line
     write-stmt

   # pragma omp atomic update new-line
     update-stmt

   # pragma omp atomic capture new-line
     capture-stmt

   # pragma omp atomic capture new-line
     capture-block

   read-stmt:
     v = x
   write-stmt:
     x = expr
   update-stmt:
     expression-stmt | x = x binop expr
   capture-stmt:
     v = expression-stmt
   capture-block:
     { v = x; update-stmt; } | { update-stmt; v = x; }

   OpenMP 4.0:
   update-stmt:
     expression-stmt | x = x binop expr | x = expr binop x
   capture-stmt:
     v = update-stmt
   capture-block:
     { v = x; update-stmt; } | { update-stmt; v = x; } | { v = x; x = expr; }

   OpenMP 5.1:
   # pragma omp atomic compare new-line
     conditional-update-atomic

   # pragma omp atomic compare capture new-line
     conditional-update-capture-atomic

   conditional-update-atomic:
     cond-expr-stmt | cond-update-stmt
   cond-expr-stmt:
     x = expr ordop x ? expr : x;
     x = x ordop expr ? expr : x;
     x = x == e ? d : x;
   cond-update-stmt:
     if (expr ordop x) { x = expr; }
     if (x ordop expr) { x = expr; }
     if (x == e) { x = d; }
   ordop:
     <, >
   conditional-update-capture-atomic:
     v = cond-expr-stmt
     { v = x; cond-expr-stmt }
     { cond-expr-stmt v = x; }
     { v = x; cond-update-stmt }
     { cond-update-stmt v = x; }
     if (x == e) { x = d; } else { v = x; }
     { r = x == e; if (r) { x = d; } }
     { r = x == e; if (r) { x = d; } else { v = x; } }

  where x, r and v are lvalue expressions with scalar type,
  expr, e and d are expressions with scalar type and e might be
  the same as v.  */

static void
cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok, bool openacc)
{
  tree lhs = NULL_TREE, rhs = NULL_TREE, v = NULL_TREE, lhs1 = NULL_TREE;
  tree rhs1 = NULL_TREE, orig_lhs, r = NULL_TREE;
  location_t loc = pragma_tok->location;
  enum tree_code code = ERROR_MARK, opcode = NOP_EXPR;
  enum omp_memory_order memory_order = OMP_MEMORY_ORDER_UNSPECIFIED;
  bool structured_block = false;
  tree clauses = NULL_TREE;
  bool capture = false;
  bool compare = false;
  bool weak = false;
  enum omp_memory_order fail = OMP_MEMORY_ORDER_UNSPECIFIED;
  bool no_semicolon = false;
  bool extra_scope = false;

  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
	  const char *p = IDENTIFIER_POINTER (id);
	  enum tree_code new_code = ERROR_MARK;
	  enum omp_memory_order new_memory_order
	    = OMP_MEMORY_ORDER_UNSPECIFIED;
	  bool new_capture = false;
	  bool new_compare = false;
	  bool new_weak = false;
	  enum omp_memory_order new_fail = OMP_MEMORY_ORDER_UNSPECIFIED;

	  if (!strcmp (p, "read"))
	    new_code = OMP_ATOMIC_READ;
	  else if (!strcmp (p, "write"))
	    new_code = NOP_EXPR;
	  else if (!strcmp (p, "update"))
	    new_code = OMP_ATOMIC;
	  else if (openacc && !strcmp (p, "capture"))
	    new_code = OMP_ATOMIC_CAPTURE_NEW;
	  else if (openacc)
	    {
	      p = NULL;
	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
			      "or %<capture%> clause");
	    }
	  else if (!strcmp (p, "capture"))
	    new_capture = true;
	  else if (!strcmp (p, "compare"))
	    new_compare = true;
	  else if (!strcmp (p, "weak"))
	    new_weak = true;
	  else if (!strcmp (p, "fail"))
	    {
	      matching_parens parens;

	      cp_lexer_consume_token (parser->lexer);
	      if (!parens.require_open (parser))
		continue;

	      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
		{
		  id = cp_lexer_peek_token (parser->lexer)->u.value;
		  const char *q = IDENTIFIER_POINTER (id);

		  if (!strcmp (q, "seq_cst"))
		    new_fail = OMP_MEMORY_ORDER_SEQ_CST;
		  else if (!strcmp (q, "acquire"))
		    new_fail = OMP_MEMORY_ORDER_ACQUIRE;
		  else if (!strcmp (q, "relaxed"))
		    new_fail = OMP_MEMORY_ORDER_RELAXED;
		}

	      if (new_fail != OMP_MEMORY_ORDER_UNSPECIFIED)
		{
		  cp_lexer_consume_token (parser->lexer);
		  if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
		    error_at (cloc, "too many %qs clauses", "fail");
		  else
		    fail = new_fail;
		}
	      else
		cp_parser_error (parser, "expected %<seq_cst%>, %<acquire%> "
					 "or %<relaxed%>");
	      if (new_fail == OMP_MEMORY_ORDER_UNSPECIFIED
		  || !parens.require_close (parser))
		cp_parser_skip_to_closing_parenthesis (parser,
						       /*recovering=*/true,
						       /*or_comma=*/false,
						       /*consume_paren=*/true);
	      continue;
	    }
	  else if (!strcmp (p, "seq_cst"))
	    new_memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  else if (!strcmp (p, "acq_rel"))
	    new_memory_order = OMP_MEMORY_ORDER_ACQ_REL;
	  else if (!strcmp (p, "release"))
	    new_memory_order = OMP_MEMORY_ORDER_RELEASE;
	  else if (!strcmp (p, "acquire"))
	    new_memory_order = OMP_MEMORY_ORDER_ACQUIRE;
	  else if (!strcmp (p, "relaxed"))
	    new_memory_order = OMP_MEMORY_ORDER_RELAXED;
	  else if (!strcmp (p, "hint"))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      clauses = cp_parser_omp_clause_hint (parser, clauses, cloc);
	      continue;
	    }
	  else
	    {
	      p = NULL;
	      error_at (cloc, "expected %<read%>, %<write%>, %<update%>, "
			      "%<capture%>, %<compare%>, %<weak%>, %<fail%>, "
			      "%<seq_cst%>, %<acq_rel%>, %<release%>, "
			      "%<relaxed%> or %<hint%> clause");
	    }
	  if (p)
	    {
	      if (new_code != ERROR_MARK)
		{
		  /* OpenACC permits 'update capture'.  */
		  if (openacc
		      && code == OMP_ATOMIC
		      && new_code == OMP_ATOMIC_CAPTURE_NEW)
		    code = new_code;
		  else if (code != ERROR_MARK)
		    error_at (cloc, "too many atomic clauses");
		  else
		    code = new_code;
		}
	      else if (new_memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
		{
		  if (memory_order != OMP_MEMORY_ORDER_UNSPECIFIED)
		    error_at (cloc, "too many memory order clauses");
		  else
		    memory_order = new_memory_order;
		}
	      else if (new_capture)
		{
		  if (capture)
		    error_at (cloc, "too many %qs clauses", "capture");
		  else
		    capture = true;
		}
	      else if (new_compare)
		{
		  if (compare)
		    error_at (cloc, "too many %qs clauses", "compare");
		  else
		    compare = true;
		}
	      else if (new_weak)
		{
		  if (weak)
		    error_at (cloc, "too many %qs clauses", "weak");
		  else
		    weak = true;
		}
	      cp_lexer_consume_token (parser->lexer);
	      continue;
	    }
	}
      break;
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);

  if (code == ERROR_MARK)
    code = OMP_ATOMIC;
  if (capture)
    {
      if (code != OMP_ATOMIC)
	error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
		       "clauses", "capture");
      else
	code = OMP_ATOMIC_CAPTURE_NEW;
    }
  if (compare && code != OMP_ATOMIC && code != OMP_ATOMIC_CAPTURE_NEW)
    {
      error_at (loc, "%qs clause is incompatible with %<read%> or %<write%> "
		     "clauses", "compare");
      compare = false;
    }
  if (fail != OMP_MEMORY_ORDER_UNSPECIFIED && !compare)
    {
      error_at (loc, "%qs clause requires %qs clause", "fail", "compare");
      fail = OMP_MEMORY_ORDER_UNSPECIFIED;
    }
  if (weak && !compare)
    {
      error_at (loc, "%qs clause requires %qs clause", "weak", "compare");
      weak = false;
    }
  if (openacc)
    memory_order = OMP_MEMORY_ORDER_RELAXED;
  else if (memory_order == OMP_MEMORY_ORDER_UNSPECIFIED)
    {
      omp_requires_mask
	= (enum omp_requires) (omp_requires_mask
			       | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED);
      switch ((enum omp_memory_order)
	      (omp_requires_mask & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER))
	{
	case OMP_MEMORY_ORDER_UNSPECIFIED:
	case OMP_MEMORY_ORDER_RELAXED:
	  memory_order = OMP_MEMORY_ORDER_RELAXED;
	  break;
	case OMP_MEMORY_ORDER_SEQ_CST:
	  memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  break;
	case OMP_MEMORY_ORDER_ACQ_REL:
	  switch (code)
	    {
	    case OMP_ATOMIC_READ:
	      memory_order = OMP_MEMORY_ORDER_ACQUIRE;
	      break;
	    case NOP_EXPR: /* atomic write */
	      memory_order = OMP_MEMORY_ORDER_RELEASE;
	      break;
	    default:
	      memory_order = OMP_MEMORY_ORDER_ACQ_REL;
	      break;
	    }
	  break;
	default:
	  gcc_unreachable ();
	}
    }
  else
    switch (code)
      {
      case OMP_ATOMIC_READ:
	if (memory_order == OMP_MEMORY_ORDER_RELEASE)
	  {
	    error_at (loc, "%<#pragma omp atomic read%> incompatible with "
			   "%<release%> clause");
	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  }
	else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
	  memory_order = OMP_MEMORY_ORDER_ACQUIRE;
	break;
      case NOP_EXPR: /* atomic write */
	if (memory_order == OMP_MEMORY_ORDER_ACQUIRE)
	  {
	    error_at (loc, "%<#pragma omp atomic write%> incompatible with "
			   "%<acquire%> clause");
	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  }
	else if (memory_order == OMP_MEMORY_ORDER_ACQ_REL)
	  memory_order = OMP_MEMORY_ORDER_RELEASE;
	break;
      default:
	break;
      }
  if (fail != OMP_MEMORY_ORDER_UNSPECIFIED)
    memory_order
      = (enum omp_memory_order) (memory_order
				 | (fail << OMP_FAIL_MEMORY_ORDER_SHIFT));

  switch (code)
    {
    case OMP_ATOMIC_READ:
    case NOP_EXPR: /* atomic write */
      v = cp_parser_unary_expression (parser);
      if (v == error_mark_node)
	goto saw_error;
      if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
	goto saw_error;
      if (code == NOP_EXPR)
	lhs = cp_parser_expression (parser);
      else
	lhs = cp_parser_unary_expression (parser);
      if (lhs == error_mark_node)
	goto saw_error;
      if (code == NOP_EXPR)
	{
	  /* atomic write is represented by OMP_ATOMIC with NOP_EXPR
	     opcode.  */
	  code = OMP_ATOMIC;
	  rhs = lhs;
	  lhs = v;
	  v = NULL_TREE;
	}
      goto done;
    case OMP_ATOMIC_CAPTURE_NEW:
      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	{
	  cp_lexer_consume_token (parser->lexer);
	  structured_block = true;
	}
      else if (compare
	       && cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
	break;
      else
	{
	  v = cp_parser_unary_expression (parser);
	  if (v == error_mark_node)
	    goto saw_error;
	  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
	    goto saw_error;
	  if (compare
	      && cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
	    {
	      location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
	      error_at (eloc, "expected expression");
	      goto saw_error;
	    }
	}
    default:
      break;
    }

restart:
  if (compare && cp_lexer_next_token_is_keyword (parser->lexer, RID_IF))
    {
      cp_lexer_consume_token (parser->lexer);

      matching_parens parens;
      if (!parens.require_open (parser))
	goto saw_error;
      location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
      tree cmp_expr;
      if (r)
	cmp_expr = cp_parser_unary_expression (parser);
      else
	cmp_expr = cp_parser_binary_expression (parser, false, true,
						PREC_NOT_OPERATOR, NULL);
      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, true, false, true);
      if (cmp_expr == error_mark_node)
	goto saw_error;
      if (r)
	{
	  if (!cp_tree_equal (cmp_expr, r))
	    goto bad_if;
	  cmp_expr = rhs;
	  rhs = NULL_TREE;
	  gcc_assert (TREE_CODE (cmp_expr) == EQ_EXPR);
	}
      if (TREE_CODE (cmp_expr) == EQ_EXPR)
	;
      else if (!structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
	{
	  error_at (EXPR_LOC_OR_LOC (cmp_expr, eloc),
		    "expected %<==%> comparison in %<if%> condition");
	  goto saw_error;
	}
      else if (TREE_CODE (cmp_expr) != GT_EXPR
	       && TREE_CODE (cmp_expr) != LT_EXPR)
	{
	  error_at (EXPR_LOC_OR_LOC (cmp_expr, eloc),
		    "expected %<==%>, %<<%> or %<>%> comparison in %<if%> "
		    "condition");
	  goto saw_error;
	}
      if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
	goto saw_error;

      extra_scope = true;
      eloc = cp_lexer_peek_token (parser->lexer)->location;
      lhs = cp_parser_unary_expression (parser);
      orig_lhs = lhs;
      if (lhs == error_mark_node)
	goto saw_error;
      if (!cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	{
	  cp_parser_error (parser, "expected %<=%>");
	  goto saw_error;
	}
      cp_lexer_consume_token (parser->lexer);
      eloc = cp_lexer_peek_token (parser->lexer)->location;
      if (TREE_CODE (cmp_expr) == EQ_EXPR)
	rhs1 = cp_parser_expression (parser);
      else
	rhs1 = cp_parser_simple_cast_expression (parser);

      if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
	goto saw_error;

      if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
	goto saw_error;

      extra_scope = false;
      no_semicolon = true;

      if (cp_tree_equal (TREE_OPERAND (cmp_expr, 0), lhs))
	{
	  if (TREE_CODE (cmp_expr) == EQ_EXPR)
	    {
	      opcode = COND_EXPR;
	      rhs = TREE_OPERAND (cmp_expr, 1);
	    }
	  else if (cp_tree_equal (TREE_OPERAND (cmp_expr, 1), rhs1))
	    {
	      opcode = (TREE_CODE (cmp_expr) == GT_EXPR
			? MIN_EXPR : MAX_EXPR);
	      rhs = rhs1;
	      rhs1 = TREE_OPERAND (cmp_expr, 0);
	    }
	  else
	    goto bad_if;
	}
      else if (TREE_CODE (cmp_expr) == EQ_EXPR)
	goto bad_if;
      else if (cp_tree_equal (TREE_OPERAND (cmp_expr, 1), lhs)
	       && cp_tree_equal (TREE_OPERAND (cmp_expr, 0), rhs1))
	{
	  opcode = (TREE_CODE (cmp_expr) == GT_EXPR
		    ? MAX_EXPR : MIN_EXPR);
	  rhs = rhs1;
	  rhs1 = TREE_OPERAND (cmp_expr, 1);
	}
      else
	{
	bad_if:
	  cp_parser_error (parser,
			   "invalid form of %<#pragma omp atomic compare%>");
	  goto saw_error;
	}

      if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ELSE))
	{
	  if (code != OMP_ATOMIC_CAPTURE_NEW
	      || (structured_block && r == NULL_TREE)
	      || TREE_CODE (cmp_expr) != EQ_EXPR)
	    {
	      eloc = cp_lexer_peek_token (parser->lexer)->location;
	      error_at (eloc, "unexpected %<else%>");
	      goto saw_error;
	    }

	  cp_lexer_consume_token (parser->lexer);

	  if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
	    goto saw_error;

	  extra_scope = true;
	  v = cp_parser_unary_expression (parser);
	  if (v == error_mark_node)
	    goto saw_error;
	  if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
	    goto saw_error;

	  tree expr = cp_parser_simple_cast_expression (parser);

	  if (!cp_tree_equal (expr, lhs))
	    goto bad_if;

	  if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
	    goto saw_error;

	  if (!cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE))
	    goto saw_error;

	  extra_scope = false;
	  code = OMP_ATOMIC_CAPTURE_OLD;
	  if (r == NULL_TREE)
	    /* Signal to c_finish_omp_atomic that in
	       if (x == e) { x = d; } else { v = x; }
	       case the store to v should be conditional.  */
	    r = void_list_node;
	}
      else if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
	{
	  cp_parser_error (parser, "expected %<else%>");
	  goto saw_error;
	}
      else if (code == OMP_ATOMIC_CAPTURE_NEW
	       && r != NULL_TREE
	       && v == NULL_TREE)
	code = OMP_ATOMIC;
      goto stmt_done;
    }
  lhs = cp_parser_unary_expression (parser);
  orig_lhs = lhs;
  switch (TREE_CODE (lhs))
    {
    case ERROR_MARK:
      goto saw_error;

    case POSTINCREMENT_EXPR:
      if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
	code = OMP_ATOMIC_CAPTURE_OLD;
      /* FALLTHROUGH */
    case PREINCREMENT_EXPR:
      lhs = TREE_OPERAND (lhs, 0);
      opcode = PLUS_EXPR;
      rhs = integer_one_node;
      if (compare)
	goto invalid_compare;
      break;

    case POSTDECREMENT_EXPR:
      if (code == OMP_ATOMIC_CAPTURE_NEW && !structured_block)
	code = OMP_ATOMIC_CAPTURE_OLD;
      /* FALLTHROUGH */
    case PREDECREMENT_EXPR:
      lhs = TREE_OPERAND (lhs, 0);
      opcode = MINUS_EXPR;
      rhs = integer_one_node;
      if (compare)
	goto invalid_compare;
      break;

    case COMPOUND_EXPR:
      if (TREE_CODE (TREE_OPERAND (lhs, 0)) == SAVE_EXPR
	 && TREE_CODE (TREE_OPERAND (lhs, 1)) == COMPOUND_EXPR
	 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (lhs, 1), 0)) == MODIFY_EXPR
	 && TREE_OPERAND (TREE_OPERAND (lhs, 1), 1) == TREE_OPERAND (lhs, 0)
	 && TREE_CODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND
					     (TREE_OPERAND (lhs, 1), 0), 0)))
	    == BOOLEAN_TYPE)
       /* Undo effects of boolean_increment for post {in,de}crement.  */
       lhs = TREE_OPERAND (TREE_OPERAND (lhs, 1), 0);
      /* FALLTHRU */
    case MODIFY_EXPR:
      if (TREE_CODE (lhs) == MODIFY_EXPR
	 && TREE_CODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) == BOOLEAN_TYPE)
	{
	  /* Undo effects of boolean_increment.  */
	  if (integer_onep (TREE_OPERAND (lhs, 1)))
	    {
	      /* This is pre or post increment.  */
	      rhs = TREE_OPERAND (lhs, 1);
	      lhs = TREE_OPERAND (lhs, 0);
	      opcode = NOP_EXPR;
	      if (code == OMP_ATOMIC_CAPTURE_NEW
		  && !structured_block
		  && TREE_CODE (orig_lhs) == COMPOUND_EXPR)
		code = OMP_ATOMIC_CAPTURE_OLD;
	      if (compare)
		goto invalid_compare;
	      break;
	    }
	}
      /* FALLTHRU */
    default:
      if (compare && !cp_lexer_next_token_is (parser->lexer, CPP_EQ))
	{
	  cp_parser_error (parser, "expected %<=%>");
	  goto saw_error;
	}
      switch (cp_lexer_peek_token (parser->lexer)->type)
	{
	case CPP_MULT_EQ:
	  opcode = MULT_EXPR;
	  break;
	case CPP_DIV_EQ:
	  opcode = TRUNC_DIV_EXPR;
	  break;
	case CPP_PLUS_EQ:
	  opcode = PLUS_EXPR;
	  break;
	case CPP_MINUS_EQ:
	  opcode = MINUS_EXPR;
	  break;
	case CPP_LSHIFT_EQ:
	  opcode = LSHIFT_EXPR;
	  break;
	case CPP_RSHIFT_EQ:
	  opcode = RSHIFT_EXPR;
	  break;
	case CPP_AND_EQ:
	  opcode = BIT_AND_EXPR;
	  break;
	case CPP_OR_EQ:
	  opcode = BIT_IOR_EXPR;
	  break;
	case CPP_XOR_EQ:
	  opcode = BIT_XOR_EXPR;
	  break;
	case CPP_EQ:
	  enum cp_parser_prec oprec;
	  cp_token *token;
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_parse_tentatively (parser);
	  rhs1 = cp_parser_simple_cast_expression (parser);
	  if (rhs1 == error_mark_node)
	    {
	      cp_parser_abort_tentative_parse (parser);
	      cp_parser_simple_cast_expression (parser);
	      goto saw_error;
	    }
	  token = cp_lexer_peek_token (parser->lexer);
	  if (token->type != CPP_SEMICOLON
	      && (!compare || token->type != CPP_QUERY)
	      && !cp_tree_equal (lhs, rhs1))
	    {
	      cp_parser_abort_tentative_parse (parser);
	      cp_parser_parse_tentatively (parser);
	      rhs = cp_parser_binary_expression (parser, false, true,
						 PREC_NOT_OPERATOR, NULL);
	      if (rhs == error_mark_node)
		{
		  cp_parser_abort_tentative_parse (parser);
		  cp_parser_binary_expression (parser, false, true,
					       PREC_NOT_OPERATOR, NULL);
		  goto saw_error;
		}
	      switch (TREE_CODE (rhs))
		{
		case MULT_EXPR:
		case TRUNC_DIV_EXPR:
		case RDIV_EXPR:
		case PLUS_EXPR:
		case MINUS_EXPR:
		case LSHIFT_EXPR:
		case RSHIFT_EXPR:
		case BIT_AND_EXPR:
		case BIT_IOR_EXPR:
		case BIT_XOR_EXPR:
		  if (compare)
		    break;
		  if (cp_tree_equal (lhs, TREE_OPERAND (rhs, 1)))
		    {
		      if (cp_parser_parse_definitely (parser))
			{
			  opcode = TREE_CODE (rhs);
			  rhs1 = TREE_OPERAND (rhs, 0);
			  rhs = TREE_OPERAND (rhs, 1);
			  goto stmt_done;
			}
		      else
			goto saw_error;
		    }
		  break;
		case EQ_EXPR:
		  if (!compare
		      || code != OMP_ATOMIC_CAPTURE_NEW
		      || !structured_block
		      || v
		      || r)
		    break;
		  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON)
		      && cp_lexer_nth_token_is_keyword (parser->lexer,
							2, RID_IF))
		    {
		      if (cp_parser_parse_definitely (parser))
			{
			  r = lhs;
			  lhs = NULL_TREE;
			  rhs1 = NULL_TREE;
			  cp_lexer_consume_token (parser->lexer);
			  goto restart;
			}
		    }
		  break;
		case GT_EXPR:
		case LT_EXPR:
		  if (compare
		      && cp_lexer_next_token_is (parser->lexer, CPP_QUERY)
		      && cp_tree_equal (lhs, TREE_OPERAND (rhs, 1))
		      && cp_parser_parse_definitely (parser))
		    {
		      opcode = TREE_CODE (rhs);
		      rhs1 = TREE_OPERAND (rhs, 0);
		      rhs = TREE_OPERAND (rhs, 1);
		     cond_expr:
		      cp_lexer_consume_token (parser->lexer);
		      bool saved_colon_corrects_to_scope_p
			= parser->colon_corrects_to_scope_p;
		      parser->colon_corrects_to_scope_p = false;
		      tree e1 = cp_parser_expression (parser);
		      parser->colon_corrects_to_scope_p
			= saved_colon_corrects_to_scope_p;
		      cp_parser_require (parser, CPP_COLON, RT_COLON);
		      tree e2 = cp_parser_simple_cast_expression (parser);
		      if (cp_tree_equal (lhs, e2))
			{
			  if (cp_tree_equal (lhs, rhs1))
			    {
			      if (opcode == EQ_EXPR)
				{
				  opcode = COND_EXPR;
				  rhs1 = e1;
				  goto stmt_done;
				}
			      if (cp_tree_equal (rhs, e1))
				{
				  opcode
				    = opcode == GT_EXPR ? MIN_EXPR : MAX_EXPR;
				  rhs = e1;
				  goto stmt_done;
				}
			    }
			  else
			    {
			      gcc_assert (opcode != EQ_EXPR);
			      if (cp_tree_equal (rhs1, e1))
				{
				  opcode
				    = opcode == GT_EXPR ? MAX_EXPR : MIN_EXPR;
				  rhs1 = rhs;
				  rhs = e1;
				  goto stmt_done;
				}
			    }
			}
		      cp_parser_error (parser,
				       "invalid form of "
				       "%<#pragma omp atomic compare%>");
		      goto saw_error;
		    }
		  break;
		default:
		  break;
		}
	      cp_parser_abort_tentative_parse (parser);
	      if (structured_block
		  && code == OMP_ATOMIC_CAPTURE_OLD
		  && !compare)
		{
		  rhs = cp_parser_expression (parser);
		  if (rhs == error_mark_node)
		    goto saw_error;
		  opcode = NOP_EXPR;
		  rhs1 = NULL_TREE;
		  goto stmt_done;
		}
	      cp_parser_error (parser,
			       "invalid form of %<#pragma omp atomic%>");
	      goto saw_error;
	    }
	  if (!cp_parser_parse_definitely (parser))
	    goto saw_error;
	  switch (token->type)
	    {
	    case CPP_SEMICOLON:
	      if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW)
		{
		  code = OMP_ATOMIC_CAPTURE_OLD;
		  v = lhs;
		  lhs = NULL_TREE;
		  lhs1 = rhs1;
		  rhs1 = NULL_TREE;
		  cp_lexer_consume_token (parser->lexer);
		  goto restart;
		}
	      else if (structured_block && !compare)
		{
		  opcode = NOP_EXPR;
		  rhs = rhs1;
		  rhs1 = NULL_TREE;
		  goto stmt_done;
		}
	      cp_parser_error (parser,
			       "invalid form of %<#pragma omp atomic%>");
	      goto saw_error;
	    case CPP_MULT:
	      opcode = MULT_EXPR;
	      break;
	    case CPP_DIV:
	      opcode = TRUNC_DIV_EXPR;
	      break;
	    case CPP_PLUS:
	      opcode = PLUS_EXPR;
	      break;
	    case CPP_MINUS:
	      opcode = MINUS_EXPR;
	      break;
	    case CPP_LSHIFT:
	      opcode = LSHIFT_EXPR;
	      break;
	    case CPP_RSHIFT:
	      opcode = RSHIFT_EXPR;
	      break;
	    case CPP_AND:
	      opcode = BIT_AND_EXPR;
	      break;
	    case CPP_OR:
	      opcode = BIT_IOR_EXPR;
	      break;
	    case CPP_XOR:
	      opcode = BIT_XOR_EXPR;
	      break;
	    case CPP_EQ_EQ:
	      opcode = EQ_EXPR;
	      break;
	    case CPP_GREATER:
	      opcode = GT_EXPR;
	      break;
	    case CPP_LESS:
	      opcode = LT_EXPR;
	      break;
	    default:
	      cp_parser_error (parser,
			       "invalid operator for %<#pragma omp atomic%>");
	      goto saw_error;
	    }
	  if (compare
	      && TREE_CODE_CLASS (opcode) != tcc_comparison)
	    {
	      cp_parser_error (parser,
			       "invalid form of "
			       "%<#pragma omp atomic compare%>");
	      goto saw_error;
	    }
	  oprec = TOKEN_PRECEDENCE (token);
	  gcc_assert (oprec != PREC_NOT_OPERATOR);
	  if (commutative_tree_code (opcode))
	    oprec = (enum cp_parser_prec) (oprec - 1);
	  cp_lexer_consume_token (parser->lexer);
	  rhs = cp_parser_binary_expression (parser, false, false,
					     oprec, NULL);
	  if (rhs == error_mark_node)
	    goto saw_error;
	  if (compare)
	    {
	      if (!cp_lexer_next_token_is (parser->lexer, CPP_QUERY))
		{
		  cp_parser_error (parser,
				   "invalid form of "
				   "%<#pragma omp atomic compare%>");
		  goto saw_error;
		}
	      goto cond_expr;
	    }
	  goto stmt_done;
	default:
	  cp_parser_error (parser,
			   "invalid operator for %<#pragma omp atomic%>");
	  goto saw_error;
	}
      cp_lexer_consume_token (parser->lexer);

      rhs = cp_parser_expression (parser);
      if (rhs == error_mark_node)
	goto saw_error;
      break;
    }
stmt_done:
  if (structured_block && code == OMP_ATOMIC_CAPTURE_NEW && r == NULL_TREE)
    {
      if (!no_semicolon
	  && !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
	goto saw_error;
      no_semicolon = false;
      v = cp_parser_unary_expression (parser);
      if (v == error_mark_node)
	goto saw_error;
      if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
	goto saw_error;
      lhs1 = cp_parser_unary_expression (parser);
      if (lhs1 == error_mark_node)
	goto saw_error;
    }
  if (structured_block)
    {
      if (!no_semicolon)
	cp_parser_consume_semicolon_at_end_of_statement (parser);
      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
    }
done:
  if (weak && opcode != COND_EXPR)
    {
      error_at (loc, "%<weak%> clause requires atomic equality comparison");
      weak = false;
    }
  clauses = finish_omp_clauses (clauses, C_ORT_OMP);
  finish_omp_atomic (pragma_tok->location, code, opcode, lhs, rhs, v, lhs1,
		     rhs1, r, clauses, memory_order, weak);
  if (!structured_block && !no_semicolon)
    cp_parser_consume_semicolon_at_end_of_statement (parser);
  return;

 invalid_compare:
  error ("invalid form of %<pragma omp atomic compare%>");
  /* FALLTHRU */
 saw_error:
  cp_parser_skip_to_end_of_block_or_statement (parser);
  if (extra_scope && cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
    cp_lexer_consume_token (parser->lexer);
  if (structured_block)
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
        cp_lexer_consume_token (parser->lexer);
      else if (code == OMP_ATOMIC_CAPTURE_NEW)
	{
	  cp_parser_skip_to_end_of_block_or_statement (parser);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
	    cp_lexer_consume_token (parser->lexer);
	}
    }
}


/* OpenMP 2.5:
   # pragma omp barrier new-line  */

static void
cp_parser_omp_barrier (cp_parser *parser, cp_token *pragma_tok)
{
  cp_parser_require_pragma_eol (parser, pragma_tok);
  finish_omp_barrier ();
}

/* OpenMP 2.5:
   # pragma omp critical [(name)] new-line
     structured-block

   OpenMP 4.5:
   # pragma omp critical [(name) [hint(expression)]] new-line
     structured-block  */

#define OMP_CRITICAL_CLAUSE_MASK		\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HINT) )

static tree
cp_parser_omp_critical (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree stmt, name = NULL_TREE, clauses = NULL_TREE;

  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      matching_parens parens;
      parens.consume_open (parser);

      name = cp_parser_identifier (parser);

      if (name == error_mark_node
	  || !parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);
      if (name == error_mark_node)
	name = NULL;

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	cp_lexer_consume_token (parser->lexer);
    }

  clauses = cp_parser_omp_all_clauses (parser, OMP_CRITICAL_CLAUSE_MASK,
				       "#pragma omp critical", pragma_tok);

  stmt = cp_parser_omp_structured_block (parser, if_p);
  return c_finish_omp_critical (input_location, stmt, name, clauses);
}

/* OpenMP 5.0:
   # pragma omp depobj ( depobj ) depobj-clause new-line

   depobj-clause:
     depend (dependence-type : locator)
     destroy
     update (dependence-type)

   dependence-type:
     in
     out
     inout
     mutexinout  */

static void
cp_parser_omp_depobj (cp_parser *parser, cp_token *pragma_tok)
{
  location_t loc = pragma_tok->location;
  matching_parens parens;
  if (!parens.require_open (parser))
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return;
    }

  tree depobj = cp_parser_assignment_expression (parser);

  if (!parens.require_close (parser))
    cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					   /*or_comma=*/false,
					   /*consume_paren=*/true);

  tree clause = NULL_TREE;
  enum omp_clause_depend_kind kind = OMP_CLAUSE_DEPEND_INVALID;
  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
    cp_lexer_consume_token (parser->lexer);
  location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      cp_lexer_consume_token (parser->lexer);
      if (!strcmp ("depend", p))
	{
	  /* Don't create location wrapper nodes within the depend clause.  */
	  auto_suppress_location_wrappers sentinel;
	  clause = cp_parser_omp_clause_depend (parser, NULL_TREE, c_loc);
	  if (clause)
	    clause = finish_omp_clauses (clause, C_ORT_OMP);
	  if (!clause)
	    clause = error_mark_node;
	}
      else if (!strcmp ("destroy", p))
	kind = OMP_CLAUSE_DEPEND_LAST;
      else if (!strcmp ("update", p))
	{
	  matching_parens c_parens;
	  if (c_parens.require_open (parser))
	    {
	      location_t c2_loc
		= cp_lexer_peek_token (parser->lexer)->location;
	      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
		{
		  tree id2 = cp_lexer_peek_token (parser->lexer)->u.value;
		  const char *p2 = IDENTIFIER_POINTER (id2);

		  cp_lexer_consume_token (parser->lexer);
		  if (!strcmp ("in", p2))
		    kind = OMP_CLAUSE_DEPEND_IN;
		  else if (!strcmp ("out", p2))
		    kind = OMP_CLAUSE_DEPEND_OUT;
		  else if (!strcmp ("inout", p2))
		    kind = OMP_CLAUSE_DEPEND_INOUT;
		  else if (!strcmp ("mutexinoutset", p2))
		    kind = OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
		  else if (!strcmp ("inoutset", p2))
		    kind = OMP_CLAUSE_DEPEND_INOUTSET;
		}
	      if (kind == OMP_CLAUSE_DEPEND_INVALID)
		{
		  clause = error_mark_node;
		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%>, "
				    "%<mutexinoutset%> or %<inoutset%>");
		}
	      if (!c_parens.require_close (parser))
		cp_parser_skip_to_closing_parenthesis (parser,
						       /*recovering=*/true,
						       /*or_comma=*/false,
						       /*consume_paren=*/true);
	    }
	  else
	    clause = error_mark_node;
	}
    }
  if (!clause && kind == OMP_CLAUSE_DEPEND_INVALID)
    {
      clause = error_mark_node;
      error_at (c_loc, "expected %<depend%>, %<destroy%> or %<update%> clause");
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);

  finish_omp_depobj (loc, depobj, kind, clause);
}


/* OpenMP 2.5:
   # pragma omp flush flush-vars[opt] new-line

   flush-vars:
     ( variable-list )

   OpenMP 5.0:
   # pragma omp flush memory-order-clause new-line  */

static void
cp_parser_omp_flush (cp_parser *parser, cp_token *pragma_tok)
{
  enum memmodel mo = MEMMODEL_LAST;
  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
    cp_lexer_consume_token (parser->lexer);
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      if (!strcmp (p, "seq_cst"))
	mo = MEMMODEL_SEQ_CST;
      else if (!strcmp (p, "acq_rel"))
	mo = MEMMODEL_ACQ_REL;
      else if (!strcmp (p, "release"))
	mo = MEMMODEL_RELEASE;
      else if (!strcmp (p, "acquire"))
	mo = MEMMODEL_ACQUIRE;
      else
	error_at (cp_lexer_peek_token (parser->lexer)->location,
		  "expected %<seq_cst%>, %<acq_rel%>, %<release%> or "
		  "%<acquire%>");
      cp_lexer_consume_token (parser->lexer);
    }
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      if (mo != MEMMODEL_LAST)
	error_at (cp_lexer_peek_token (parser->lexer)->location,
		  "%<flush%> list specified together with memory order "
		  "clause");
      (void) cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);

  finish_omp_flush (mo);
}

/* Helper function, to parse omp for increment expression.  */

static tree
cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
{
  tree cond = cp_parser_binary_expression (parser, false, true,
					   PREC_NOT_OPERATOR, NULL);
  if (cond == error_mark_node
      || cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
    {
      cp_parser_skip_to_end_of_statement (parser);
      return error_mark_node;
    }

  switch (TREE_CODE (cond))
    {
    case GT_EXPR:
    case GE_EXPR:
    case LT_EXPR:
    case LE_EXPR:
      break;
    case NE_EXPR:
      if (code != OACC_LOOP)
	break;
      gcc_fallthrough ();
    default:
      return error_mark_node;
    }

  /* If decl is an iterator, preserve LHS and RHS of the relational
     expr until finish_omp_for.  */
  if (decl
      && (type_dependent_expression_p (decl)
	  || CLASS_TYPE_P (TREE_TYPE (decl))))
    return cond;

  return build_x_binary_op (cp_expr_loc_or_input_loc (cond),
			    TREE_CODE (cond),
			    TREE_OPERAND (cond, 0), ERROR_MARK,
			    TREE_OPERAND (cond, 1), ERROR_MARK,
			    NULL_TREE, /*overload=*/NULL, tf_warning_or_error);
}

/* Helper function, to parse omp for increment expression.  */

static tree
cp_parser_omp_for_incr (cp_parser *parser, tree decl)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);
  enum tree_code op;
  tree lhs, rhs;
  cp_id_kind idk;
  bool decl_first;

  if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
    {
      op = (token->type == CPP_PLUS_PLUS
	    ? PREINCREMENT_EXPR : PREDECREMENT_EXPR);
      cp_lexer_consume_token (parser->lexer);
      lhs = cp_parser_simple_cast_expression (parser);
      if (lhs != decl
	  && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
	return error_mark_node;
      return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
    }

  lhs = cp_parser_primary_expression (parser, false, false, false, &idk);
  if (lhs != decl
      && (!processing_template_decl || !cp_tree_equal (lhs, decl)))
    return error_mark_node;

  token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_PLUS_PLUS || token->type == CPP_MINUS_MINUS)
    {
      op = (token->type == CPP_PLUS_PLUS
	    ? POSTINCREMENT_EXPR : POSTDECREMENT_EXPR);
      cp_lexer_consume_token (parser->lexer);
      return build2 (op, TREE_TYPE (decl), decl, NULL_TREE);
    }

  op = cp_parser_assignment_operator_opt (parser);
  if (op == ERROR_MARK)
    return error_mark_node;

  if (op != NOP_EXPR)
    {
      rhs = cp_parser_assignment_expression (parser);
      rhs = build2 (op, TREE_TYPE (decl), decl, rhs);
      return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
    }

  lhs = cp_parser_binary_expression (parser, false, false,
				     PREC_ADDITIVE_EXPRESSION, NULL);
  token = cp_lexer_peek_token (parser->lexer);
  decl_first = (lhs == decl
		|| (processing_template_decl && cp_tree_equal (lhs, decl)));
  if (decl_first)
    lhs = NULL_TREE;
  if (token->type != CPP_PLUS
      && token->type != CPP_MINUS)
    return error_mark_node;

  do
    {
      op = token->type == CPP_PLUS ? PLUS_EXPR : MINUS_EXPR;
      cp_lexer_consume_token (parser->lexer);
      rhs = cp_parser_binary_expression (parser, false, false,
					 PREC_ADDITIVE_EXPRESSION, NULL);
      token = cp_lexer_peek_token (parser->lexer);
      if (token->type == CPP_PLUS || token->type == CPP_MINUS || decl_first)
	{
	  if (lhs == NULL_TREE)
	    {
	      if (op == PLUS_EXPR)
		lhs = rhs;
	      else
		lhs = build_x_unary_op (input_location, NEGATE_EXPR, rhs,
					NULL_TREE, tf_warning_or_error);
	    }
	  else
	    lhs = build_x_binary_op (input_location, op,
				     lhs, ERROR_MARK,
				     rhs, ERROR_MARK,
				     NULL_TREE, NULL, tf_warning_or_error);
	}
    }
  while (token->type == CPP_PLUS || token->type == CPP_MINUS);

  if (!decl_first)
    {
      if ((rhs != decl
	   && (!processing_template_decl || !cp_tree_equal (rhs, decl)))
	  || op == MINUS_EXPR)
	return error_mark_node;
      rhs = build2 (op, TREE_TYPE (decl), lhs, decl);
    }
  else
    rhs = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, lhs);

  return build2 (MODIFY_EXPR, TREE_TYPE (decl), decl, rhs);
}

/* Parse the initialization statement of an OpenMP for loop.

   Return true if the resulting construct should have an
   OMP_CLAUSE_PRIVATE added to it.  */

static tree
cp_parser_omp_for_loop_init (cp_parser *parser,
			     tree &this_pre_body,
			     releasing_vec &for_block,
			     tree &init,
			     tree &orig_init,
			     tree &decl,
			     tree &real_decl)
{
  if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
    return NULL_TREE;

  tree add_private_clause = NULL_TREE;

  /* See 2.5.1 (in OpenMP 3.0, similar wording is in 2.5 standard too):

     init-expr:
     var = lb
     integer-type var = lb
     random-access-iterator-type var = lb
     pointer-type var = lb
  */
  cp_decl_specifier_seq type_specifiers;

  /* First, try to parse as an initialized declaration.  See
     cp_parser_condition, from whence the bulk of this is copied.  */

  cp_parser_parse_tentatively (parser);
  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
				/*is_declaration=*/true,
				/*is_trailing_return=*/false,
				&type_specifiers);
  if (cp_parser_parse_definitely (parser))
    {
      /* If parsing a type specifier seq succeeded, then this
	 MUST be a initialized declaration.  */
      tree asm_specification, attributes;
      cp_declarator *declarator;

      declarator = cp_parser_declarator (parser,
					 CP_PARSER_DECLARATOR_NAMED,
					 CP_PARSER_FLAGS_NONE,
					 /*ctor_dtor_or_conv_p=*/NULL,
					 /*parenthesized_p=*/NULL,
					 /*member_p=*/false,
					 /*friend_p=*/false,
					 /*static_p=*/false);
      attributes = cp_parser_attributes_opt (parser);
      asm_specification = cp_parser_asm_specification_opt (parser);

      if (declarator == cp_error_declarator)
	cp_parser_skip_to_end_of_statement (parser);

      else
	{
	  tree pushed_scope, auto_node;

	  decl = start_decl (declarator, &type_specifiers,
			     SD_INITIALIZED, attributes,
			     /*prefix_attributes=*/NULL_TREE,
			     &pushed_scope);

	  auto_node = type_uses_auto (TREE_TYPE (decl));
	  if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
	    {
	      if (cp_lexer_next_token_is (parser->lexer,
					  CPP_OPEN_PAREN))
	        error ("parenthesized initialization is not allowed in "
		       "OpenMP %<for%> loop");
	      else
		/* Trigger an error.  */
		cp_parser_require (parser, CPP_EQ, RT_EQ);

	      init = error_mark_node;
	      cp_parser_skip_to_end_of_statement (parser);
	    }
	  else if (CLASS_TYPE_P (TREE_TYPE (decl))
		   || type_dependent_expression_p (decl)
		   || auto_node)
	    {
	      bool is_direct_init, is_non_constant_init;

	      init = cp_parser_initializer (parser,
					    &is_direct_init,
					    &is_non_constant_init);

	      if (auto_node)
		{
		  TREE_TYPE (decl)
		    = do_auto_deduction (TREE_TYPE (decl), init,
					 auto_node);

		  if (!CLASS_TYPE_P (TREE_TYPE (decl))
		      && !type_dependent_expression_p (decl))
		    goto non_class;
		}

	      cp_finish_decl (decl, init, !is_non_constant_init,
			      asm_specification,
			      LOOKUP_ONLYCONVERTING);
	      orig_init = init;
	      if (CLASS_TYPE_P (TREE_TYPE (decl)))
		{
		  vec_safe_push (for_block, this_pre_body);
		  init = NULL_TREE;
		}
	      else
		{
		  init = pop_stmt_list (this_pre_body);
		  if (init && TREE_CODE (init) == STATEMENT_LIST)
		    {
		      tree_stmt_iterator i = tsi_start (init);
		      /* Move lambda DECL_EXPRs to FOR_BLOCK.  */
		      while (!tsi_end_p (i))
			{
			  tree t = tsi_stmt (i);
			  if (TREE_CODE (t) == DECL_EXPR
			      && TREE_CODE (DECL_EXPR_DECL (t)) == TYPE_DECL)
			    {
			      tsi_delink (&i);
			      vec_safe_push (for_block, t);
			      continue;
			    }
			  break;
			}
		      if (tsi_one_before_end_p (i))
			{
			  tree t = tsi_stmt (i);
			  tsi_delink (&i);
			  free_stmt_list (init);
			  init = t;
			}
		    }
		}
	      this_pre_body = NULL_TREE;
	    }
	  else
	    {
	      /* Consume '='.  */
	      cp_lexer_consume_token (parser->lexer);
	      init = cp_parser_assignment_expression (parser);

	    non_class:
	      if (TYPE_REF_P (TREE_TYPE (decl)))
		init = error_mark_node;
	      else
		cp_finish_decl (decl, NULL_TREE,
				/*init_const_expr_p=*/false,
				asm_specification,
				LOOKUP_ONLYCONVERTING);
	    }

	  if (pushed_scope)
	    pop_scope (pushed_scope);
	}
    }
  else
    {
      cp_id_kind idk;
      /* If parsing a type specifier sequence failed, then
	 this MUST be a simple expression.  */
      cp_parser_parse_tentatively (parser);
      decl = cp_parser_primary_expression (parser, false, false,
					   false, &idk);
      cp_token *last_tok = cp_lexer_peek_token (parser->lexer);
      if (!cp_parser_error_occurred (parser)
	  && decl
	  && (TREE_CODE (decl) == COMPONENT_REF
	      || (TREE_CODE (decl) == SCOPE_REF && TREE_TYPE (decl))))
	{
	  cp_parser_abort_tentative_parse (parser);
	  cp_parser_parse_tentatively (parser);
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  tree name = cp_parser_id_expression (parser, /*template_p=*/false,
					       /*check_dependency_p=*/true,
					       /*template_p=*/NULL,
					       /*declarator_p=*/false,
					       /*optional_p=*/false);
	  if (name != error_mark_node
	      && last_tok == cp_lexer_peek_token (parser->lexer))
	    {
	      decl = cp_parser_lookup_name_simple (parser, name,
						   token->location);
	      if (TREE_CODE (decl) == FIELD_DECL)
		add_private_clause = omp_privatize_field (decl, false);
	    }
	  cp_parser_abort_tentative_parse (parser);
	  cp_parser_parse_tentatively (parser);
	  decl = cp_parser_primary_expression (parser, false, false,
					       false, &idk);
	}
      if (!cp_parser_error_occurred (parser)
	  && decl
	  && DECL_P (decl)
	  && CLASS_TYPE_P (TREE_TYPE (decl)))
	{
	  tree rhs;

	  cp_parser_parse_definitely (parser);
	  cp_parser_require (parser, CPP_EQ, RT_EQ);
	  rhs = cp_parser_assignment_expression (parser);
	  orig_init = rhs;
	  finish_expr_stmt (build_x_modify_expr (EXPR_LOCATION (rhs),
						 decl, NOP_EXPR,
						 rhs, NULL_TREE,
						 tf_warning_or_error));
	  if (!add_private_clause)
	    add_private_clause = decl;
	}
      else
	{
	  decl = NULL;
	  cp_parser_abort_tentative_parse (parser);
	  init = cp_parser_expression (parser);
	  if (init)
	    {
	      if (TREE_CODE (init) == MODIFY_EXPR
		  || TREE_CODE (init) == MODOP_EXPR)
		real_decl = TREE_OPERAND (init, 0);
	    }
	}
    }
  return add_private_clause;
}

/* Helper for cp_parser_omp_for_loop, handle one range-for loop.  */

void
cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
			  tree &decl, tree &orig_decl, tree &init,
			  tree &orig_init, tree &cond, tree &incr)
{
  tree begin, end, range_temp_decl = NULL_TREE;
  tree iter_type, begin_expr, end_expr;
  bool clear_has_value_expr = false;

  if (processing_template_decl)
    {
      if (check_for_bare_parameter_packs (init))
	init = error_mark_node;
      if (!type_dependent_expression_p (init)
	  /* do_auto_deduction doesn't mess with template init-lists.  */
	  && !BRACE_ENCLOSED_INITIALIZER_P (init))
	{
	  tree d = decl;
	  tree decomp_first_name = NULL_TREE;
	  unsigned decomp_cnt = 0;
	  if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
	    {
	      tree v = DECL_VALUE_EXPR (decl);
	      if (TREE_CODE (v) == ARRAY_REF
		  && VAR_P (TREE_OPERAND (v, 0))
		  && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
		{
		  d = TREE_OPERAND (v, 0);
		  decomp_cnt = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
		  decomp_first_name = decl;
		}
	    }
	  do_range_for_auto_deduction (d, init, decomp_first_name, decomp_cnt);
	}
      cond = global_namespace;
      incr = NULL_TREE;
      orig_init = init;
      if (this_pre_body)
	this_pre_body = pop_stmt_list (this_pre_body);
      return;
    }

  init = mark_lvalue_use (init);

  if (decl == error_mark_node || init == error_mark_node)
    /* If an error happened previously do nothing or else a lot of
       unhelpful errors would be issued.  */
    begin_expr = end_expr = iter_type = error_mark_node;
  else
    {
      tree range_temp;

      if (VAR_P (init)
	  && array_of_runtime_bound_p (TREE_TYPE (init)))
	/* Can't bind a reference to an array of runtime bound.  */
	range_temp = init;
      else
	{
	  range_temp = build_range_temp (init);
	  DECL_NAME (range_temp) = NULL_TREE;
	  pushdecl (range_temp);
	  cp_finish_decl (range_temp, init,
			  /*is_constant_init*/false, NULL_TREE,
			  LOOKUP_ONLYCONVERTING);
	  range_temp_decl = range_temp;
	  range_temp = convert_from_reference (range_temp);
	}
      iter_type = cp_parser_perform_range_for_lookup (range_temp,
						      &begin_expr, &end_expr);
    }

  tree end_iter_type = iter_type;
  if (cxx_dialect >= cxx17)
    end_iter_type = cv_unqualified (TREE_TYPE (end_expr));
  end = build_decl (input_location, VAR_DECL, NULL_TREE, end_iter_type);
  TREE_USED (end) = 1;
  DECL_ARTIFICIAL (end) = 1;
  pushdecl (end);
  cp_finish_decl (end, end_expr,
		  /*is_constant_init*/false, NULL_TREE,
		  LOOKUP_ONLYCONVERTING);

  /* The new for initialization statement.  */
  begin = build_decl (input_location, VAR_DECL, NULL_TREE, iter_type);
  TREE_USED (begin) = 1;
  DECL_ARTIFICIAL (begin) = 1;
  pushdecl (begin);
  orig_init = init;
  if (CLASS_TYPE_P (iter_type))
    init = NULL_TREE;
  else
    {
      init = begin_expr;
      begin_expr = NULL_TREE;
    }
  cp_finish_decl (begin, begin_expr,
		  /*is_constant_init*/false, NULL_TREE,
		  LOOKUP_ONLYCONVERTING);

  /* The new for condition.  */
  if (CLASS_TYPE_P (iter_type))
    cond = build2 (NE_EXPR, boolean_type_node, begin, end);
  else
    cond = build_x_binary_op (input_location, NE_EXPR,
			      begin, ERROR_MARK,
			      end, ERROR_MARK,
			      NULL_TREE, NULL, tf_warning_or_error);

  /* The new increment expression.  */
  if (CLASS_TYPE_P (iter_type))
    incr = build2 (PREINCREMENT_EXPR, iter_type, begin, NULL_TREE);
  else
    incr = finish_unary_op_expr (input_location,
				 PREINCREMENT_EXPR, begin,
				 tf_warning_or_error);

  orig_decl = decl;
  decl = begin;
  if (for_block)
    {
      vec_safe_push (for_block, this_pre_body);
      this_pre_body = NULL_TREE;
    }

  tree decomp_first_name = NULL_TREE;
  unsigned decomp_cnt = 0;
  if (orig_decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (orig_decl))
    {
      tree v = DECL_VALUE_EXPR (orig_decl);
      if (TREE_CODE (v) == ARRAY_REF
	  && VAR_P (TREE_OPERAND (v, 0))
	  && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
	{
	  tree d = orig_decl;
	  orig_decl = TREE_OPERAND (v, 0);
	  decomp_cnt = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
	  decomp_first_name = d;
	}
    }

  tree auto_node = type_uses_auto (TREE_TYPE (orig_decl));
  if (auto_node)
    {
      tree t = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
				     NULL_TREE, tf_none);
      if (!error_operand_p (t))
	{
	  TREE_TYPE (orig_decl) = do_auto_deduction (TREE_TYPE (orig_decl),
						     t, auto_node);
	  if (decomp_first_name)
	    {
	      ++processing_template_decl;
	      cp_finish_decomp (orig_decl, decomp_first_name, decomp_cnt);
	      --processing_template_decl;
	      if (!processing_template_decl)
		clear_has_value_expr = true;
	    }
	}
    }

  tree v = make_tree_vec (decomp_cnt + 3);
  TREE_VEC_ELT (v, 0) = range_temp_decl;
  TREE_VEC_ELT (v, 1) = end;
  TREE_VEC_ELT (v, 2) = orig_decl;
  if (clear_has_value_expr)
    TREE_PUBLIC (v) = 1;
  for (unsigned i = 0; i < decomp_cnt; i++)
    {
      if (clear_has_value_expr)
	{
	  /* If cp_finish_decomp was called with processing_template_decl
	     temporarily set to 1, then decomp names will have deduced
	     name but the DECL_VALUE_EXPR will be dependent.  Hide those
	     from folding of other loop initializers e.g. for warning
	     purposes until cp_finish_omp_range_for.  */
	  gcc_checking_assert (DECL_HAS_VALUE_EXPR_P (decomp_first_name));
	  DECL_HAS_VALUE_EXPR_P (decomp_first_name) = 0;
	}
      TREE_VEC_ELT (v, i + 3) = decomp_first_name;
      decomp_first_name = DECL_CHAIN (decomp_first_name);
    }
  orig_decl = tree_cons (NULL_TREE, NULL_TREE, v);
}

/* Helper for cp_parser_omp_for_loop, finalize part of range for
   inside of the collapsed body.  */

void
cp_finish_omp_range_for (tree orig, tree begin)
{
  gcc_assert (TREE_CODE (orig) == TREE_LIST
	      && TREE_CODE (TREE_CHAIN (orig)) == TREE_VEC);
  tree decl = TREE_VEC_ELT (TREE_CHAIN (orig), 2);
  tree decomp_first_name = NULL_TREE;
  unsigned int decomp_cnt = 0;

  if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
    {
      decomp_first_name = TREE_VEC_ELT (TREE_CHAIN (orig), 3);
      decomp_cnt = TREE_VEC_LENGTH (TREE_CHAIN (orig)) - 3;
      if (TREE_PUBLIC (TREE_CHAIN (orig)))
	{
	  /* Undo temporary clearing of DECL_HAS_VALUE_EXPR_P done
	     by cp_convert_omp_range_for above.  */
	  TREE_PUBLIC (TREE_CHAIN (orig)) = 0;
	  tree d = decomp_first_name;
	  for (unsigned i = 0; i < decomp_cnt; i++)
	    {
	      DECL_HAS_VALUE_EXPR_P (d) = 1;
	      d = DECL_CHAIN (d);
	    }
	}
      cp_maybe_mangle_decomp (decl, decomp_first_name, decomp_cnt);
    }

  /* The declaration is initialized with *__begin inside the loop body.  */
  cp_finish_decl (decl,
		  build_x_indirect_ref (input_location, begin, RO_UNARY_STAR,
					NULL_TREE, tf_warning_or_error),
		  /*is_constant_init*/false, NULL_TREE,
		  LOOKUP_ONLYCONVERTING);
  if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
    cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
}

/* Return true if next tokens contain a standard attribute that contains
   omp::directive (DIRECTIVE).  */

static bool
cp_parser_omp_section_scan (cp_parser *parser, const char *directive,
			    bool tentative)
{
  size_t n = cp_parser_skip_attributes_opt (parser, 1), i;
  if (n < 10)
    return false;
  for (i = 5; i < n - 4; i++)
    if (cp_lexer_nth_token_is (parser->lexer, i, CPP_NAME)
	&& cp_lexer_nth_token_is (parser->lexer, i + 1, CPP_OPEN_PAREN)
	&& cp_lexer_nth_token_is (parser->lexer, i + 2, CPP_NAME))
      {
	tree first = cp_lexer_peek_nth_token (parser->lexer, i)->u.value;
	tree second = cp_lexer_peek_nth_token (parser->lexer, i + 2)->u.value;
	if (strcmp (IDENTIFIER_POINTER (first), "directive"))
	  continue;
	if (strcmp (IDENTIFIER_POINTER (second), directive) == 0)
	  break;
      }
  if (i == n - 4)
    return false;
  cp_parser_parse_tentatively (parser);
  location_t first_loc = cp_lexer_peek_token (parser->lexer)->location;
  location_t last_loc
    = cp_lexer_peek_nth_token (parser->lexer, n - 1)->location;
  location_t middle_loc = UNKNOWN_LOCATION;
  tree std_attrs = cp_parser_std_attribute_spec_seq (parser);
  int cnt = 0;
  bool seen = false;
  for (tree attr = std_attrs; attr; attr = TREE_CHAIN (attr))
    if (get_attribute_namespace (attr) == omp_identifier
	&& is_attribute_p ("directive", get_attribute_name (attr)))
      {
	for (tree a = TREE_VALUE (attr); a; a = TREE_CHAIN (a))
	  {
	    tree d = TREE_VALUE (a);
	    gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
	    cp_token *first = DEFPARSE_TOKENS (d)->first;
	    cnt++;
	    if (first->type == CPP_NAME
		&& strcmp (IDENTIFIER_POINTER (first->u.value),
			   directive) == 0)
	      {
		seen = true;
		if (middle_loc == UNKNOWN_LOCATION)
		  middle_loc = first->location;
	      }
	  }
      }
  if (!seen || tentative)
    {
      cp_parser_abort_tentative_parse (parser);
      return seen;
    }
  if (cnt != 1 || TREE_CHAIN (std_attrs))
    {
      error_at (make_location (first_loc, last_loc, middle_loc),
		"%<[[omp::directive(%s)]]%> must be the only specified "
		"attribute on a statement", directive);
      cp_parser_abort_tentative_parse (parser);
      return false;
    }
  if (!cp_parser_parse_definitely (parser))
    return false;
  cp_parser_handle_statement_omp_attributes (parser, std_attrs);
  return true;
}

/* Parse an OpenMP structured block sequence.  KIND is the corresponding
   separating directive.  */

static tree
cp_parser_omp_structured_block_sequence (cp_parser *parser,
					 enum pragma_kind kind)
{
  tree stmt = begin_omp_structured_block ();
  unsigned int save = cp_parser_begin_omp_structured_block (parser);

  cp_parser_statement (parser, NULL_TREE, false, NULL);
  while (true)
    {
      cp_token *token = cp_lexer_peek_token (parser->lexer);

      if (token->type == CPP_CLOSE_BRACE
	  || token->type == CPP_EOF
	  || token->type == CPP_PRAGMA_EOL
	  || (token->type == CPP_KEYWORD && token->keyword == RID_AT_END)
	  || (kind != PRAGMA_NONE
	      && cp_parser_pragma_kind (token) == kind))
	break;

      if (kind != PRAGMA_NONE
	  && cp_parser_omp_section_scan (parser,
					 kind == PRAGMA_OMP_SCAN
					 ? "scan" : "section", false))
	break;

      cp_parser_statement (parser, NULL_TREE, false, NULL);
    }

  cp_parser_end_omp_structured_block (parser, save);
  return finish_omp_structured_block (stmt);
}


/* OpenMP 5.0:

   scan-loop-body:
     { structured-block scan-directive structured-block }  */

static void
cp_parser_omp_scan_loop_body (cp_parser *parser)
{
  tree substmt, clauses = NULL_TREE;

  matching_braces braces;
  if (!braces.require_open (parser))
    return;

  substmt = cp_parser_omp_structured_block_sequence (parser, PRAGMA_OMP_SCAN);
  substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
  add_stmt (substmt);

  cp_token *tok = cp_lexer_peek_token (parser->lexer);
  if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SCAN)
    {
      enum omp_clause_code clause = OMP_CLAUSE_ERROR;

      cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  const char *p = IDENTIFIER_POINTER (id);
	  if (strcmp (p, "inclusive") == 0)
	    clause = OMP_CLAUSE_INCLUSIVE;
	  else if (strcmp (p, "exclusive") == 0)
	    clause = OMP_CLAUSE_EXCLUSIVE;
	}
      if (clause != OMP_CLAUSE_ERROR)
	{
	  cp_lexer_consume_token (parser->lexer);
	  clauses = cp_parser_omp_var_list (parser, clause, NULL_TREE);
	}
      else
	cp_parser_error (parser, "expected %<inclusive%> or "
				 "%<exclusive%> clause");

      cp_parser_require_pragma_eol (parser, tok);
    }
  else
    error ("expected %<#pragma omp scan%>");

  clauses = finish_omp_clauses (clauses, C_ORT_OMP);
  substmt = cp_parser_omp_structured_block_sequence (parser, PRAGMA_NONE);
  substmt = build2_loc (tok->location, OMP_SCAN, void_type_node, substmt,
			clauses);
  add_stmt (substmt);

  braces.require_close (parser);
}

/* Parse the restricted form of the for statement allowed by OpenMP.  */

static tree
cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
			tree *cclauses, bool *if_p)
{
  tree init, orig_init, cond, incr, body, decl, pre_body = NULL_TREE, ret;
  tree orig_decl;
  tree real_decl, initv, condv, incrv, declv, orig_declv;
  tree this_pre_body, cl, ordered_cl = NULL_TREE;
  location_t loc_first;
  bool collapse_err = false;
  int i, collapse = 1, ordered = 0, count, nbraces = 0;
  releasing_vec for_block;
  auto_vec<tree, 4> orig_inits;
  bool tiling = false;
  bool inscan = false;

  for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl))
    if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE)
      collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl));
    else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE)
      {
	tiling = true;
	collapse = list_length (OMP_CLAUSE_TILE_LIST (cl));
      }
    else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED
	     && OMP_CLAUSE_ORDERED_EXPR (cl))
      {
	ordered_cl = cl;
	ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (cl));
      }
    else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_REDUCTION
	     && OMP_CLAUSE_REDUCTION_INSCAN (cl)
	     && (code == OMP_SIMD || code == OMP_FOR))
      inscan = true;

  if (ordered && ordered < collapse)
    {
      error_at (OMP_CLAUSE_LOCATION (ordered_cl),
		"%<ordered%> clause parameter is less than %<collapse%>");
      OMP_CLAUSE_ORDERED_EXPR (ordered_cl)
	= build_int_cst (NULL_TREE, collapse);
      ordered = collapse;
    }

  gcc_assert (tiling || (collapse >= 1 && ordered >= 0));
  count = ordered ? ordered : collapse;

  declv = make_tree_vec (count);
  initv = make_tree_vec (count);
  condv = make_tree_vec (count);
  incrv = make_tree_vec (count);
  orig_declv = NULL_TREE;

  loc_first = cp_lexer_peek_token (parser->lexer)->location;

  for (i = 0; i < count; i++)
    {
      int bracecount = 0;
      tree add_private_clause = NULL_TREE;
      location_t loc;

      if (!cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
	{
	  if (!collapse_err)
	    cp_parser_error (parser, "for statement expected");
	  return NULL;
	}
      loc = cp_lexer_consume_token (parser->lexer)->location;

      /* Don't create location wrapper nodes within an OpenMP "for"
	 statement.  */
      auto_suppress_location_wrappers sentinel;

      matching_parens parens;
      if (!parens.require_open (parser))
	return NULL;

      init = orig_init = decl = real_decl = orig_decl = NULL_TREE;
      this_pre_body = push_stmt_list ();

      if (code != OACC_LOOP && cxx_dialect >= cxx11)
	{
	  /* Save tokens so that we can put them back.  */
	  cp_lexer_save_tokens (parser->lexer);

	  /* Look for ':' that is not nested in () or {}.  */
	  bool is_range_for
	    = (cp_parser_skip_to_closing_parenthesis_1 (parser,
							/*recovering=*/false,
							CPP_COLON,
							/*consume_paren=*/
							false) == -1);

	  /* Roll back the tokens we skipped.  */
	  cp_lexer_rollback_tokens (parser->lexer);

	  if (is_range_for)
	    {
	      bool saved_colon_corrects_to_scope_p
		= parser->colon_corrects_to_scope_p;

	      /* A colon is used in range-based for.  */
	      parser->colon_corrects_to_scope_p = false;

	      /* Parse the declaration.  */
	      cp_parser_simple_declaration (parser,
					    /*function_definition_allowed_p=*/
					    false, &decl);
	      parser->colon_corrects_to_scope_p
		= saved_colon_corrects_to_scope_p;

	      cp_parser_require (parser, CPP_COLON, RT_COLON);

	      init = cp_parser_range_for (parser, NULL_TREE, NULL_TREE, decl,
					  false, 0, true);

	      cp_convert_omp_range_for (this_pre_body, for_block, decl,
					orig_decl, init, orig_init,
					cond, incr);
	      if (this_pre_body)
		{
		  if (pre_body)
		    {
		      tree t = pre_body;
		      pre_body = push_stmt_list ();
		      add_stmt (t);
		      add_stmt (this_pre_body);
		      pre_body = pop_stmt_list (pre_body);
		    }
		  else
		    pre_body = this_pre_body;
		}

	      if (ordered_cl)
		error_at (OMP_CLAUSE_LOCATION (ordered_cl),
			  "%<ordered%> clause with parameter on "
			  "range-based %<for%> loop");

	      goto parse_close_paren;
	    }
	}

      add_private_clause
	= cp_parser_omp_for_loop_init (parser, this_pre_body, for_block,
				       init, orig_init, decl, real_decl);

      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
      if (this_pre_body)
	{
	  this_pre_body = pop_stmt_list (this_pre_body);
	  if (pre_body)
	    {
	      tree t = pre_body;
	      pre_body = push_stmt_list ();
	      add_stmt (t);
	      add_stmt (this_pre_body);
	      pre_body = pop_stmt_list (pre_body);
	    }
	  else
	    pre_body = this_pre_body;
	}

      if (decl)
	real_decl = decl;
      if (cclauses != NULL
	  && cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL
	  && real_decl != NULL_TREE
	  && code != OMP_LOOP)
	{
	  tree *c;
	  for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
	    if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_FIRSTPRIVATE
		&& OMP_CLAUSE_DECL (*c) == real_decl)
	      {
		error_at (loc, "iteration variable %qD"
			  " should not be firstprivate", real_decl);
		*c = OMP_CLAUSE_CHAIN (*c);
	      }
	    else if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_LASTPRIVATE
		     && OMP_CLAUSE_DECL (*c) == real_decl)
	      {
		/* Move lastprivate (decl) clause to OMP_FOR_CLAUSES.  */
		tree l = *c;
		*c = OMP_CLAUSE_CHAIN (*c);
		if (code == OMP_SIMD)
		  {
		    OMP_CLAUSE_CHAIN (l) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
		    cclauses[C_OMP_CLAUSE_SPLIT_FOR] = l;
		  }
		else
		  {
		    OMP_CLAUSE_CHAIN (l) = clauses;
		    clauses = l;
		  }
		add_private_clause = NULL_TREE;
	      }
	    else
	      {
		if (OMP_CLAUSE_CODE (*c) == OMP_CLAUSE_PRIVATE
		    && OMP_CLAUSE_DECL (*c) == real_decl)
		  add_private_clause = NULL_TREE;
		c = &OMP_CLAUSE_CHAIN (*c);
	      }
	}

      if (add_private_clause)
	{
	  tree c;
	  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
	    {
	      if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
		   || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
		  && OMP_CLAUSE_DECL (c) == decl)
		break;
	      else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE
		       && OMP_CLAUSE_DECL (c) == decl)
		error_at (loc, "iteration variable %qD "
			  "should not be firstprivate",
			  decl);
	      else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
			|| OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
		       && OMP_CLAUSE_DECL (c) == decl)
		error_at (loc, "iteration variable %qD should not be reduction",
			  decl);
	    }
	  if (c == NULL)
	    {
	      if ((code == OMP_SIMD && collapse != 1) || code == OMP_LOOP)
		c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
	      else if (code != OMP_SIMD)
		c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
	      else
		c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
	      OMP_CLAUSE_DECL (c) = add_private_clause;
	      c = finish_omp_clauses (c, C_ORT_OMP);
	      if (c)
		{
		  OMP_CLAUSE_CHAIN (c) = clauses;
		  clauses = c;
		  /* For linear, signal that we need to fill up
		     the so far unknown linear step.  */
		  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
		    OMP_CLAUSE_LINEAR_STEP (c) = NULL_TREE;
		}
	    }
	}

      cond = NULL;
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	cond = cp_parser_omp_for_cond (parser, decl, code);
      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

      incr = NULL;
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_PAREN))
	{
	  /* If decl is an iterator, preserve the operator on decl
	     until finish_omp_for.  */
	  if (real_decl
	      && ((processing_template_decl
		   && (TREE_TYPE (real_decl) == NULL_TREE
		       || !INDIRECT_TYPE_P (TREE_TYPE (real_decl))))
		  || CLASS_TYPE_P (TREE_TYPE (real_decl))))
	    incr = cp_parser_omp_for_incr (parser, real_decl);
	  else
	    incr = cp_parser_expression (parser);
	  protected_set_expr_location_if_unset (incr, input_location);
	}

    parse_close_paren:
      if (!parens.require_close (parser))
	cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
					       /*or_comma=*/false,
					       /*consume_paren=*/true);

      TREE_VEC_ELT (declv, i) = decl;
      TREE_VEC_ELT (initv, i) = init;
      TREE_VEC_ELT (condv, i) = cond;
      TREE_VEC_ELT (incrv, i) = incr;
      if (orig_init)
	{
	  orig_inits.safe_grow_cleared (i + 1, true);
	  orig_inits[i] = orig_init;
	}
      if (orig_decl)
	{
	  if (!orig_declv)
	    orig_declv = copy_node (declv);
	  TREE_VEC_ELT (orig_declv, i) = orig_decl;
	}
      else if (orig_declv)
	TREE_VEC_ELT (orig_declv, i) = decl;

      if (i == count - 1)
	break;

      /* FIXME: OpenMP 3.0 draft isn't very clear on what exactly is allowed
	 in between the collapsed for loops to be still considered perfectly
	 nested.  Hopefully the final version clarifies this.
	 For now handle (multiple) {'s and empty statements.  */
      cp_parser_parse_tentatively (parser);
      for (;;)
	{
	  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
	    break;
	  else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      bracecount++;
	    }
	  else if (bracecount
		   && cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	    cp_lexer_consume_token (parser->lexer);
	  else
	    {
	      loc = cp_lexer_peek_token (parser->lexer)->location;
	      error_at (loc, "not enough for loops to collapse");
	      collapse_err = true;
	      cp_parser_abort_tentative_parse (parser);
	      declv = NULL_TREE;
	      break;
	    }
	}

      if (declv)
	{
	  cp_parser_parse_definitely (parser);
	  nbraces += bracecount;
	}
    }

  if (nbraces)
    if_p = NULL;

  /* Note that we saved the original contents of this flag when we entered
     the structured block, and so we don't need to re-save it here.  */
  parser->in_statement = IN_OMP_FOR;

  /* Note that the grammar doesn't call for a structured block here,
     though the loop as a whole is a structured block.  */
  if (orig_declv)
    {
      body = begin_omp_structured_block ();
      for (i = 0; i < count; i++)
	if (TREE_VEC_ELT (orig_declv, i) != TREE_VEC_ELT (declv, i))
	  cp_finish_omp_range_for (TREE_VEC_ELT (orig_declv, i),
				   TREE_VEC_ELT (declv, i));
    }
  else
    body = push_stmt_list ();
  if (inscan)
    cp_parser_omp_scan_loop_body (parser);
  else
    cp_parser_statement (parser, NULL_TREE, false, if_p);
  if (orig_declv)
    body = finish_omp_structured_block (body);
  else
    body = pop_stmt_list (body);

  if (declv == NULL_TREE)
    ret = NULL_TREE;
  else
    ret = finish_omp_for (loc_first, code, declv, orig_declv, initv, condv,
			  incrv, body, pre_body, &orig_inits, clauses);

  while (nbraces)
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
	{
	  cp_lexer_consume_token (parser->lexer);
	  nbraces--;
	}
      else if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	cp_lexer_consume_token (parser->lexer);
      else
	{
	  if (!collapse_err)
	    {
	      error_at (cp_lexer_peek_token (parser->lexer)->location,
			"collapsed loops not perfectly nested");
	    }
	  collapse_err = true;
	  cp_parser_statement_seq_opt (parser, NULL);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_EOF))
	    break;
	}
    }

  while (!for_block->is_empty ())
    {
      tree t = for_block->pop ();
      if (TREE_CODE (t) == STATEMENT_LIST)
	add_stmt (pop_stmt_list (t));
      else
	add_stmt (t);
    }

  return ret;
}

/* Helper function for OpenMP parsing, split clauses and call
   finish_omp_clauses on each of the set of clauses afterwards.  */

static void
cp_omp_split_clauses (location_t loc, enum tree_code code,
		      omp_clause_mask mask, tree clauses, tree *cclauses)
{
  int i;
  c_omp_split_clauses (loc, code, mask, clauses, cclauses);
  for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
    if (cclauses[i])
      cclauses[i] = finish_omp_clauses (cclauses[i],
					i == C_OMP_CLAUSE_SPLIT_TARGET
					? C_ORT_OMP_TARGET : C_ORT_OMP);
}

/* OpenMP 5.0:
   #pragma omp loop loop-clause[optseq] new-line
     for-loop  */

#define OMP_LOOP_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_BIND)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))

static tree
cp_parser_omp_loop (cp_parser *parser, cp_token *pragma_tok,
		    char *p_name, omp_clause_mask mask, tree *cclauses,
		    bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " loop");
  mask |= OMP_LOOP_CLAUSE_MASK;

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_LOOP, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_LOOP];
    }

  keep_next_level (true);
  sb = begin_omp_structured_block ();
  save = cp_parser_begin_omp_structured_block (parser);

  ret = cp_parser_omp_for_loop (parser, OMP_LOOP, clauses, cclauses, if_p);

  cp_parser_end_omp_structured_block (parser, save);
  add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));

  return ret;
}

/* OpenMP 4.0:
   #pragma omp simd simd-clause[optseq] new-line
     for-loop  */

#define OMP_SIMD_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SAFELEN)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NONTEMPORAL)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))

static tree
cp_parser_omp_simd (cp_parser *parser, cp_token *pragma_tok,
		    char *p_name, omp_clause_mask mask, tree *cclauses,
		    bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " simd");
  mask |= OMP_SIMD_CLAUSE_MASK;

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_SIMD, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_SIMD];
    }

  keep_next_level (true);
  sb = begin_omp_structured_block ();
  save = cp_parser_begin_omp_structured_block (parser);

  ret = cp_parser_omp_for_loop (parser, OMP_SIMD, clauses, cclauses, if_p);

  cp_parser_end_omp_structured_block (parser, save);
  add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));

  return ret;
}

/* OpenMP 2.5:
   #pragma omp for for-clause[optseq] new-line
     for-loop

   OpenMP 4.0:
   #pragma omp for simd for-simd-clause[optseq] new-line
     for-loop  */

#define OMP_FOR_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SCHEDULE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))

static tree
cp_parser_omp_for (cp_parser *parser, cp_token *pragma_tok,
		   char *p_name, omp_clause_mask mask, tree *cclauses,
		   bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " for");
  mask |= OMP_FOR_CLAUSE_MASK;
  /* parallel for{, simd} disallows nowait clause, but for
     target {teams distribute ,}parallel for{, simd} it should be accepted.  */
  if (cclauses && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) == 0)
    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);
  /* Composite distribute parallel for{, simd} disallows ordered clause.  */
  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDERED);

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "simd") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
				       cclauses, if_p);
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
				    cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  ret = make_node (OMP_FOR);
	  TREE_TYPE (ret) = void_type_node;
	  OMP_FOR_BODY (ret) = body;
	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
	  SET_EXPR_LOCATION (ret, loc);
	  add_stmt (ret);
	  return ret;
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  /* Composite distribute parallel for disallows linear clause.  */
  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR);

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_FOR, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_FOR];
    }

  keep_next_level (true);
  sb = begin_omp_structured_block ();
  save = cp_parser_begin_omp_structured_block (parser);

  ret = cp_parser_omp_for_loop (parser, OMP_FOR, clauses, cclauses, if_p);

  cp_parser_end_omp_structured_block (parser, save);
  add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));

  return ret;
}

static tree cp_parser_omp_taskloop (cp_parser *, cp_token *, char *,
				    omp_clause_mask, tree *, bool *);

/* OpenMP 2.5:
   # pragma omp master new-line
     structured-block  */

static tree
cp_parser_omp_master (cp_parser *parser, cp_token *pragma_tok,
		      char *p_name, omp_clause_mask mask, tree *cclauses,
		      bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " master");

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "taskloop") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
					   cclauses, if_p);
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
					cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  ret = c_finish_omp_master (loc, body);
	  OMP_MASTER_COMBINED (ret) = 1;
	  return ret;
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  if (cclauses)
    {
      clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
					   false);
      cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
    }
  else
    cp_parser_require_pragma_eol (parser, pragma_tok);

  return c_finish_omp_master (loc,
			      cp_parser_omp_structured_block (parser, if_p));
}

/* OpenMP 5.1:
   # pragma omp masked masked-clauses new-line
     structured-block  */

#define OMP_MASKED_CLAUSE_MASK					\
	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FILTER)

static tree
cp_parser_omp_masked (cp_parser *parser, cp_token *pragma_tok,
		      char *p_name, omp_clause_mask mask, tree *cclauses,
		      bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " masked");
  mask |= OMP_MASKED_CLAUSE_MASK;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "taskloop") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
					   cclauses, if_p);
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  ret = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask,
					cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  ret = c_finish_omp_masked (loc, body,
				     cclauses[C_OMP_CLAUSE_SPLIT_MASKED]);
	  OMP_MASKED_COMBINED (ret) = 1;
	  return ret;
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_MASTER, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_MASKED];
    }

  return c_finish_omp_masked (loc,
			      cp_parser_omp_structured_block (parser, if_p),
			      clauses);
}

/* OpenMP 2.5:
   # pragma omp ordered new-line
     structured-block

   OpenMP 4.5:
   # pragma omp ordered ordered-clauses new-line
     structured-block  */

#define OMP_ORDERED_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREADS)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMD))

#define OMP_ORDERED_DEPEND_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DOACROSS))

static bool
cp_parser_omp_ordered (cp_parser *parser, cp_token *pragma_tok,
		       enum pragma_context context, bool *if_p)
{
  location_t loc = pragma_tok->location;
  int n = 1;

  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
    n = 2;

  if (cp_lexer_nth_token_is (parser->lexer, n, CPP_NAME))
    {
      tree id = cp_lexer_peek_nth_token (parser->lexer, n)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "depend") == 0 || strcmp (p, "doacross") == 0)
	{
	  if (!flag_openmp)	/* flag_openmp_simd */
	    {
	      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	      return false;
	    }
	  if (context == pragma_stmt)
	    {
	      error_at (pragma_tok->location, "%<#pragma omp ordered%> with "
			"%qs clause may only be used in compound "
			"statements", p);
	      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	      return true;
	    }
	  tree clauses
	    = cp_parser_omp_all_clauses (parser,
					 OMP_ORDERED_DEPEND_CLAUSE_MASK,
					 "#pragma omp ordered", pragma_tok);
	  c_finish_omp_ordered (loc, clauses, NULL_TREE);
	  return false;
	}
    }

  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_ORDERED_CLAUSE_MASK,
				 "#pragma omp ordered", pragma_tok);

  if (!flag_openmp     /* flag_openmp_simd  */
      && omp_find_clause (clauses, OMP_CLAUSE_SIMD) == NULL_TREE)
    return false;

  c_finish_omp_ordered (loc, clauses,
			cp_parser_omp_structured_block (parser, if_p));
  return true;
}

/* OpenMP 2.5:

   section-scope:
     { section-sequence }

   section-sequence:
     section-directive[opt] structured-block
     section-sequence section-directive structured-block  */

static tree
cp_parser_omp_sections_scope (cp_parser *parser)
{
  tree stmt, substmt;
  bool error_suppress = false;
  cp_token *tok;

  matching_braces braces;
  if (!braces.require_open (parser))
    return NULL_TREE;

  stmt = push_stmt_list ();

  if (cp_parser_pragma_kind (cp_lexer_peek_token (parser->lexer))
      != PRAGMA_OMP_SECTION
      && !cp_parser_omp_section_scan (parser, "section", true))
    {
      substmt = cp_parser_omp_structured_block_sequence (parser,
							 PRAGMA_OMP_SECTION);
      substmt = build1 (OMP_SECTION, void_type_node, substmt);
      add_stmt (substmt);
    }

  while (1)
    {
      tok = cp_lexer_peek_token (parser->lexer);
      if (tok->type == CPP_CLOSE_BRACE)
	break;
      if (tok->type == CPP_EOF)
	break;

      if (cp_parser_omp_section_scan (parser, "section", false))
	tok = cp_lexer_peek_token (parser->lexer);
      if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SECTION)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_require_pragma_eol (parser, tok);
	  error_suppress = false;
	}
      else if (!error_suppress)
	{
	  cp_parser_error (parser, "expected %<#pragma omp section%> or %<}%>");
	  error_suppress = true;
	}

      substmt = cp_parser_omp_structured_block_sequence (parser,
							 PRAGMA_OMP_SECTION);
      substmt = build1 (OMP_SECTION, void_type_node, substmt);
      add_stmt (substmt);
    }
  braces.require_close (parser);

  substmt = pop_stmt_list (stmt);

  stmt = make_node (OMP_SECTIONS);
  TREE_TYPE (stmt) = void_type_node;
  OMP_SECTIONS_BODY (stmt) = substmt;

  add_stmt (stmt);
  return stmt;
}

/* OpenMP 2.5:
   # pragma omp sections sections-clause[optseq] newline
     sections-scope  */

#define OMP_SECTIONS_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static tree
cp_parser_omp_sections (cp_parser *parser, cp_token *pragma_tok,
			char *p_name, omp_clause_mask mask, tree *cclauses)
{
  tree clauses, ret;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " sections");
  mask |= OMP_SECTIONS_CLAUSE_MASK;
  if (cclauses)
    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT);

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_SECTIONS, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_SECTIONS];
    }

  ret = cp_parser_omp_sections_scope (parser);
  if (ret)
    OMP_SECTIONS_CLAUSES (ret) = clauses;

  return ret;
}

/* OpenMP 2.5:
   # pragma omp parallel parallel-clause[optseq] new-line
     structured-block
   # pragma omp parallel for parallel-for-clause[optseq] new-line
     structured-block
   # pragma omp parallel sections parallel-sections-clause[optseq] new-line
     structured-block

   OpenMP 4.0:
   # pragma omp parallel for simd parallel-for-simd-clause[optseq] new-line
     structured-block */

#define OMP_PARALLEL_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PROC_BIND))

static tree
cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
			char *p_name, omp_clause_mask mask, tree *cclauses,
			bool *if_p)
{
  tree stmt, clauses, block;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " parallel");
  mask |= OMP_PARALLEL_CLAUSE_MASK;
  /* #pragma omp target parallel{, for, for simd} disallow copyin clause.  */
  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)) != 0
      && (mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) == 0)
    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYIN);

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR))
    {
      tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
      if (cclauses == NULL)
	cclauses = cclauses_buf;

      cp_lexer_consume_token (parser->lexer);
      if (!flag_openmp)  /* flag_openmp_simd  */
	return cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses,
				  if_p);
      block = begin_omp_parallel ();
      save = cp_parser_begin_omp_structured_block (parser);
      tree ret = cp_parser_omp_for (parser, pragma_tok, p_name, mask, cclauses,
				    if_p);
      cp_parser_end_omp_structured_block (parser, save);
      stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
				  block);
      if (ret == NULL_TREE)
	return ret;
      OMP_PARALLEL_COMBINED (stmt) = 1;
      return stmt;
    }
  /* When combined with distribute, parallel has to be followed by for.
     #pragma omp target parallel is allowed though.  */
  else if (cclauses
	   && (mask & (OMP_CLAUSE_MASK_1
		       << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)) != 0)
    {
      error_at (loc, "expected %<for%> after %qs", p_name);
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }
  else if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      if (cclauses == NULL && strcmp (p, "masked") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
					 cclauses, if_p);
	  block = begin_omp_parallel ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  tree ret = cp_parser_omp_masked (parser, pragma_tok, p_name, mask,
					   cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
				      block);
	  if (ret == NULL_TREE)
	    return ret;
	  /* masked does have just filter clause, but during gimplification
	     isn't represented by a gimplification omp context, so for
	     #pragma omp parallel masked don't set OMP_PARALLEL_COMBINED,
	     so that
	     #pragma omp parallel masked
	     #pragma omp taskloop simd lastprivate (x)
	     isn't confused with
	     #pragma omp parallel masked taskloop simd lastprivate (x)  */
	  if (OMP_MASKED_COMBINED (ret))
	    OMP_PARALLEL_COMBINED (stmt) = 1;
	  return stmt;
	}
      else if (cclauses == NULL && strcmp (p, "master") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_master (parser, pragma_tok, p_name, mask,
					 cclauses, if_p);
	  block = begin_omp_parallel ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  tree ret = cp_parser_omp_master (parser, pragma_tok, p_name, mask,
					   cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
				      block);
	  if (ret == NULL_TREE)
	    return ret;
	  /* master doesn't have any clauses and during gimplification
	     isn't represented by a gimplification omp context, so for
	     #pragma omp parallel master don't set OMP_PARALLEL_COMBINED,
	     so that
	     #pragma omp parallel master
	     #pragma omp taskloop simd lastprivate (x)
	     isn't confused with
	     #pragma omp parallel master taskloop simd lastprivate (x)  */
	  if (OMP_MASTER_COMBINED (ret))
	    OMP_PARALLEL_COMBINED (stmt) = 1;
	  return stmt;
	}
      else if (strcmp (p, "loop") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
				       cclauses, if_p);
	  block = begin_omp_parallel ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  tree ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
					 cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
				      block);
	  if (ret == NULL_TREE)
	    return ret;
	  OMP_PARALLEL_COMBINED (stmt) = 1;
	  return stmt;
	}
      else if (!flag_openmp)  /* flag_openmp_simd  */
	{
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  return NULL_TREE;
	}
      else if (cclauses == NULL && strcmp (p, "sections") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  block = begin_omp_parallel ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  cp_parser_omp_sections (parser, pragma_tok, p_name, mask, cclauses);
	  cp_parser_end_omp_structured_block (parser, save);
	  stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
				      block);
	  OMP_PARALLEL_COMBINED (stmt) = 1;
	  return stmt;
	}
    }
  else if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_PARALLEL, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL];
    }

  block = begin_omp_parallel ();
  save = cp_parser_begin_omp_structured_block (parser);
  parser->omp_attrs_forbidden_p = true;
  cp_parser_statement (parser, NULL_TREE, false, if_p);
  cp_parser_end_omp_structured_block (parser, save);
  stmt = finish_omp_parallel (clauses, block);
  return stmt;
}

/* OpenMP 2.5:
   # pragma omp single single-clause[optseq] new-line
     structured-block  */

#define OMP_SINGLE_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COPYPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static tree
cp_parser_omp_single (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree stmt = make_node (OMP_SINGLE);
  TREE_TYPE (stmt) = void_type_node;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);

  OMP_SINGLE_CLAUSES (stmt)
    = cp_parser_omp_all_clauses (parser, OMP_SINGLE_CLAUSE_MASK,
				 "#pragma omp single", pragma_tok);
  OMP_SINGLE_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);

  return add_stmt (stmt);
}

/* OpenMP 5.1:
   # pragma omp scope scope-clause[optseq] new-line
     structured-block  */

#define OMP_SCOPE_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static tree
cp_parser_omp_scope (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree stmt = make_node (OMP_SCOPE);
  TREE_TYPE (stmt) = void_type_node;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);

  OMP_SCOPE_CLAUSES (stmt)
    = cp_parser_omp_all_clauses (parser, OMP_SCOPE_CLAUSE_MASK,
				 "#pragma omp scope", pragma_tok);
  OMP_SCOPE_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);

  return add_stmt (stmt);
}

/* OpenMP 3.0:
   # pragma omp task task-clause[optseq] new-line
     structured-block  */

#define OMP_TASK_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DETACH)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_AFFINITY))

static tree
cp_parser_omp_task (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree clauses, block;
  unsigned int save;

  clauses = cp_parser_omp_all_clauses (parser, OMP_TASK_CLAUSE_MASK,
				       "#pragma omp task", pragma_tok);
  block = begin_omp_task ();
  save = cp_parser_begin_omp_structured_block (parser);
  parser->omp_attrs_forbidden_p = true;
  cp_parser_statement (parser, NULL_TREE, false, if_p);
  cp_parser_end_omp_structured_block (parser, save);
  return finish_omp_task (clauses, block);
}

/* OpenMP 3.0:
   # pragma omp taskwait new-line

   OpenMP 5.0:
   # pragma omp taskwait taskwait-clause[opt] new-line  */

#define OMP_TASKWAIT_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static void
cp_parser_omp_taskwait (cp_parser *parser, cp_token *pragma_tok)
{
  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_TASKWAIT_CLAUSE_MASK,
				 "#pragma omp taskwait", pragma_tok);

  if (clauses)
    {
      tree stmt = make_node (OMP_TASK);
      TREE_TYPE (stmt) = void_node;
      OMP_TASK_CLAUSES (stmt) = clauses;
      OMP_TASK_BODY (stmt) = NULL_TREE;
      SET_EXPR_LOCATION (stmt, pragma_tok->location);
      add_stmt (stmt);
    }
  else
    finish_omp_taskwait ();
}

/* OpenMP 3.1:
   # pragma omp taskyield new-line  */

static void
cp_parser_omp_taskyield (cp_parser *parser, cp_token *pragma_tok)
{
  cp_parser_require_pragma_eol (parser, pragma_tok);
  finish_omp_taskyield ();
}

/* OpenMP 4.0:
   # pragma omp taskgroup new-line
     structured-block

   OpenMP 5.0:
   # pragma omp taskgroup taskgroup-clause[optseq] new-line  */

#define OMP_TASKGROUP_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASK_REDUCTION))

static tree
cp_parser_omp_taskgroup (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_TASKGROUP_CLAUSE_MASK,
				 "#pragma omp taskgroup", pragma_tok);
  return c_finish_omp_taskgroup (input_location,
				 cp_parser_omp_structured_block (parser,
								 if_p),
				 clauses);
}


/* OpenMP 2.5:
   # pragma omp threadprivate (variable-list) */

static void
cp_parser_omp_threadprivate (cp_parser *parser, cp_token *pragma_tok)
{
  tree vars;

  vars = cp_parser_omp_var_list (parser, OMP_CLAUSE_ERROR, NULL);
  cp_parser_require_pragma_eol (parser, pragma_tok);

  finish_omp_threadprivate (vars);
}

/* OpenMP 4.0:
   # pragma omp cancel cancel-clause[optseq] new-line  */

#define OMP_CANCEL_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF))

static void
cp_parser_omp_cancel (cp_parser *parser, cp_token *pragma_tok)
{
  tree clauses = cp_parser_omp_all_clauses (parser, OMP_CANCEL_CLAUSE_MASK,
					    "#pragma omp cancel", pragma_tok);
  finish_omp_cancel (clauses);
}

/* OpenMP 4.0:
   # pragma omp cancellation point cancelpt-clause[optseq] new-line  */

#define OMP_CANCELLATION_POINT_CLAUSE_MASK			\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PARALLEL)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FOR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SECTIONS)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TASKGROUP))

static bool
cp_parser_omp_cancellation_point (cp_parser *parser, cp_token *pragma_tok,
				  enum pragma_context context)
{
  tree clauses;
  bool point_seen = false;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "point") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  point_seen = true;
	}
    }
  if (!point_seen)
    {
      cp_parser_error (parser, "expected %<point%>");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return false;
    }

  if (context != pragma_compound)
    {
      if (context == pragma_stmt)
	error_at (pragma_tok->location,
		  "%<#pragma %s%> may only be used in compound statements",
		  "omp cancellation point");
      else
	cp_parser_error (parser, "expected declaration specifiers");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return true;
    }

  clauses = cp_parser_omp_all_clauses (parser,
				       OMP_CANCELLATION_POINT_CLAUSE_MASK,
				       "#pragma omp cancellation point",
				       pragma_tok);
  finish_omp_cancellation_point (clauses);
  return true;
}

/* OpenMP 4.0:
   #pragma omp distribute distribute-clause[optseq] new-line
     for-loop  */

#define OMP_DISTRIBUTE_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DIST_SCHEDULE)\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ORDER))

static tree
cp_parser_omp_distribute (cp_parser *parser, cp_token *pragma_tok,
			  char *p_name, omp_clause_mask mask, tree *cclauses,
			  bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " distribute");
  mask |= OMP_DISTRIBUTE_CLAUSE_MASK;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      bool simd = false;
      bool parallel = false;

      if (strcmp (p, "simd") == 0)
	simd = true;
      else
	parallel = strcmp (p, "parallel") == 0;
      if (parallel || simd)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;
	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    {
	      if (simd)
		return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
					   cclauses, if_p);
	      else
		return cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
					       cclauses, if_p);
	    }
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  if (simd)
	    ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
				      cclauses, if_p);
	  else
	    ret = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask,
					  cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  ret = make_node (OMP_DISTRIBUTE);
	  TREE_TYPE (ret) = void_type_node;
	  OMP_FOR_BODY (ret) = body;
	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
	  SET_EXPR_LOCATION (ret, loc);
	  add_stmt (ret);
	  return ret;
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_DISTRIBUTE, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_DISTRIBUTE];
    }

  keep_next_level (true);
  sb = begin_omp_structured_block ();
  save = cp_parser_begin_omp_structured_block (parser);

  ret = cp_parser_omp_for_loop (parser, OMP_DISTRIBUTE, clauses, NULL, if_p);

  cp_parser_end_omp_structured_block (parser, save);
  add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));

  return ret;
}

/* OpenMP 4.0:
   # pragma omp teams teams-clause[optseq] new-line
     structured-block  */

#define OMP_TEAMS_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TEAMS)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT))

static tree
cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
		     char *p_name, omp_clause_mask mask, tree *cclauses,
		     bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " teams");
  mask |= OMP_TEAMS_CLAUSE_MASK;

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      if (strcmp (p, "distribute") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
					     cclauses, if_p);
	  keep_next_level (true);
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  ret = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask,
					  cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
	  ret = make_node (OMP_TEAMS);
	  TREE_TYPE (ret) = void_type_node;
	  OMP_TEAMS_CLAUSES (ret) = clauses;
	  OMP_TEAMS_BODY (ret) = body;
	  OMP_TEAMS_COMBINED (ret) = 1;
	  SET_EXPR_LOCATION (ret, loc);
	  return add_stmt (ret);
	}
      else if (strcmp (p, "loop") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
				       cclauses, if_p);
	  keep_next_level (true);
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  ret = cp_parser_omp_loop (parser, pragma_tok, p_name, mask,
				    cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
	  ret = make_node (OMP_TEAMS);
	  TREE_TYPE (ret) = void_type_node;
	  OMP_TEAMS_CLAUSES (ret) = clauses;
	  OMP_TEAMS_BODY (ret) = body;
	  OMP_TEAMS_COMBINED (ret) = 1;
	  SET_EXPR_LOCATION (ret, loc);
	  return add_stmt (ret);
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_TEAMS, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
    }

  tree stmt = make_node (OMP_TEAMS);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TEAMS_CLAUSES (stmt) = clauses;
  keep_next_level (true);
  OMP_TEAMS_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);
  SET_EXPR_LOCATION (stmt, loc);

  return add_stmt (stmt);
}

/* OpenMP 4.0:
   # pragma omp target data target-data-clause[optseq] new-line
     structured-block  */

#define OMP_TARGET_DATA_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))

static tree
cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  if (flag_openmp)
    omp_requires_mask
      = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);

  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_TARGET_DATA_CLAUSE_MASK,
				 "#pragma omp target data", pragma_tok);
  c_omp_adjust_map_clauses (clauses, false);
  int map_seen = 0;
  for (tree *pc = &clauses; *pc;)
    {
      if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
	switch (OMP_CLAUSE_MAP_KIND (*pc))
	  {
	  case GOMP_MAP_TO:
	  case GOMP_MAP_ALWAYS_TO:
	  case GOMP_MAP_FROM:
	  case GOMP_MAP_ALWAYS_FROM:
	  case GOMP_MAP_TOFROM:
	  case GOMP_MAP_ALWAYS_TOFROM:
	  case GOMP_MAP_ALLOC:
	    map_seen = 3;
	    break;
	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
	  case GOMP_MAP_ALWAYS_POINTER:
	  case GOMP_MAP_ATTACH_DETACH:
	    break;
	  default:
	    map_seen |= 1;
	    error_at (OMP_CLAUSE_LOCATION (*pc),
		      "%<#pragma omp target data%> with map-type other "
		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
		      "on %<map%> clause");
	    *pc = OMP_CLAUSE_CHAIN (*pc);
	    continue;
	  }
      else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
	       || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
	map_seen = 3;
      pc = &OMP_CLAUSE_CHAIN (*pc);
    }

  if (map_seen != 3)
    {
      if (map_seen == 0)
	error_at (pragma_tok->location,
		  "%<#pragma omp target data%> must contain at least "
		  "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
		  "clause");
      return NULL_TREE;
    }

  tree stmt = make_node (OMP_TARGET_DATA);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TARGET_DATA_CLAUSES (stmt) = clauses;

  keep_next_level (true);
  OMP_TARGET_DATA_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);

  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  return add_stmt (stmt);
}

/* OpenMP 4.5:
   # pragma omp target enter data target-enter-data-clause[optseq] new-line
     structured-block  */

#define OMP_TARGET_ENTER_DATA_CLAUSE_MASK			\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static bool
cp_parser_omp_target_enter_data (cp_parser *parser, cp_token *pragma_tok,
				 enum pragma_context context)
{
  bool data_seen = false;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "data") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  data_seen = true;
	}
    }
  if (!data_seen)
    {
      cp_parser_error (parser, "expected %<data%>");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return false;
    }

  if (context == pragma_stmt)
    {
      error_at (pragma_tok->location,
		"%<#pragma %s%> may only be used in compound statements",
		"omp target enter data");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return true;
    }

  if (flag_openmp)
    omp_requires_mask
      = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);

  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_TARGET_ENTER_DATA_CLAUSE_MASK,
				 "#pragma omp target enter data", pragma_tok);
  c_omp_adjust_map_clauses (clauses, false);
  int map_seen = 0;
  for (tree *pc = &clauses; *pc;)
    {
      if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
	switch (OMP_CLAUSE_MAP_KIND (*pc))
	  {
	  case GOMP_MAP_TO:
	  case GOMP_MAP_ALWAYS_TO:
	  case GOMP_MAP_ALLOC:
	    map_seen = 3;
	    break;
	  case GOMP_MAP_TOFROM:
	    OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_TO);
	    map_seen = 3;
	    break;
	  case GOMP_MAP_ALWAYS_TOFROM:
	    OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_TO);
	    map_seen = 3;
	    break;
	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
	  case GOMP_MAP_ALWAYS_POINTER:
	  case GOMP_MAP_ATTACH_DETACH:
	    break;
	  default:
	    map_seen |= 1;
	    error_at (OMP_CLAUSE_LOCATION (*pc),
		      "%<#pragma omp target enter data%> with map-type other "
		      "than %<to%>, %<tofrom%> or %<alloc%> on %<map%> clause");
	    *pc = OMP_CLAUSE_CHAIN (*pc);
	    continue;
	  }
      pc = &OMP_CLAUSE_CHAIN (*pc);
    }

  if (map_seen != 3)
    {
      if (map_seen == 0)
	error_at (pragma_tok->location,
		  "%<#pragma omp target enter data%> must contain at least "
		  "one %<map%> clause");
      return true;
    }

  tree stmt = make_node (OMP_TARGET_ENTER_DATA);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TARGET_ENTER_DATA_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  add_stmt (stmt);
  return true;
}

/* OpenMP 4.5:
   # pragma omp target exit data target-enter-data-clause[optseq] new-line
     structured-block  */

#define OMP_TARGET_EXIT_DATA_CLAUSE_MASK			\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static bool
cp_parser_omp_target_exit_data (cp_parser *parser, cp_token *pragma_tok,
				enum pragma_context context)
{
  bool data_seen = false;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "data") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  data_seen = true;
	}
    }
  if (!data_seen)
    {
      cp_parser_error (parser, "expected %<data%>");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return false;
    }

  if (context == pragma_stmt)
    {
      error_at (pragma_tok->location,
		"%<#pragma %s%> may only be used in compound statements",
		"omp target exit data");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return true;
    }

  if (flag_openmp)
    omp_requires_mask
      = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);

  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_TARGET_EXIT_DATA_CLAUSE_MASK,
				 "#pragma omp target exit data", pragma_tok);
  c_omp_adjust_map_clauses (clauses, false);
  int map_seen = 0;
  for (tree *pc = &clauses; *pc;)
    {
      if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_MAP)
	switch (OMP_CLAUSE_MAP_KIND (*pc))
	  {
	  case GOMP_MAP_FROM:
	  case GOMP_MAP_ALWAYS_FROM:
	  case GOMP_MAP_RELEASE:
	  case GOMP_MAP_DELETE:
	    map_seen = 3;
	    break;
	  case GOMP_MAP_TOFROM:
	    OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_FROM);
	    map_seen = 3;
	    break;
	  case GOMP_MAP_ALWAYS_TOFROM:
	    OMP_CLAUSE_SET_MAP_KIND (*pc, GOMP_MAP_ALWAYS_FROM);
	    map_seen = 3;
	    break;
	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
	  case GOMP_MAP_ALWAYS_POINTER:
	  case GOMP_MAP_ATTACH_DETACH:
	    break;
	  default:
	    map_seen |= 1;
	    error_at (OMP_CLAUSE_LOCATION (*pc),
		      "%<#pragma omp target exit data%> with map-type other "
		      "than %<from%>, %<tofrom%>, %<release%> or %<delete%> "
		      "on %<map%> clause");
	    *pc = OMP_CLAUSE_CHAIN (*pc);
	    continue;
	  }
      pc = &OMP_CLAUSE_CHAIN (*pc);
    }

  if (map_seen != 3)
    {
      if (map_seen == 0)
	error_at (pragma_tok->location,
		  "%<#pragma omp target exit data%> must contain at least "
		  "one %<map%> clause");
      return true;
    }

  tree stmt = make_node (OMP_TARGET_EXIT_DATA);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TARGET_EXIT_DATA_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  add_stmt (stmt);
  return true;
}

/* OpenMP 4.0:
   # pragma omp target update target-update-clause[optseq] new-line */

#define OMP_TARGET_UPDATE_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FROM)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT))

static bool
cp_parser_omp_target_update (cp_parser *parser, cp_token *pragma_tok,
			     enum pragma_context context)
{
  if (context == pragma_stmt)
    {
      error_at (pragma_tok->location,
		"%<#pragma %s%> may only be used in compound statements",
		"omp target update");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return true;
    }

  tree clauses
    = cp_parser_omp_all_clauses (parser, OMP_TARGET_UPDATE_CLAUSE_MASK,
				 "#pragma omp target update", pragma_tok);
  if (omp_find_clause (clauses, OMP_CLAUSE_TO) == NULL_TREE
      && omp_find_clause (clauses, OMP_CLAUSE_FROM) == NULL_TREE)
    {
      error_at (pragma_tok->location,
		"%<#pragma omp target update%> must contain at least one "
		"%<from%> or %<to%> clauses");
      return true;
    }

  if (flag_openmp)
    omp_requires_mask
      = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);

  tree stmt = make_node (OMP_TARGET_UPDATE);
  TREE_TYPE (stmt) = void_type_node;
  OMP_TARGET_UPDATE_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  add_stmt (stmt);
  return true;
}

/* OpenMP 4.0:
   # pragma omp target target-clause[optseq] new-line
     structured-block  */

#define OMP_TARGET_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEPEND)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOWAIT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULTMAP)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_THREAD_LIMIT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR)\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_HAS_DEVICE_ADDR))

static bool
cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
		      enum pragma_context context, bool *if_p)
{
  if (flag_openmp)
    omp_requires_mask
      = (enum omp_requires) (omp_requires_mask | OMP_REQUIRES_TARGET_USED);

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);
      enum tree_code ccode = ERROR_MARK;

      if (strcmp (p, "teams") == 0)
	ccode = OMP_TEAMS;
      else if (strcmp (p, "parallel") == 0)
	ccode = OMP_PARALLEL;
      else if (strcmp (p, "simd") == 0)
	ccode = OMP_SIMD;
      if (ccode != ERROR_MARK)
	{
	  tree cclauses[C_OMP_CLAUSE_SPLIT_COUNT];
	  char p_name[sizeof ("#pragma omp target teams distribute "
			      "parallel for simd")];

	  cp_lexer_consume_token (parser->lexer);
	  strcpy (p_name, "#pragma omp target");
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    {
	      tree stmt;
	      switch (ccode)
		{
		case OMP_TEAMS:
		  stmt = cp_parser_omp_teams (parser, pragma_tok, p_name,
					      OMP_TARGET_CLAUSE_MASK,
					      cclauses, if_p);
		  break;
		case OMP_PARALLEL:
		  stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name,
						 OMP_TARGET_CLAUSE_MASK,
						 cclauses, if_p);
		  break;
		case OMP_SIMD:
		  stmt = cp_parser_omp_simd (parser, pragma_tok, p_name,
					     OMP_TARGET_CLAUSE_MASK,
					     cclauses, if_p);
		  break;
		default:
		  gcc_unreachable ();
		}
	      return stmt != NULL_TREE;
	    }
	  keep_next_level (true);
	  tree sb = begin_omp_structured_block (), ret;
	  unsigned save = cp_parser_begin_omp_structured_block (parser);
	  switch (ccode)
	    {
	    case OMP_TEAMS:
	      ret = cp_parser_omp_teams (parser, pragma_tok, p_name,
					 OMP_TARGET_CLAUSE_MASK, cclauses,
					 if_p);
	      break;
	    case OMP_PARALLEL:
	      ret = cp_parser_omp_parallel (parser, pragma_tok, p_name,
					    OMP_TARGET_CLAUSE_MASK, cclauses,
					    if_p);
	      break;
	    case OMP_SIMD:
	      ret = cp_parser_omp_simd (parser, pragma_tok, p_name,
					OMP_TARGET_CLAUSE_MASK, cclauses,
					if_p);
	      break;
	    default:
	      gcc_unreachable ();
	    }
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL_TREE)
	    return false;
	  if (ccode == OMP_TEAMS && !processing_template_decl)
	    /* For combined target teams, ensure the num_teams and
	       thread_limit clause expressions are evaluated on the host,
	       before entering the target construct.  */
	    for (tree c = cclauses[C_OMP_CLAUSE_SPLIT_TEAMS];
		 c; c = OMP_CLAUSE_CHAIN (c))
	      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS
		  || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_THREAD_LIMIT)
		for (int i = 0;
		     i <= (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_TEAMS); ++i)
		  if (OMP_CLAUSE_OPERAND (c, i)
		      && TREE_CODE (OMP_CLAUSE_OPERAND (c, i)) != INTEGER_CST)
		    {
		      tree expr = OMP_CLAUSE_OPERAND (c, i);
		      expr = force_target_expr (TREE_TYPE (expr), expr,
						tf_none);
		      if (expr == error_mark_node)
			continue;
		      tree tmp = TARGET_EXPR_SLOT (expr);
		      add_stmt (expr);
		      OMP_CLAUSE_OPERAND (c, i) = expr;
		      tree tc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
						  OMP_CLAUSE_FIRSTPRIVATE);
		      OMP_CLAUSE_DECL (tc) = tmp;
		      OMP_CLAUSE_CHAIN (tc)
			= cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
		      cclauses[C_OMP_CLAUSE_SPLIT_TARGET] = tc;
		    }
	  c_omp_adjust_map_clauses (cclauses[C_OMP_CLAUSE_SPLIT_TARGET], true);
	  finish_omp_target (pragma_tok->location,
			     cclauses[C_OMP_CLAUSE_SPLIT_TARGET], body, true);
	  return true;
	}
      else if (!flag_openmp)  /* flag_openmp_simd  */
	{
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  return false;
	}
      else if (strcmp (p, "data") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_omp_target_data (parser, pragma_tok, if_p);
	  return true;
	}
      else if (strcmp (p, "enter") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  return cp_parser_omp_target_enter_data (parser, pragma_tok, context);
	}
      else if (strcmp (p, "exit") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  return cp_parser_omp_target_exit_data (parser, pragma_tok, context);
	}
      else if (strcmp (p, "update") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  return cp_parser_omp_target_update (parser, pragma_tok, context);
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return false;
    }

  tree clauses = cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
					    "#pragma omp target", pragma_tok,
					    false);
  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_IN_REDUCTION)
      {
	tree nc = build_omp_clause (OMP_CLAUSE_LOCATION (c), OMP_CLAUSE_MAP);
	OMP_CLAUSE_DECL (nc) = OMP_CLAUSE_DECL (c);
	OMP_CLAUSE_SET_MAP_KIND (nc, GOMP_MAP_ALWAYS_TOFROM);
	OMP_CLAUSE_CHAIN (nc) = OMP_CLAUSE_CHAIN (c);
	OMP_CLAUSE_CHAIN (c) = nc;
      }
  clauses = finish_omp_clauses (clauses, C_ORT_OMP_TARGET);

  c_omp_adjust_map_clauses (clauses, true);
  keep_next_level (true);
  tree body = cp_parser_omp_structured_block (parser, if_p);

  finish_omp_target (pragma_tok->location, clauses, body, false);
  return true;
}

/* OpenACC 2.0:
   # pragma acc cache (variable-list) new-line
*/

static tree
cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
{
  /* Don't create location wrapper nodes within 'OMP_CLAUSE__CACHE_'
     clauses.  */
  auto_suppress_location_wrappers sentinel;

  tree stmt, clauses;

  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE__CACHE_, NULL_TREE);
  clauses = finish_omp_clauses (clauses, C_ORT_ACC);

  cp_parser_require_pragma_eol (parser, cp_lexer_peek_token (parser->lexer));

  stmt = make_node (OACC_CACHE);
  TREE_TYPE (stmt) = void_type_node;
  OACC_CACHE_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  add_stmt (stmt);

  return stmt;
}

/* OpenACC 2.0:
   # pragma acc data oacc-data-clause[optseq] new-line
     structured-block  */

#define OACC_DATA_CLAUSE_MASK						\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )

static tree
cp_parser_oacc_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree stmt, clauses, block;
  unsigned int save;

  clauses = cp_parser_oacc_all_clauses (parser, OACC_DATA_CLAUSE_MASK,
					"#pragma acc data", pragma_tok);

  block = begin_omp_parallel ();
  save = cp_parser_begin_omp_structured_block (parser);
  cp_parser_statement (parser, NULL_TREE, false, if_p);
  cp_parser_end_omp_structured_block (parser, save);
  stmt = finish_oacc_data (clauses, block);
  return stmt;
}

/* OpenACC 2.0:
  # pragma acc host_data <clauses> new-line
  structured-block  */

#define OACC_HOST_DATA_CLAUSE_MASK					\
  ( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_USE_DEVICE)                \
   | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)                        \
   | (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT) )

static tree
cp_parser_oacc_host_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree stmt, clauses, block;
  unsigned int save;

  clauses = cp_parser_oacc_all_clauses (parser, OACC_HOST_DATA_CLAUSE_MASK,
					"#pragma acc host_data", pragma_tok);

  block = begin_omp_parallel ();
  save = cp_parser_begin_omp_structured_block (parser);
  cp_parser_statement (parser, NULL_TREE, false, if_p);
  cp_parser_end_omp_structured_block (parser, save);
  stmt = finish_oacc_host_data (clauses, block);
  return stmt;
}

/* OpenACC 2.0:
   # pragma acc declare oacc-data-clause[optseq] new-line
*/

#define OACC_DECLARE_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_LINK)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT) )

static tree
cp_parser_oacc_declare (cp_parser *parser, cp_token *pragma_tok)
{
  tree clauses, stmt;
  bool error = false;
  bool found_in_scope = global_bindings_p ();

  clauses = cp_parser_oacc_all_clauses (parser, OACC_DECLARE_CLAUSE_MASK,
					"#pragma acc declare", pragma_tok, true);


  if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
    {
      error_at (pragma_tok->location,
		"no valid clauses specified in %<#pragma acc declare%>");
      return NULL_TREE;
    }

  for (tree t = clauses; t; t = OMP_CLAUSE_CHAIN (t))
    {
      location_t loc = OMP_CLAUSE_LOCATION (t);
      tree decl = OMP_CLAUSE_DECL (t);
      if (!DECL_P (decl))
	{
	  error_at (loc, "array section in %<#pragma acc declare%>");
	  error = true;
	  continue;
	}
      gcc_assert (OMP_CLAUSE_CODE (t) == OMP_CLAUSE_MAP);
      switch (OMP_CLAUSE_MAP_KIND (t))
	{
	case GOMP_MAP_FIRSTPRIVATE_POINTER:
	case GOMP_MAP_ALLOC:
	case GOMP_MAP_TO:
	case GOMP_MAP_FORCE_DEVICEPTR:
	case GOMP_MAP_DEVICE_RESIDENT:
	  break;

	case GOMP_MAP_LINK:
	  if (!global_bindings_p ()
	      && (TREE_STATIC (decl)
	       || !DECL_EXTERNAL (decl)))
	    {
	      error_at (loc,
			"%qD must be a global variable in "
			"%<#pragma acc declare link%>",
			decl);
	      error = true;
	      continue;
	    }
	  break;

	default:
	  if (global_bindings_p ())
	    {
	      error_at (loc, "invalid OpenACC clause at file scope");
	      error = true;
	      continue;
	    }
	  if (DECL_EXTERNAL (decl))
	    {
	      error_at (loc,
			"invalid use of %<extern%> variable %qD "
			"in %<#pragma acc declare%>", decl);
	      error = true;
	      continue;
	    }
	  else if (TREE_PUBLIC (decl))
	    {
	      error_at (loc,
			"invalid use of %<global%> variable %qD "
			"in %<#pragma acc declare%>", decl);
	      error = true;
	      continue;
	    }
	  break;
	}

      if (!found_in_scope)
	/* This seems to ignore the existence of cleanup scopes?
	   What is the meaning for local extern decls?  The local
	   extern is in this scope, but it is referring to a decl that
	   is namespace scope.  */
	for (tree d = current_binding_level->names; d; d = TREE_CHAIN (d))
	  if (d == decl)
	    {
	      found_in_scope = true;
	      break;
	    }
      if (!found_in_scope)
	{
	  error_at (loc,
		    "%qD must be a variable declared in the same scope as "
		    "%<#pragma acc declare%>", decl);
	  error = true;
	  continue;
	}

      if (lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl))
	  || lookup_attribute ("omp declare target link",
			       DECL_ATTRIBUTES (decl)))
	{
	  error_at (loc, "variable %qD used more than once with "
		    "%<#pragma acc declare%>", decl);
	  error = true;
	  continue;
	}

      if (!error)
	{
	  tree id;

	  if (DECL_LOCAL_DECL_P (decl))
	    /* We need to mark the aliased decl, as that is the entity
	       that is being referred to.  This won't work for
	       dependent variables, but it didn't work for them before
	       DECL_LOCAL_DECL_P was a thing either.  But then
	       dependent local extern variable decls are as rare as
	       hen's teeth.  */
	    if (auto alias = DECL_LOCAL_DECL_ALIAS (decl))
	      if (alias != error_mark_node)
		decl = alias;

	  if (OMP_CLAUSE_MAP_KIND (t) == GOMP_MAP_LINK)
	    id = get_identifier ("omp declare target link");
	  else
	    id = get_identifier ("omp declare target");

	  DECL_ATTRIBUTES (decl)
	    = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
	  if (current_binding_level->kind == sk_namespace)
	    {
	      symtab_node *node = symtab_node::get (decl);
	      if (node != NULL)
		{
		  node->offloadable = 1;
		  if (ENABLE_OFFLOADING)
		    {
		      g->have_offload = true;
		      if (is_a <varpool_node *> (node))
			vec_safe_push (offload_vars, decl);
		    }
		}
	    }
	}
    }

  if (error || current_binding_level->kind == sk_namespace)
    return NULL_TREE;

  stmt = make_node (OACC_DECLARE);
  TREE_TYPE (stmt) = void_type_node;
  OACC_DECLARE_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);

  add_stmt (stmt);

  return NULL_TREE;
}

/* OpenACC 2.0:
   # pragma acc enter data oacc-enter-data-clause[optseq] new-line

   or

   # pragma acc exit data oacc-exit-data-clause[optseq] new-line

   LOC is the location of the #pragma token.
*/

#define OACC_ENTER_DATA_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )

#define OACC_EXIT_DATA_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DELETE) 		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DETACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FINALIZE) 		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )

static tree
cp_parser_oacc_enter_exit_data (cp_parser *parser, cp_token *pragma_tok,
				bool enter)
{
  location_t loc = pragma_tok->location;
  tree stmt, clauses;
  const char *p = "";

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    p = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);

  if (strcmp (p, "data") != 0)
    {
      error_at (loc, "expected %<data%> after %<#pragma acc %s%>",
		enter ? "enter" : "exit");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  cp_lexer_consume_token (parser->lexer);

  if (enter)
    clauses = cp_parser_oacc_all_clauses (parser, OACC_ENTER_DATA_CLAUSE_MASK,
					 "#pragma acc enter data", pragma_tok);
  else
    clauses = cp_parser_oacc_all_clauses (parser, OACC_EXIT_DATA_CLAUSE_MASK,
					 "#pragma acc exit data", pragma_tok);

  if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
    {
      error_at (loc, "%<#pragma acc %s data%> has no data movement clause",
		enter ? "enter" : "exit");
      return NULL_TREE;
    }

  stmt = enter ? make_node (OACC_ENTER_DATA) : make_node (OACC_EXIT_DATA);
  TREE_TYPE (stmt) = void_type_node;
  OMP_STANDALONE_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, loc);
  add_stmt (stmt);
  return stmt;
}

/* OpenACC 2.0:
   # pragma acc loop oacc-loop-clause[optseq] new-line
     structured-block  */

#define OACC_LOOP_CLAUSE_MASK						\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COLLAPSE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_AUTO)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_INDEPENDENT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_TILE))

static tree
cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
		     omp_clause_mask mask, tree *cclauses, bool *if_p)
{
  bool is_parallel = ((mask >> PRAGMA_OACC_CLAUSE_REDUCTION) & 1) == 1;

  strcat (p_name, " loop");
  mask |= OACC_LOOP_CLAUSE_MASK;

  tree clauses = cp_parser_oacc_all_clauses (parser, mask, p_name, pragma_tok,
					     cclauses == NULL);
  if (cclauses)
    {
      clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
      if (*cclauses)
	*cclauses = finish_omp_clauses (*cclauses, C_ORT_ACC);
      if (clauses)
	clauses = finish_omp_clauses (clauses, C_ORT_ACC);
    }

  tree block = begin_omp_structured_block ();
  int save = cp_parser_begin_omp_structured_block (parser);
  tree stmt = cp_parser_omp_for_loop (parser, OACC_LOOP, clauses, NULL, if_p);
  cp_parser_end_omp_structured_block (parser, save);
  add_stmt (finish_omp_structured_block (block));

  return stmt;
}

/* OpenACC 2.0:
   # pragma acc kernels oacc-kernels-clause[optseq] new-line
     structured-block

   or

   # pragma acc parallel oacc-parallel-clause[optseq] new-line
     structured-block

   OpenACC 2.6:

   # pragma acc serial oacc-serial-clause[optseq] new-line
*/

#define OACC_KERNELS_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )

#define OACC_PARALLEL_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_GANGS)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NUM_WORKERS)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR_LENGTH)       \
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )

#define OACC_SERIAL_CLAUSE_MASK						\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ATTACH)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPY)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYIN)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_COPYOUT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEFAULT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICEPTR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NO_CREATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRIVATE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_PRESENT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_REDUCTION)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT) )

static tree
cp_parser_oacc_compute (cp_parser *parser, cp_token *pragma_tok,
			char *p_name, bool *if_p)
{
  omp_clause_mask mask;
  enum tree_code code;
  switch (cp_parser_pragma_kind (pragma_tok))
    {
    case PRAGMA_OACC_KERNELS:
      strcat (p_name, " kernels");
      mask = OACC_KERNELS_CLAUSE_MASK;
      code = OACC_KERNELS;
      break;
    case PRAGMA_OACC_PARALLEL:
      strcat (p_name, " parallel");
      mask = OACC_PARALLEL_CLAUSE_MASK;
      code = OACC_PARALLEL;
      break;
    case PRAGMA_OACC_SERIAL:
      strcat (p_name, " serial");
      mask = OACC_SERIAL_CLAUSE_MASK;
      code = OACC_SERIAL;
      break;
    default:
      gcc_unreachable ();
    }

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      const char *p
	= IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
      if (strcmp (p, "loop") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  tree block = begin_omp_parallel ();
	  tree clauses;
	  tree stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask,
					   &clauses, if_p);
	  protected_set_expr_location (stmt, pragma_tok->location);
	  return finish_omp_construct (code, block, clauses);
	}
    }

  tree clauses = cp_parser_oacc_all_clauses (parser, mask, p_name, pragma_tok);

  tree block = begin_omp_parallel ();
  unsigned int save = cp_parser_begin_omp_structured_block (parser);
  cp_parser_statement (parser, NULL_TREE, false, if_p);
  cp_parser_end_omp_structured_block (parser, save);
  return finish_omp_construct (code, block, clauses);
}

/* OpenACC 2.0:
   # pragma acc update oacc-update-clause[optseq] new-line
*/

#define OACC_UPDATE_CLAUSE_MASK						\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_DEVICE)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_HOST)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_IF_PRESENT)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WAIT))

static tree
cp_parser_oacc_update (cp_parser *parser, cp_token *pragma_tok)
{
  tree stmt, clauses;

  clauses = cp_parser_oacc_all_clauses (parser, OACC_UPDATE_CLAUSE_MASK,
					 "#pragma acc update", pragma_tok);

  if (omp_find_clause (clauses, OMP_CLAUSE_MAP) == NULL_TREE)
    {
      error_at (pragma_tok->location,
		"%<#pragma acc update%> must contain at least one "
		"%<device%> or %<host%> or %<self%> clause");
      return NULL_TREE;
    }

  stmt = make_node (OACC_UPDATE);
  TREE_TYPE (stmt) = void_type_node;
  OACC_UPDATE_CLAUSES (stmt) = clauses;
  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  add_stmt (stmt);
  return stmt;
}

/* OpenACC 2.0:
   # pragma acc wait [(intseq)] oacc-wait-clause[optseq] new-line

   LOC is the location of the #pragma token.
*/

#define OACC_WAIT_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC))

static tree
cp_parser_oacc_wait (cp_parser *parser, cp_token *pragma_tok)
{
  tree clauses, list = NULL_TREE, stmt = NULL_TREE;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
    list = cp_parser_oacc_wait_list (parser, loc, list);

  clauses = cp_parser_oacc_all_clauses (parser, OACC_WAIT_CLAUSE_MASK,
					"#pragma acc wait", pragma_tok);

  stmt = c_finish_oacc_wait (loc, list, clauses);
  stmt = finish_expr_stmt (stmt);

  return stmt;
}

/* OpenMP 4.0:
   # pragma omp declare simd declare-simd-clauses[optseq] new-line  */

#define OMP_DECLARE_SIMD_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SIMDLEN)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINEAR)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALIGNED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_INBRANCH)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOTINBRANCH))

static void
cp_parser_omp_declare_simd (cp_parser *parser, cp_token *pragma_tok,
			    enum pragma_context context,
			    bool variant_p)
{
  bool first_p = parser->omp_declare_simd == NULL;
  cp_omp_declare_simd_data data;
  if (first_p)
    {
      data.error_seen = false;
      data.fndecl_seen = false;
      data.variant_p = variant_p;
      data.tokens = vNULL;
      data.attribs[0] = NULL;
      data.attribs[1] = NULL;
      data.loc = UNKNOWN_LOCATION;
      /* It is safe to take the address of a local variable; it will only be
	 used while this scope is live.  */
      parser->omp_declare_simd = &data;
    }
  else if (parser->omp_declare_simd->variant_p != variant_p)
    {
      error_at (pragma_tok->location,
		"%<#pragma omp declare %s%> followed by "
		"%<#pragma omp declare %s%>",
		parser->omp_declare_simd->variant_p ? "variant" : "simd",
		parser->omp_declare_simd->variant_p ? "simd" : "variant");
      parser->omp_declare_simd->error_seen = true;
    }

  /* Store away all pragma tokens.  */
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    cp_lexer_consume_token (parser->lexer);
  cp_parser_require_pragma_eol (parser, pragma_tok);
  struct cp_token_cache *cp
    = cp_token_cache_new (pragma_tok, cp_lexer_peek_token (parser->lexer));
  parser->omp_declare_simd->tokens.safe_push (cp);

  if (first_p)
    {
      while (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
	cp_parser_pragma (parser, context, NULL);
      switch (context)
	{
	case pragma_external:
	  cp_parser_declaration (parser, NULL_TREE);
	  break;
	case pragma_member:
	  cp_parser_member_declaration (parser);
	  break;
	case pragma_objc_icode:
	  cp_parser_block_declaration (parser, /*statement_p=*/false);
	  break;
	default:
	  cp_parser_declaration_statement (parser);
	  break;
	}
      if (parser->omp_declare_simd
	  && !parser->omp_declare_simd->error_seen
	  && !parser->omp_declare_simd->fndecl_seen)
	error_at (pragma_tok->location,
		  "%<#pragma omp declare %s%> not immediately followed by "
		  "function declaration or definition",
		  parser->omp_declare_simd->variant_p ? "variant" : "simd");
      data.tokens.release ();
      parser->omp_declare_simd = NULL;
    }
}

static const char *const omp_construct_selectors[] = {
  "simd", "target", "teams", "parallel", "for", NULL };
static const char *const omp_device_selectors[] = {
  "kind", "isa", "arch", NULL };
static const char *const omp_implementation_selectors[] = {
  "vendor", "extension", "atomic_default_mem_order", "unified_address",
  "unified_shared_memory", "dynamic_allocators", "reverse_offload", NULL };
static const char *const omp_user_selectors[] = {
  "condition", NULL };

/* OpenMP 5.0:

   trait-selector:
     trait-selector-name[([trait-score:]trait-property[,trait-property[,...]])]

   trait-score:
     score(score-expression)  */

static tree
cp_parser_omp_context_selector (cp_parser *parser, tree set, bool has_parms_p)
{
  tree ret = NULL_TREE;
  do
    {
      tree selector;
      if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)
	  || cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	selector = cp_lexer_peek_token (parser->lexer)->u.value;
      else
	{
	  cp_parser_error (parser, "expected trait selector name");
	  return error_mark_node;
	}

      tree properties = NULL_TREE;
      const char *const *selectors = NULL;
      bool allow_score = true;
      bool allow_user = false;
      int property_limit = 0;
      enum { CTX_PROPERTY_NONE, CTX_PROPERTY_USER, CTX_PROPERTY_NAME_LIST,
	     CTX_PROPERTY_ID, CTX_PROPERTY_EXPR,
	     CTX_PROPERTY_SIMD } property_kind = CTX_PROPERTY_NONE;
      switch (IDENTIFIER_POINTER (set)[0])
	{
	case 'c': /* construct */
	  selectors = omp_construct_selectors;
	  allow_score = false;
	  property_limit = 1;
	  property_kind = CTX_PROPERTY_SIMD;
	  break;
	case 'd': /* device */
	  selectors = omp_device_selectors;
	  allow_score = false;
	  allow_user = true;
	  property_limit = 3;
	  property_kind = CTX_PROPERTY_NAME_LIST;
	  break;
	case 'i': /* implementation */
	  selectors = omp_implementation_selectors;
	  allow_user = true;
	  property_limit = 3;
	  property_kind = CTX_PROPERTY_NAME_LIST;
	  break;
	case 'u': /* user */
	  selectors = omp_user_selectors;
	  property_limit = 1;
	  property_kind = CTX_PROPERTY_EXPR;
	  break;
	default:
	  gcc_unreachable ();
	}
      for (int i = 0; ; i++)
	{
	  if (selectors[i] == NULL)
	    {
	      if (allow_user)
		{
		  property_kind = CTX_PROPERTY_USER;
		  break;
		}
	      else
		{
		  error ("selector %qs not allowed for context selector "
			 "set %qs", IDENTIFIER_POINTER (selector),
			 IDENTIFIER_POINTER (set));
		  cp_lexer_consume_token (parser->lexer);
		  return error_mark_node;
		}
	    }
	  if (i == property_limit)
	    property_kind = CTX_PROPERTY_NONE;
	  if (strcmp (selectors[i], IDENTIFIER_POINTER (selector)) == 0)
	    break;
	}
      if (property_kind == CTX_PROPERTY_NAME_LIST
	  && IDENTIFIER_POINTER (set)[0] == 'i'
	  && strcmp (IDENTIFIER_POINTER (selector),
		     "atomic_default_mem_order") == 0)
	property_kind = CTX_PROPERTY_ID;

      cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
	{
	  if (property_kind == CTX_PROPERTY_NONE)
	    {
	      error ("selector %qs does not accept any properties",
		     IDENTIFIER_POINTER (selector));
	      return error_mark_node;
	    }

	  matching_parens parens;
	  parens.consume_open (parser);

	  cp_token *token = cp_lexer_peek_token (parser->lexer);
	  if (allow_score
	      && cp_lexer_next_token_is (parser->lexer, CPP_NAME)
	      && strcmp (IDENTIFIER_POINTER (token->u.value), "score") == 0
	      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_OPEN_PAREN))
	    {
	      cp_lexer_save_tokens (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	      cp_lexer_consume_token (parser->lexer);
	      if (cp_parser_skip_to_closing_parenthesis (parser, false, false,
							 true)
		  && cp_lexer_next_token_is (parser->lexer, CPP_COLON))
		{
		  cp_lexer_rollback_tokens (parser->lexer);
		  cp_lexer_consume_token (parser->lexer);

		  matching_parens parens2;
		  parens2.require_open (parser);
		  tree score = cp_parser_constant_expression (parser);
		  if (!parens2.require_close (parser))
		    cp_parser_skip_to_closing_parenthesis (parser, true,
							   false, true);
		  cp_parser_require (parser, CPP_COLON, RT_COLON);
		  if (score != error_mark_node)
		    {
		      score = fold_non_dependent_expr (score);
		      if (value_dependent_expression_p (score))
			properties = tree_cons (get_identifier (" score"),
						score, properties);
		      else if (!INTEGRAL_TYPE_P (TREE_TYPE (score))
			       || TREE_CODE (score) != INTEGER_CST)
			error_at (token->location, "score argument must be "
				  "constant integer expression");
		      else if (tree_int_cst_sgn (score) < 0)
			error_at (token->location, "score argument must be "
				  "non-negative");
		      else
			properties = tree_cons (get_identifier (" score"),
						score, properties);
		    }
		}
	      else
		cp_lexer_rollback_tokens (parser->lexer);

	      token = cp_lexer_peek_token (parser->lexer);
	    }

	  switch (property_kind)
	    {
	      tree t;
	    case CTX_PROPERTY_USER:
	      do
		{
		  t = cp_parser_constant_expression (parser);
		  if (t != error_mark_node)
		    {
		      t = fold_non_dependent_expr (t);
		      if (TREE_CODE (t) == STRING_CST)
			properties = tree_cons (NULL_TREE, t, properties);
		      else if (!value_dependent_expression_p (t)
			       && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
				   || !tree_fits_shwi_p (t)))
			error_at (token->location, "property must be "
				  "constant integer expression or string "
				  "literal");
		      else
			properties = tree_cons (NULL_TREE, t, properties);
		    }
		  else
		    return error_mark_node;

		  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
		    cp_lexer_consume_token (parser->lexer);
		  else
		    break;
		}
	      while (1);
	      break;
	    case CTX_PROPERTY_ID:
	      if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)
		  || cp_lexer_next_token_is (parser->lexer, CPP_NAME))
		{
		  tree prop = cp_lexer_peek_token (parser->lexer)->u.value;
		  cp_lexer_consume_token (parser->lexer);
		  properties = tree_cons (prop, NULL_TREE, properties);
		}
	      else
		{
		  cp_parser_error (parser, "expected identifier");
		  return error_mark_node;
		}
	      break;
	    case CTX_PROPERTY_NAME_LIST:
	      do
		{
		  tree prop = NULL_TREE, value = NULL_TREE;
		  if (cp_lexer_next_token_is (parser->lexer, CPP_KEYWORD)
		      || cp_lexer_next_token_is (parser->lexer, CPP_NAME))
		    {
		      prop = cp_lexer_peek_token (parser->lexer)->u.value;
		      cp_lexer_consume_token (parser->lexer);
		    }
		  else if (cp_lexer_next_token_is (parser->lexer, CPP_STRING))
		    value = cp_parser_string_literal (parser,
						      /*translate=*/false,
						      /*wide_ok=*/false);
		  else
		    {
		      cp_parser_error (parser, "expected identifier or "
					       "string literal");
		      return error_mark_node;
		    }

		  properties = tree_cons (prop, value, properties);

		  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
		    cp_lexer_consume_token (parser->lexer);
		  else
		    break;
		}
	      while (1);
	      break;
	    case CTX_PROPERTY_EXPR:
	      t = cp_parser_constant_expression (parser);
	      if (t != error_mark_node)
		{
		  t = fold_non_dependent_expr (t);
		  if (!value_dependent_expression_p (t)
		      && (!INTEGRAL_TYPE_P (TREE_TYPE (t))
			  || !tree_fits_shwi_p (t)))
		    error_at (token->location, "property must be "
			      "constant integer expression");
		  else
		    properties = tree_cons (NULL_TREE, t, properties);
		}
	      else
		return error_mark_node;
	      break;
	    case CTX_PROPERTY_SIMD:
	      if (!has_parms_p)
		{
		  error_at (token->location, "properties for %<simd%> "
			    "selector may not be specified in "
			    "%<metadirective%>");
		  return error_mark_node;
		}
	      properties
		= cp_parser_omp_all_clauses (parser,
					     OMP_DECLARE_SIMD_CLAUSE_MASK,
					     "simd", NULL, true, 2);
	      break;
	    default:
	      gcc_unreachable ();
	    }

	  if (!parens.require_close (parser))
	    cp_parser_skip_to_closing_parenthesis (parser, true, false, true);

	  properties = nreverse (properties);
	}
      else if (property_kind == CTX_PROPERTY_NAME_LIST
	       || property_kind == CTX_PROPERTY_ID
	       || property_kind == CTX_PROPERTY_EXPR)
	{
	  cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);
	  return error_mark_node;
	}

      ret = tree_cons (selector, properties, ret);

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	break;
    }
  while (1);

  return nreverse (ret);
}

/* OpenMP 5.0:

   trait-set-selector[,trait-set-selector[,...]]

   trait-set-selector:
     trait-set-selector-name = { trait-selector[, trait-selector[, ...]] }

   trait-set-selector-name:
     constructor
     device
     implementation
     user  */

static tree
cp_parser_omp_context_selector_specification (cp_parser *parser,
					      bool has_parms_p)
{
  tree ret = NULL_TREE;
  do
    {
      const char *setp = "";
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	setp
	  = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
      switch (setp[0])
	{
	case 'c':
	  if (strcmp (setp, "construct") == 0)
	    setp = NULL;
	  break;
	case 'd':
	  if (strcmp (setp, "device") == 0)
	    setp = NULL;
	  break;
	case 'i':
	  if (strcmp (setp, "implementation") == 0)
	    setp = NULL;
	  break;
	case 'u':
	  if (strcmp (setp, "user") == 0)
	    setp = NULL;
	  break;
	default:
	  break;
	}
      if (setp)
	{
	  cp_parser_error (parser, "expected %<construct%>, %<device%>, "
				   "%<implementation%> or %<user%>");
	  return error_mark_node;
	}

      tree set = cp_lexer_peek_token (parser->lexer)->u.value;
      cp_lexer_consume_token (parser->lexer);

      if (!cp_parser_require (parser, CPP_EQ, RT_EQ))
	return error_mark_node;

      matching_braces braces;
      if (!braces.require_open (parser))
	return error_mark_node;

      tree selectors
	= cp_parser_omp_context_selector (parser, set, has_parms_p);
      if (selectors == error_mark_node)
	{
	  cp_parser_skip_to_closing_brace (parser);
	  ret = error_mark_node;
	}
      else if (ret != error_mark_node)
	ret = tree_cons (set, selectors, ret);

      braces.require_close (parser);

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	break;
    }
  while (1);

  if (ret == error_mark_node)
    return ret;
  return nreverse (ret);
}

/* Assumption clauses:
   OpenMP 5.1
   absent (directive-name-list)
   contains (directive-name-list)
   holds (expression)
   no_openmp
   no_openmp_routines
   no_parallelism  */

static void
cp_parser_omp_assumption_clauses (cp_parser *parser, cp_token *pragma_tok,
				  bool is_assume)
{
  bool no_openmp = false;
  bool no_openmp_routines = false;
  bool no_parallelism = false;
  bitmap_head absent_head, contains_head;

  bitmap_obstack_initialize (NULL);
  bitmap_initialize (&absent_head, &bitmap_default_obstack);
  bitmap_initialize (&contains_head, &bitmap_default_obstack);

  if (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
    error_at (cp_lexer_peek_token (parser->lexer)->location,
	      "expected at least one assumption clause");

  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	cp_lexer_consume_token (parser->lexer);

      if (!cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	break;

      const char *p
	= IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
      location_t cloc = cp_lexer_peek_token (parser->lexer)->location;

      if (!strcmp (p, "no_openmp"))
	{
	  cp_lexer_consume_token (parser->lexer);
	  if (no_openmp)
	    error_at (cloc, "too many %qs clauses", "no_openmp");
	  no_openmp = true;
	}
      else if (!strcmp (p, "no_openmp_routines"))
	{
	  cp_lexer_consume_token (parser->lexer);
	  if (no_openmp_routines)
	    error_at (cloc, "too many %qs clauses", "no_openmp_routines");
	  no_openmp_routines = true;
	}
      else if (!strcmp (p, "no_parallelism"))
	{
	  cp_lexer_consume_token (parser->lexer);
	  if (no_parallelism)
	    error_at (cloc, "too many %qs clauses", "no_parallelism");
	  no_parallelism = true;
	}
      else if (!strcmp (p, "holds"))
	{
	  cp_lexer_consume_token (parser->lexer);
	  matching_parens parens;
	  if (parens.require_open (parser))
	    {
	      location_t eloc = cp_lexer_peek_token (parser->lexer)->location;
	      tree t = cp_parser_assignment_expression (parser);
	      if (!type_dependent_expression_p (t))
		t = contextual_conv_bool (t, tf_warning_or_error);
	      if (is_assume && !error_operand_p (t))
		finish_expr_stmt (build_assume_call (eloc, t));
	      if (!parens.require_close (parser))
		cp_parser_skip_to_closing_parenthesis (parser,
						       /*recovering=*/true,
						       /*or_comma=*/false,
						       /*consume_paren=*/true);
	    }
	}
      else if (!strcmp (p, "absent") || !strcmp (p, "contains"))
	{
	  cp_lexer_consume_token (parser->lexer);
	  matching_parens parens;
	  if (parens.require_open (parser))
	    {
	      do
		{
		  const char *directive[3] = {};
		  int i;
		  location_t dloc
		    = cp_lexer_peek_token (parser->lexer)->location;
		  for (i = 0; i < 3; i++)
		    {
		      tree id;
		      if (cp_lexer_nth_token_is (parser->lexer, i + 1, CPP_NAME))
			id = cp_lexer_peek_nth_token (parser->lexer,
						      i + 1)->u.value;
		      else if (cp_lexer_nth_token_is (parser->lexer, i + 1,
						      CPP_KEYWORD))
			{
			  enum rid rid
			    = cp_lexer_peek_nth_token (parser->lexer,
						       i + 1)->keyword;
			  id = ridpointers[rid];
			}
		      else
			break;
		      directive[i] = IDENTIFIER_POINTER (id);
		    }
		  if (i == 0)
		    error_at (dloc, "expected directive name");
		  else
		    {
		      const struct c_omp_directive *dir
			= c_omp_categorize_directive (directive[0],
						      directive[1],
						      directive[2]);
		      if (dir == NULL
			  || dir->kind == C_OMP_DIR_DECLARATIVE
			  || dir->kind == C_OMP_DIR_INFORMATIONAL
			  || dir->id == PRAGMA_OMP_END
			  || (!dir->second && directive[1])
			  || (!dir->third && directive[2]))
			error_at (dloc, "unknown OpenMP directive name in "
					"%qs clause argument", p);
		      else
			{
			  int id = dir - c_omp_directives;
			  if (bitmap_bit_p (p[0] == 'a' ? &contains_head
							: &absent_head, id))
			    error_at (dloc, "%<%s%s%s%s%s%> directive "
					    "mentioned in both %<absent%> and "
					    "%<contains%> clauses",
				      directive[0],
				      directive[1] ? " " : "",
				      directive[1] ? directive[1] : "",
				      directive[2] ? " " : "",
				      directive[2] ? directive[2] : "");
			  else if (!bitmap_set_bit (p[0] == 'a'
						    ? &absent_head
						    : &contains_head, id))
			    error_at (dloc, "%<%s%s%s%s%s%> directive "
					    "mentioned multiple times in %qs "
					    "clauses",
				      directive[0],
				      directive[1] ? " " : "",
				      directive[1] ? directive[1] : "",
				      directive[2] ? " " : "",
				      directive[2] ? directive[2] : "", p);
			}
		      for (; i; --i)
			cp_lexer_consume_token (parser->lexer);
		    }
		  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
		    cp_lexer_consume_token (parser->lexer);
		  else
		    break;
		}
	      while (1);
	      if (!parens.require_close (parser))
		cp_parser_skip_to_closing_parenthesis (parser,
						       /*recovering=*/true,
						       /*or_comma=*/false,
						       /*consume_paren=*/true);
	    }
	}
      else if (startswith (p, "ext_"))
	{
	  warning_at (cloc, 0, "unknown assumption clause %qs", p);
	  cp_lexer_consume_token (parser->lexer);
	  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
	    for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 1;
		 n; --n)
	      cp_lexer_consume_token (parser->lexer);
	}
      else
	{
	  cp_lexer_consume_token (parser->lexer);
	  error_at (cloc, "expected assumption clause");
	  break;
	}
    }
  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
}

/* OpenMP 5.1
   # pragma omp assume clauses[optseq] new-line  */

static void
cp_parser_omp_assume (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  cp_parser_omp_assumption_clauses (parser, pragma_tok, true);
  add_stmt (cp_parser_omp_structured_block (parser, if_p));
}

/* OpenMP 5.1
   # pragma omp assumes clauses[optseq] new-line  */

static bool
cp_parser_omp_assumes (cp_parser *parser, cp_token *pragma_tok)
{
  cp_parser_omp_assumption_clauses (parser, pragma_tok, false);
  return false;
}

/* Finalize #pragma omp declare variant after a fndecl has been parsed, and put
   that into "omp declare variant base" attribute.  */

static tree
cp_finish_omp_declare_variant (cp_parser *parser, cp_token *pragma_tok,
			       tree attrs)
{
  matching_parens parens;
  if (!parens.require_open (parser))
    {
     fail:
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return attrs;
    }

  bool template_p;
  cp_id_kind idk = CP_ID_KIND_NONE;
  cp_token *varid_token = cp_lexer_peek_token (parser->lexer);
  cp_expr varid
    = cp_parser_id_expression (parser, /*template_keyword_p=*/false,
			       /*check_dependency_p=*/true,
			       /*template_p=*/&template_p,
			       /*declarator_p=*/false,
			       /*optional_p=*/false);
  parens.require_close (parser);

  tree variant;
  if (TREE_CODE (varid) == TEMPLATE_ID_EXPR
      || TREE_CODE (varid) == TYPE_DECL
      || varid == error_mark_node)
    variant = varid;
  else if (varid_token->type == CPP_NAME && varid_token->error_reported)
    variant = NULL_TREE;
  else
    {
      tree ambiguous_decls;
      variant = cp_parser_lookup_name (parser, varid, none_type,
				       template_p, /*is_namespace=*/false,
				       /*check_dependency=*/true,
				       &ambiguous_decls,
				       varid.get_location ());
      if (ambiguous_decls)
	variant = NULL_TREE;
    }
  if (variant == NULL_TREE)
    variant = error_mark_node;
  else if (TREE_CODE (variant) != SCOPE_REF)
    {
      const char *error_msg;
      variant
	= finish_id_expression (varid, variant, parser->scope,
				&idk, false, true,
				&parser->non_integral_constant_expression_p,
				template_p, true, false, false, &error_msg,
				varid.get_location ());
      if (error_msg)
	cp_parser_error (parser, error_msg);
    }
  location_t caret_loc = get_pure_location (varid.get_location ());
  location_t start_loc = get_start (varid_token->location);
  location_t finish_loc = get_finish (varid.get_location ());
  location_t varid_loc = make_location (caret_loc, start_loc, finish_loc);

  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
    cp_lexer_consume_token (parser->lexer);

  const char *clause = "";
  location_t match_loc = cp_lexer_peek_token (parser->lexer)->location;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    clause = IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
  if (strcmp (clause, "match"))
    {
      cp_parser_error (parser, "expected %<match%>");
      goto fail;
    }

  cp_lexer_consume_token (parser->lexer);

  if (!parens.require_open (parser))
    goto fail;

  tree ctx = cp_parser_omp_context_selector_specification (parser, true);
  if (ctx == error_mark_node)
    goto fail;
  ctx = omp_check_context_selector (match_loc, ctx);
  if (ctx != error_mark_node && variant != error_mark_node)
    {
      tree match_loc_node = maybe_wrap_with_location (integer_zero_node,
						      match_loc);
      tree loc_node = maybe_wrap_with_location (integer_zero_node, varid_loc);
      loc_node = tree_cons (match_loc_node,
			    build_int_cst (integer_type_node, idk),
			    build_tree_list (loc_node, integer_zero_node));
      attrs = tree_cons (get_identifier ("omp declare variant base"),
			 tree_cons (variant, ctx, loc_node), attrs);
      if (processing_template_decl)
	ATTR_IS_DEPENDENT (attrs) = 1;
    }

  parens.require_close (parser);
  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
  return attrs;
}


/* Finalize #pragma omp declare simd clauses after direct declarator has
   been parsed, and put that into "omp declare simd" attribute.  */

static tree
cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
{
  struct cp_token_cache *ce;
  cp_omp_declare_simd_data *data = parser->omp_declare_simd;
  int i;

  if (!data->error_seen && data->fndecl_seen)
    {
      error ("%<#pragma omp declare %s%> not immediately followed by "
	     "a single function declaration or definition",
	     data->variant_p ? "variant" : "simd");
      data->error_seen = true;
    }
  if (data->error_seen)
    return attrs;

  FOR_EACH_VEC_ELT (data->tokens, i, ce)
    {
      tree c, cl;

      cp_parser_push_lexer_for_tokens (parser, ce);
      parser->lexer->in_pragma = true;
      gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);
      cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *kind = IDENTIFIER_POINTER (id);
      cp_lexer_consume_token (parser->lexer);
      if (strcmp (kind, "simd") == 0)
	{
	  cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
					  "#pragma omp declare simd",
					  pragma_tok);
	  if (cl)
	    cl = tree_cons (NULL_TREE, cl, NULL_TREE);
	  c = build_tree_list (get_identifier ("omp declare simd"), cl);
	  TREE_CHAIN (c) = attrs;
	  if (processing_template_decl)
	    ATTR_IS_DEPENDENT (c) = 1;
	  attrs = c;
	}
      else
	{
	  gcc_assert (strcmp (kind, "variant") == 0);
	  attrs
	    = cp_finish_omp_declare_variant (parser, pragma_tok, attrs);
	}
      cp_parser_pop_lexer (parser);
    }

  cp_lexer *lexer = NULL;
  for (int i = 0; i < 2; i++)
    {
      if (data->attribs[i] == NULL)
	continue;
      for (tree *pa = data->attribs[i]; *pa; )
	if (get_attribute_namespace (*pa) == omp_identifier
	    && is_attribute_p ("directive", get_attribute_name (*pa)))
	  {
	    for (tree a = TREE_VALUE (*pa); a; a = TREE_CHAIN (a))
	      {
		tree d = TREE_VALUE (a);
		gcc_assert (TREE_CODE (d) == DEFERRED_PARSE);
		cp_token *first = DEFPARSE_TOKENS (d)->first;
		cp_token *last = DEFPARSE_TOKENS (d)->last;
		const char *directive[3] = {};
		for (int j = 0; j < 3; j++)
		  {
		    tree id = NULL_TREE;
		    if (first + j == last)
		      break;
		    if (first[j].type == CPP_NAME)
		      id = first[j].u.value;
		    else if (first[j].type == CPP_KEYWORD)
		      id = ridpointers[(int) first[j].keyword];
		    else
		      break;
		    directive[j] = IDENTIFIER_POINTER (id);
		  }
		const c_omp_directive *dir = NULL;
		if (directive[0])
		  dir = c_omp_categorize_directive (directive[0], directive[1],
						    directive[2]);
		if (dir == NULL)
		  {
		    error_at (first->location,
			      "unknown OpenMP directive name in "
			      "%<omp::directive%> attribute argument");
		    continue;
		  }
		if (dir->id != PRAGMA_OMP_DECLARE
		    || (strcmp (directive[1], "simd") != 0
			&& strcmp (directive[1], "variant") != 0))
		  {
		    error_at (first->location,
			      "OpenMP directive other than %<declare simd%> "
			      "or %<declare variant%> appertains to a "
			      "declaration");
		    continue;
		  }

		if (parser->omp_attrs_forbidden_p)
		  {
		    error_at (first->location,
			      "mixing OpenMP directives with attribute and "
			      "pragma syntax on the same statement");
		    parser->omp_attrs_forbidden_p = false;
		  }

		if (!flag_openmp && strcmp (directive[1], "simd") != 0)
		  continue;
		if (lexer == NULL)
		  {
		    lexer = cp_lexer_alloc ();
		    lexer->debugging_p = parser->lexer->debugging_p;
		  }
		vec_safe_reserve (lexer->buffer, (last - first) + 2);
		cp_token tok = {};
		tok.type = CPP_PRAGMA;
		tok.keyword = RID_MAX;
		tok.u.value = build_int_cst (NULL, PRAGMA_OMP_DECLARE);
		tok.location = first->location;
		lexer->buffer->quick_push (tok);
		while (++first < last)
		  lexer->buffer->quick_push (*first);
		tok = {};
		tok.type = CPP_PRAGMA_EOL;
		tok.keyword = RID_MAX;
		tok.location = last->location;
		lexer->buffer->quick_push (tok);
		tok = {};
		tok.type = CPP_EOF;
		tok.keyword = RID_MAX;
		tok.location = last->location;
		lexer->buffer->quick_push (tok);
		lexer->next = parser->lexer;
		lexer->next_token = lexer->buffer->address ();
		lexer->last_token = lexer->next_token
				    + lexer->buffer->length ()
		      - 1;
		lexer->in_omp_attribute_pragma = true;
		parser->lexer = lexer;
		/* Move the current source position to that of the first token
		   in the new lexer.  */
		cp_lexer_set_source_position_from_token (lexer->next_token);

		cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
		tree id = cp_lexer_peek_token (parser->lexer)->u.value;
		const char *kind = IDENTIFIER_POINTER (id);
		cp_lexer_consume_token (parser->lexer);

		tree c, cl;
		if (strcmp (kind, "simd") == 0)
		  {
		    if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
			&& cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
		      cp_lexer_consume_token (parser->lexer);

		    omp_clause_mask mask = OMP_DECLARE_SIMD_CLAUSE_MASK;
		    cl = cp_parser_omp_all_clauses (parser, mask,
						    "#pragma omp declare simd",
						    pragma_tok);
		    if (cl)
		      cl = tree_cons (NULL_TREE, cl, NULL_TREE);
		    c = build_tree_list (get_identifier ("omp declare simd"),
					 cl);
		    TREE_CHAIN (c) = attrs;
		    if (processing_template_decl)
		      ATTR_IS_DEPENDENT (c) = 1;
		    attrs = c;
		  }
		else
		  {
		    gcc_assert (strcmp (kind, "variant") == 0);
		    attrs
		      = cp_finish_omp_declare_variant (parser, pragma_tok,
						       attrs);
		  }
		gcc_assert (parser->lexer != lexer);
		vec_safe_truncate (lexer->buffer, 0);
	      }
	    *pa = TREE_CHAIN (*pa);
	  }
	else
	  pa = &TREE_CHAIN (*pa);
    }
  if (lexer)
    cp_lexer_destroy (lexer);

  data->fndecl_seen = true;
  return attrs;
}

/* Helper for cp_parser_omp_declare_target, handle one to or link clause
   on #pragma omp declare target.  Return false if errors were reported.  */

static bool
handle_omp_declare_target_clause (tree c, tree t, int device_type)
{
  tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
  tree at2 = lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t));
  tree id;
  if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
    {
      id = get_identifier ("omp declare target link");
      std::swap (at1, at2);
    }
  else
    id = get_identifier ("omp declare target");
  if (at2)
    {
      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_ENTER)
	error_at (OMP_CLAUSE_LOCATION (c),
		  "%qD specified both in declare target %<link%> and %qs"
		  " clauses", t, OMP_CLAUSE_ENTER_TO (c) ? "to" : "enter");
      else
	error_at (OMP_CLAUSE_LOCATION (c),
		  "%qD specified both in declare target %<link%> and "
		  "%<to%> or %<enter%> clauses", t);
      return false;
    }
  if (!at1)
    {
      DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
      if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
	return true;

      symtab_node *node = symtab_node::get (t);
      if (node != NULL)
	{
	  node->offloadable = 1;
	  if (ENABLE_OFFLOADING)
	    {
	      g->have_offload = true;
	      if (is_a <varpool_node *> (node))
		vec_safe_push (offload_vars, t);
	    }
	}
    }
  if (TREE_CODE (t) != FUNCTION_DECL)
    return true;
  if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
    {
      tree at3 = lookup_attribute ("omp declare target host",
				   DECL_ATTRIBUTES (t));
      if (at3 == NULL_TREE)
	{
	  id = get_identifier ("omp declare target host");
	  DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
	}
    }
  if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
    {
      tree at3 = lookup_attribute ("omp declare target nohost",
				   DECL_ATTRIBUTES (t));
      if (at3 == NULL_TREE)
	{
	  id = get_identifier ("omp declare target nohost");
	  DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
	}
    }
  return true;
}

/* OpenMP 4.0:
   # pragma omp declare target new-line
   declarations and definitions
   # pragma omp end declare target new-line

   OpenMP 4.5:
   # pragma omp declare target ( extended-list ) new-line

   # pragma omp declare target declare-target-clauses[seq] new-line  */

#define OMP_DECLARE_TARGET_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ENTER)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))

static void
cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
  tree clauses = NULL_TREE;
  int device_type = 0;
  bool only_device_type = true;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME)
      || (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME)))
    clauses
      = cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
				   "#pragma omp declare target", pragma_tok);
  else if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_ENTER,
					clauses);
      clauses = finish_omp_clauses (clauses, C_ORT_OMP);
      cp_parser_require_pragma_eol (parser, pragma_tok);
    }
  else
    {
      cp_omp_declare_target_attr a
	= { parser->lexer->in_omp_attribute_pragma, -1 };
      vec_safe_push (scope_chain->omp_declare_target_attribute, a);
      cp_parser_require_pragma_eol (parser, pragma_tok);
      return;
    }
  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
      device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    {
      if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
	continue;
      tree t = OMP_CLAUSE_DECL (c);
      only_device_type = false;
      if (!handle_omp_declare_target_clause (c, t, device_type))
	continue;
      if (VAR_OR_FUNCTION_DECL_P (t)
	  && DECL_LOCAL_DECL_P (t)
	  && DECL_LANG_SPECIFIC (t)
	  && DECL_LOCAL_DECL_ALIAS (t)
	  && DECL_LOCAL_DECL_ALIAS (t) != error_mark_node)
	handle_omp_declare_target_clause (c, DECL_LOCAL_DECL_ALIAS (t),
					  device_type);
    }
  if (device_type && only_device_type)
    error_at (OMP_CLAUSE_LOCATION (clauses),
	      "directive with only %<device_type%> clause");
}

/* OpenMP 5.1
   # pragma omp begin assumes clauses[optseq] new-line

   # pragma omp begin declare target clauses[optseq] new-line  */

#define OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK			\
	(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE)

static void
cp_parser_omp_begin (cp_parser *parser, cp_token *pragma_tok)
{
  const char *p = "";
  bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
    }
  if (strcmp (p, "declare") == 0)
    {
      cp_lexer_consume_token (parser->lexer);
      p = "";
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  p = IDENTIFIER_POINTER (id);
	}
      if (strcmp (p, "target") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  tree clauses
	    = cp_parser_omp_all_clauses (parser,
					 OMP_BEGIN_DECLARE_TARGET_CLAUSE_MASK,
					 "#pragma omp begin declare target",
					 pragma_tok);
	  int device_type = 0;
	  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
	    if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
	      device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
	  cp_omp_declare_target_attr a
	    = { in_omp_attribute_pragma, device_type };
	  vec_safe_push (scope_chain->omp_declare_target_attribute, a);
	}
      else
	{
	  cp_parser_error (parser, "expected %<target%>");
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	}
    }
  else if (strcmp (p, "assumes") == 0)
    {
      cp_lexer_consume_token (parser->lexer);
      cp_parser_omp_assumption_clauses (parser, pragma_tok, false);
      cp_omp_begin_assumes_data a = { in_omp_attribute_pragma };
      vec_safe_push (scope_chain->omp_begin_assumes, a);
    }
  else
    {
      cp_parser_error (parser, "expected %<declare target%> or %<assumes%>");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
    }
}

/* OpenMP 4.0:
   # pragma omp end declare target new-line

   OpenMP 5.1:
   # pragma omp end assumes new-line  */

static void
cp_parser_omp_end (cp_parser *parser, cp_token *pragma_tok)
{
  const char *p = "";
  bool in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
    }
  if (strcmp (p, "declare") == 0)
    {
      cp_lexer_consume_token (parser->lexer);
      p = "";
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  p = IDENTIFIER_POINTER (id);
	}
      if (strcmp (p, "target") == 0)
	cp_lexer_consume_token (parser->lexer);
      else
	{
	  cp_parser_error (parser, "expected %<target%>");
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  return;
	}
      cp_parser_require_pragma_eol (parser, pragma_tok);
      if (!vec_safe_length (scope_chain->omp_declare_target_attribute))
	error_at (pragma_tok->location,
		  "%<#pragma omp end declare target%> without corresponding "
		  "%<#pragma omp declare target%> or "
		  "%<#pragma omp begin declare target%>");
      else
	{
	  cp_omp_declare_target_attr
	    a = scope_chain->omp_declare_target_attribute->pop ();
	  if (a.attr_syntax != in_omp_attribute_pragma)
	    {
	      if (a.attr_syntax)
		error_at (pragma_tok->location,
			  "%qs in attribute syntax terminated "
			  "with %qs in pragma syntax",
			  a.device_type >= 0 ? "begin declare target"
					     : "declare target",
			  "end declare target");
	      else
		error_at (pragma_tok->location,
			  "%qs in pragma syntax terminated "
			  "with %qs in attribute syntax",
			  a.device_type >= 0 ? "begin declare target"
					     : "declare target",
			  "end declare target");
	    }
	}
    }
  else if (strcmp (p, "assumes") == 0)
    {
      cp_lexer_consume_token (parser->lexer);
      cp_parser_require_pragma_eol (parser, pragma_tok);
      if (!vec_safe_length (scope_chain->omp_begin_assumes))
	error_at (pragma_tok->location,
		  "%qs without corresponding %qs",
		  "#pragma omp end assumes", "#pragma omp begin assumes");
      else
	{
	  cp_omp_begin_assumes_data
	    a = scope_chain->omp_begin_assumes->pop ();
	  if (a.attr_syntax != in_omp_attribute_pragma)
	    {
	      if (a.attr_syntax)
		error_at (pragma_tok->location,
			  "%qs in attribute syntax terminated "
			  "with %qs in pragma syntax",
			  "begin assumes", "end assumes");
	      else
		error_at (pragma_tok->location,
			  "%qs in pragma syntax terminated "
			  "with %qs in attribute syntax",
			  "begin assumes", "end assumes");
	    }
	}
    }
  else
    {
      cp_parser_error (parser, "expected %<declare%> or %<assumes%>");
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return;
    }
}

/* Helper function of cp_parser_omp_declare_reduction.  Parse the combiner
   expression and optional initializer clause of
   #pragma omp declare reduction.  We store the expression(s) as
   either 3, 6 or 7 special statements inside of the artificial function's
   body.  The first two statements are DECL_EXPRs for the artificial
   OMP_OUT resp. OMP_IN variables, followed by a statement with the combiner
   expression that uses those variables.
   If there was any INITIALIZER clause, this is followed by further statements,
   the fourth and fifth statements are DECL_EXPRs for the artificial
   OMP_PRIV resp. OMP_ORIG variables.  If the INITIALIZER clause wasn't the
   constructor variant (first token after open paren is not omp_priv),
   then the sixth statement is a statement with the function call expression
   that uses the OMP_PRIV and optionally OMP_ORIG variable.
   Otherwise, the sixth statement is whatever statement cp_finish_decl emits
   to initialize the OMP_PRIV artificial variable and there is seventh
   statement, a DECL_EXPR of the OMP_PRIV statement again.  */

static bool
cp_parser_omp_declare_reduction_exprs (tree fndecl, cp_parser *parser)
{
  tree type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
  gcc_assert (TYPE_REF_P (type));
  type = TREE_TYPE (type);
  tree omp_out = build_lang_decl (VAR_DECL, get_identifier ("omp_out"), type);
  DECL_ARTIFICIAL (omp_out) = 1;
  pushdecl (omp_out);
  add_decl_expr (omp_out);
  tree omp_in = build_lang_decl (VAR_DECL, get_identifier ("omp_in"), type);
  DECL_ARTIFICIAL (omp_in) = 1;
  pushdecl (omp_in);
  add_decl_expr (omp_in);
  tree combiner;
  tree omp_priv = NULL_TREE, omp_orig = NULL_TREE, initializer = NULL_TREE;

  keep_next_level (true);
  tree block = begin_omp_structured_block ();
  combiner = cp_parser_expression (parser);
  finish_expr_stmt (combiner);
  block = finish_omp_structured_block (block);
  if (processing_template_decl)
    block = build_stmt (input_location, EXPR_STMT, block);
  add_stmt (block);

  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
    return false;

  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
      && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
    cp_lexer_consume_token (parser->lexer);

  const char *p = "";
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      p = IDENTIFIER_POINTER (id);
    }

  if (strcmp (p, "initializer") == 0)
    {
      cp_lexer_consume_token (parser->lexer);
      matching_parens parens;
      if (!parens.require_open (parser))
	return false;

      p = "";
      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  p = IDENTIFIER_POINTER (id);
	}

      omp_priv = build_lang_decl (VAR_DECL, get_identifier ("omp_priv"), type);
      DECL_ARTIFICIAL (omp_priv) = 1;
      pushdecl (omp_priv);
      add_decl_expr (omp_priv);
      omp_orig = build_lang_decl (VAR_DECL, get_identifier ("omp_orig"), type);
      DECL_ARTIFICIAL (omp_orig) = 1;
      pushdecl (omp_orig);
      add_decl_expr (omp_orig);

      keep_next_level (true);
      block = begin_omp_structured_block ();

      bool ctor = false;
      if (strcmp (p, "omp_priv") == 0)
	{
	  bool is_direct_init, is_non_constant_init;
	  ctor = true;
	  cp_lexer_consume_token (parser->lexer);
	  /* Reject initializer (omp_priv) and initializer (omp_priv ()).  */
	  if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_PAREN)
	      || (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
		  && cp_lexer_peek_nth_token (parser->lexer, 2)->type
		     == CPP_CLOSE_PAREN
		  && cp_lexer_peek_nth_token (parser->lexer, 3)->type
		     == CPP_CLOSE_PAREN))
	    {
	      finish_omp_structured_block (block);
	      error ("invalid initializer clause");
	      return false;
	    }
	  initializer = cp_parser_initializer (parser, &is_direct_init,
					       &is_non_constant_init);
	  cp_finish_decl (omp_priv, initializer, !is_non_constant_init,
			  NULL_TREE, LOOKUP_ONLYCONVERTING);
	}
      else
	{
	  cp_parser_parse_tentatively (parser);
	  /* Don't create location wrapper nodes here.  */
	  auto_suppress_location_wrappers sentinel;
	  tree fn_name = cp_parser_id_expression (parser, /*template_p=*/false,
						  /*check_dependency_p=*/true,
						  /*template_p=*/NULL,
						  /*declarator_p=*/false,
						  /*optional_p=*/false);
	  vec<tree, va_gc> *args;
	  if (fn_name == error_mark_node
	      || cp_parser_error_occurred (parser)
	      || !cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN)
	      || ((args = cp_parser_parenthesized_expression_list
				(parser, non_attr, /*cast_p=*/false,
				 /*allow_expansion_p=*/true,
				 /*non_constant_p=*/NULL)),
		  cp_parser_error_occurred (parser)))
	    {
	      finish_omp_structured_block (block);
	      cp_parser_abort_tentative_parse (parser);
	      cp_parser_error (parser, "expected id-expression (arguments)");
	      return false;
	    }
	  unsigned int i;
	  tree arg;
	  FOR_EACH_VEC_SAFE_ELT (args, i, arg)
	    if (arg == omp_priv
		|| (TREE_CODE (arg) == ADDR_EXPR
		    && TREE_OPERAND (arg, 0) == omp_priv))
	      break;
	  cp_parser_abort_tentative_parse (parser);
	  if (arg == NULL_TREE)
	    error ("one of the initializer call arguments should be %<omp_priv%>"
		   " or %<&omp_priv%>");
	  initializer = cp_parser_postfix_expression (parser, false, false, false,
						      false, NULL);
	  finish_expr_stmt (initializer);
	}

      block = finish_omp_structured_block (block);
      cp_walk_tree (&block, cp_remove_omp_priv_cleanup_stmt, omp_priv, NULL);
      if (processing_template_decl)
	block = build_stmt (input_location, EXPR_STMT, block);
      add_stmt (block);

      if (ctor)
	add_decl_expr (omp_orig);

      if (!parens.require_close (parser))
	return false;
    }

  if (!cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA_EOL))
    cp_parser_required_error (parser, RT_PRAGMA_EOL, /*keyword=*/false,
                              UNKNOWN_LOCATION);

  return true;
}

/* OpenMP 4.0
   #pragma omp declare reduction (reduction-id : typename-list : expression) \
      initializer-clause[opt] new-line

   initializer-clause:
      initializer (omp_priv initializer)
      initializer (function-name (argument-list))  */

static void
cp_parser_omp_declare_reduction (cp_parser *parser, cp_token *pragma_tok,
				 enum pragma_context)
{
  auto_vec<tree> types;
  enum tree_code reduc_code = ERROR_MARK;
  tree reduc_id = NULL_TREE, orig_reduc_id = NULL_TREE, type;
  unsigned int i;
  cp_token *first_token;
  cp_token_cache *cp;
  int errs;
  void *p;

  /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
  p = obstack_alloc (&declarator_obstack, 0);

  if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    goto fail;

  switch (cp_lexer_peek_token (parser->lexer)->type)
    {
    case CPP_PLUS:
      reduc_code = PLUS_EXPR;
      break;
    case CPP_MULT:
      reduc_code = MULT_EXPR;
      break;
    case CPP_MINUS:
      reduc_code = MINUS_EXPR;
      break;
    case CPP_AND:
      reduc_code = BIT_AND_EXPR;
      break;
    case CPP_XOR:
      reduc_code = BIT_XOR_EXPR;
      break;
    case CPP_OR:
      reduc_code = BIT_IOR_EXPR;
      break;
    case CPP_AND_AND:
      reduc_code = TRUTH_ANDIF_EXPR;
      break;
    case CPP_OR_OR:
      reduc_code = TRUTH_ORIF_EXPR;
      break;
    case CPP_NAME:
      reduc_id = orig_reduc_id = cp_parser_identifier (parser);
      break;
    default:
      cp_parser_error (parser, "expected %<+%>, %<*%>, %<-%>, %<&%>, %<^%>, "
			       "%<|%>, %<&&%>, %<||%> or identifier");
      goto fail;
    }

  if (reduc_code != ERROR_MARK)
    cp_lexer_consume_token (parser->lexer);

  reduc_id = omp_reduction_id (reduc_code, reduc_id, NULL_TREE);
  if (reduc_id == error_mark_node)
    goto fail;

  if (!cp_parser_require (parser, CPP_COLON, RT_COLON))
    goto fail;

  /* Types may not be defined in declare reduction type list.  */
  const char *saved_message;
  saved_message = parser->type_definition_forbidden_message;
  parser->type_definition_forbidden_message
    = G_("types may not be defined in declare reduction type list");
  bool saved_colon_corrects_to_scope_p;
  saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;
  parser->colon_corrects_to_scope_p = false;
  bool saved_colon_doesnt_start_class_def_p;
  saved_colon_doesnt_start_class_def_p
    = parser->colon_doesnt_start_class_def_p;
  parser->colon_doesnt_start_class_def_p = true;

  while (true)
    {
      location_t loc = cp_lexer_peek_token (parser->lexer)->location;
      type = cp_parser_type_id (parser);
      if (type == error_mark_node)
	;
      else if (ARITHMETIC_TYPE_P (type)
	       && (orig_reduc_id == NULL_TREE
		   || (TREE_CODE (type) != COMPLEX_TYPE
		       && (id_equal (orig_reduc_id, "min")
			   || id_equal (orig_reduc_id, "max")))))
	error_at (loc, "predeclared arithmetic type %qT in "
		       "%<#pragma omp declare reduction%>", type);
      else if (FUNC_OR_METHOD_TYPE_P (type)
	       || TREE_CODE (type) == ARRAY_TYPE)
	error_at (loc, "function or array type %qT in "
		       "%<#pragma omp declare reduction%>", type);
      else if (TYPE_REF_P (type))
	error_at (loc, "reference type %qT in "
		       "%<#pragma omp declare reduction%>", type);
      else if (TYPE_QUALS_NO_ADDR_SPACE (type))
	error_at (loc, "%<const%>, %<volatile%> or %<__restrict%>-qualified "
		  "type %qT in %<#pragma omp declare reduction%>", type);
      else
	types.safe_push (type);

      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	break;
    }

  /* Restore the saved message.  */
  parser->type_definition_forbidden_message = saved_message;
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
  parser->colon_doesnt_start_class_def_p
    = saved_colon_doesnt_start_class_def_p;

  if (!cp_parser_require (parser, CPP_COLON, RT_COLON)
      || types.is_empty ())
    {
     fail:
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      goto done;
    }

  first_token = cp_lexer_peek_token (parser->lexer);
  cp = NULL;
  errs = errorcount;
  FOR_EACH_VEC_ELT (types, i, type)
    {
      tree fntype
	= build_function_type_list (void_type_node,
				    cp_build_reference_type (type, false),
				    NULL_TREE);
      tree this_reduc_id = reduc_id;
      if (!dependent_type_p (type))
	this_reduc_id = omp_reduction_id (ERROR_MARK, reduc_id, type);
      tree fndecl = build_lang_decl (FUNCTION_DECL, this_reduc_id, fntype);
      DECL_SOURCE_LOCATION (fndecl) = pragma_tok->location;
      DECL_ARTIFICIAL (fndecl) = 1;
      DECL_EXTERNAL (fndecl) = 1;
      DECL_DECLARED_INLINE_P (fndecl) = 1;
      DECL_IGNORED_P (fndecl) = 1;
      DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
      SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("<udr>"));
      DECL_ATTRIBUTES (fndecl)
	= tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
		     DECL_ATTRIBUTES (fndecl));
      bool block_scope = false;
      if (current_function_decl)
	{
	  block_scope = true;
	  DECL_CONTEXT (fndecl) = current_function_decl;
	  DECL_LOCAL_DECL_P (fndecl) = true;
	}

      if (processing_template_decl)
	fndecl = push_template_decl (fndecl);

      if (block_scope)
	{
	  if (!processing_template_decl)
	    pushdecl (fndecl);
	}
      else if (current_class_type)
	{
	  if (cp == NULL)
	    {
	      while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
		cp_lexer_consume_token (parser->lexer);
	      cp = cp_token_cache_new (first_token,
				       cp_lexer_peek_nth_token (parser->lexer,
								2));
	    }
	  DECL_STATIC_FUNCTION_P (fndecl) = 1;
	  finish_member_declaration (fndecl);
	  DECL_PENDING_INLINE_INFO (fndecl) = cp;
	  DECL_PENDING_INLINE_P (fndecl) = 1;
	  vec_safe_push (unparsed_funs_with_definitions, fndecl);
	  continue;
	}
      else
	{
	  DECL_CONTEXT (fndecl) = current_namespace;
	  tree d = pushdecl (fndecl);
	  /* We should never meet a matched duplicate decl.  */
	  gcc_checking_assert (d == error_mark_node || d == fndecl);
	}

      tree block = NULL_TREE;
      if (!block_scope)
	start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);
      else
	block = begin_omp_structured_block ();
      if (cp)
	{
	  cp_parser_push_lexer_for_tokens (parser, cp);
	  parser->lexer->in_pragma = true;
	}

      bool ok = cp_parser_omp_declare_reduction_exprs (fndecl, parser);

      if (cp)
	cp_parser_pop_lexer (parser);
      if (!block_scope)
	finish_function (/*inline_p=*/false);
      else
	{
	  DECL_CONTEXT (fndecl) = current_function_decl;
	  if (DECL_TEMPLATE_INFO (fndecl))
	    DECL_CONTEXT (DECL_TI_TEMPLATE (fndecl)) = current_function_decl;
	}
      if (!ok)
	goto fail;

      if (block_scope)
	{
	  block = finish_omp_structured_block (block);
	  if (TREE_CODE (block) == BIND_EXPR)
	    DECL_SAVED_TREE (fndecl) = BIND_EXPR_BODY (block);
	  else if (TREE_CODE (block) == STATEMENT_LIST)
	    DECL_SAVED_TREE (fndecl) = block;
	  if (processing_template_decl)
	    add_decl_expr (fndecl);
	}

      cp_check_omp_declare_reduction (fndecl);
      if (cp == NULL && types.length () > 1)
	cp = cp_token_cache_new (first_token,
				 cp_lexer_peek_nth_token (parser->lexer, 2));
      if (errs != errorcount)
	break;
    }

  cp_parser_require_pragma_eol (parser, pragma_tok);

 done:
  /* Free any declarators allocated.  */
  obstack_free (&declarator_obstack, p);
}

/* OpenMP 4.0
   #pragma omp declare simd declare-simd-clauses[optseq] new-line
   #pragma omp declare reduction (reduction-id : typename-list : expression) \
      initializer-clause[opt] new-line
   #pragma omp declare target new-line

   OpenMP 5.0
   #pragma omp declare variant (identifier) match (context-selector)  */

static bool
cp_parser_omp_declare (cp_parser *parser, cp_token *pragma_tok,
		       enum pragma_context context)
{
  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "simd") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_omp_declare_simd (parser, pragma_tok,
				      context, false);
	  return true;
	}
      if (flag_openmp && strcmp (p, "variant") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_omp_declare_simd (parser, pragma_tok,
				      context, true);
	  return true;
	}
      cp_ensure_no_omp_declare_simd (parser);
      if (strcmp (p, "reduction") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_omp_declare_reduction (parser, pragma_tok,
					   context);
	  return false;
	}
      if (!flag_openmp)  /* flag_openmp_simd  */
	{
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  return false;
	}
      if (strcmp (p, "target") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_omp_declare_target (parser, pragma_tok);
	  return false;
	}
    }
  cp_parser_error (parser, "expected %<simd%>, %<reduction%>, "
			   "%<target%> or %<variant%>");
  cp_parser_require_pragma_eol (parser, pragma_tok);
  return false;
}

/* OpenMP 5.0
   #pragma omp requires clauses[optseq] new-line  */

static bool
cp_parser_omp_requires (cp_parser *parser, cp_token *pragma_tok)
{
  enum omp_requires new_req = (enum omp_requires) 0;

  location_t loc = pragma_tok->location;
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
	{
	  tree id = cp_lexer_peek_token (parser->lexer)->u.value;
	  const char *p = IDENTIFIER_POINTER (id);
	  location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
	  enum omp_requires this_req = (enum omp_requires) 0;

	  if (!strcmp (p, "unified_address"))
	    this_req = OMP_REQUIRES_UNIFIED_ADDRESS;
	  else if (!strcmp (p, "unified_shared_memory"))
	    this_req = OMP_REQUIRES_UNIFIED_SHARED_MEMORY;
	  else if (!strcmp (p, "dynamic_allocators"))
	    this_req = OMP_REQUIRES_DYNAMIC_ALLOCATORS;
	  else if (!strcmp (p, "reverse_offload"))
	    this_req = OMP_REQUIRES_REVERSE_OFFLOAD;
	  else if (!strcmp (p, "atomic_default_mem_order"))
	    {
	      cp_lexer_consume_token (parser->lexer);

	      matching_parens parens;
	      if (parens.require_open (parser))
		{
		  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
		    {
		      id = cp_lexer_peek_token (parser->lexer)->u.value;
		      p = IDENTIFIER_POINTER (id);

		      if (!strcmp (p, "seq_cst"))
			this_req
			  = (enum omp_requires) OMP_MEMORY_ORDER_SEQ_CST;
		      else if (!strcmp (p, "relaxed"))
			this_req
			  = (enum omp_requires) OMP_MEMORY_ORDER_RELAXED;
		      else if (!strcmp (p, "acq_rel"))
			this_req
			  = (enum omp_requires) OMP_MEMORY_ORDER_ACQ_REL;
		    }
		  if (this_req == 0)
		    {
		      error_at (cp_lexer_peek_token (parser->lexer)->location,
				"expected %<seq_cst%>, %<relaxed%> or "
				"%<acq_rel%>");
		      switch (cp_lexer_peek_token (parser->lexer)->type)
			{
			case CPP_EOF:
			case CPP_PRAGMA_EOL:
			case CPP_CLOSE_PAREN:
			  break;
			default:
			  if (cp_lexer_nth_token_is (parser->lexer, 2,
						     CPP_CLOSE_PAREN))
			    cp_lexer_consume_token (parser->lexer);
			  break;
			}
		    }
		  else
		    cp_lexer_consume_token (parser->lexer);

		  if (!parens.require_close (parser))
		    cp_parser_skip_to_closing_parenthesis (parser,
							   /*recovering=*/true,
							   /*or_comma=*/false,
							   /*consume_paren=*/
							   true);

		  if (this_req == 0)
		    {
		      cp_parser_require_pragma_eol (parser, pragma_tok);
		      return false;
		    }
		}
	      p = NULL;
	    }
	  else
	    {
	      error_at (cloc, "expected %<unified_address%>, "
			      "%<unified_shared_memory%>, "
			      "%<dynamic_allocators%>, "
			       "%<reverse_offload%> "
			       "or %<atomic_default_mem_order%> clause");
	      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	      return false;
	    }
	  if (p)
	    cp_lexer_consume_token (parser->lexer);
	  if (this_req)
	    {
	      if ((this_req & ~OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
		{
		  if ((this_req & new_req) != 0)
		    error_at (cloc, "too many %qs clauses", p);
		  if (this_req != OMP_REQUIRES_DYNAMIC_ALLOCATORS
		      && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0)
		    error_at (cloc, "%qs clause used lexically after first "
				    "target construct or offloading API", p);
		}
	      else if ((new_req & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
		{
		  error_at (cloc, "too many %qs clauses",
			    "atomic_default_mem_order");
		  this_req = (enum omp_requires) 0;
		}
	      else if ((omp_requires_mask
			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER) != 0)
		{
		  error_at (cloc, "more than one %<atomic_default_mem_order%>"
				  " clause in a single compilation unit");
		  this_req
		    = (enum omp_requires)
		       (omp_requires_mask
			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER);
		}
	      else if ((omp_requires_mask
			& OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED) != 0)
		error_at (cloc, "%<atomic_default_mem_order%> clause used "
				"lexically after first %<atomic%> construct "
				"without memory order clause");
	      new_req = (enum omp_requires) (new_req | this_req);
	      omp_requires_mask
		= (enum omp_requires) (omp_requires_mask | this_req);
	      continue;
	    }
	}
      break;
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);

  if (new_req == 0)
    error_at (loc, "%<pragma omp requires%> requires at least one clause");
  return false;
}


/* OpenMP 5.1:
   #pragma omp nothing new-line  */

static void
cp_parser_omp_nothing (cp_parser *parser, cp_token *pragma_tok)
{
  cp_parser_require_pragma_eol (parser, pragma_tok);
}


/* OpenMP 5.1
   #pragma omp error clauses[optseq] new-line  */

static bool
cp_parser_omp_error (cp_parser *parser, cp_token *pragma_tok,
		     enum pragma_context context)
{
  int at_compilation = -1;
  int severity_fatal = -1;
  tree message = NULL_TREE;
  bool bad = false;
  location_t loc = pragma_tok->location;

  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
	  && cp_lexer_nth_token_is (parser->lexer, 2, CPP_NAME))
	cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
	break;

      const char *p
	= IDENTIFIER_POINTER (cp_lexer_peek_token (parser->lexer)->u.value);
      location_t cloc = cp_lexer_peek_token (parser->lexer)->location;
      static const char *args[] = {
	"execution", "compilation", "warning", "fatal"
      };
      int *v = NULL;
      int idx = 0, n = -1;
      tree m = NULL_TREE;

      if (!strcmp (p, "at"))
	v = &at_compilation;
      else if (!strcmp (p, "severity"))
	{
	  v = &severity_fatal;
	  idx += 2;
	}
      else if (strcmp (p, "message"))
	{
	  error_at (cloc,
		    "expected %<at%>, %<severity%> or %<message%> clause");
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  return false;
	}

      cp_lexer_consume_token (parser->lexer);

      matching_parens parens;
      if (parens.require_open (parser))
	{
	  if (v == NULL)
	    {
	      m = cp_parser_assignment_expression (parser);
	      if (type_dependent_expression_p (m))
		m = build1 (IMPLICIT_CONV_EXPR, const_string_type_node, m);
	      else
		m = perform_implicit_conversion_flags (const_string_type_node, m,
						       tf_warning_or_error,
						       LOOKUP_NORMAL);
	    }
	  else
	    {
	      if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
		{
		  tree val = cp_lexer_peek_token (parser->lexer)->u.value;
		  const char *q = IDENTIFIER_POINTER (val);

		  if (!strcmp (q, args[idx]))
		    n = 0;
		  else if (!strcmp (q, args[idx + 1]))
		    n = 1;
		}
	      if (n == -1)
		{
		  error_at (cp_lexer_peek_token (parser->lexer)->location,
			    "expected %qs or %qs", args[idx], args[idx + 1]);
		  bad = true;
		  switch (cp_lexer_peek_token (parser->lexer)->type)
		    {
		    case CPP_EOF:
		    case CPP_PRAGMA_EOL:
		    case CPP_CLOSE_PAREN:
		      break;
		    default:
		      if (cp_lexer_nth_token_is (parser->lexer, 2,
						 CPP_CLOSE_PAREN))
			cp_lexer_consume_token (parser->lexer);
		      break;
		    }
		}
	      else
		cp_lexer_consume_token (parser->lexer);
	    }

	  if (!parens.require_close (parser))
	    cp_parser_skip_to_closing_parenthesis (parser,
						   /*recovering=*/true,
						   /*or_comma=*/false,
						   /*consume_paren=*/
						   true);

	  if (v == NULL)
	    {
	      if (message)
		{
		  error_at (cloc, "too many %qs clauses", p);
		  bad = true;
		}
	      else
		message = m;
	    }
	  else if (n != -1)
	    {
	      if (*v != -1)
		{
		  error_at (cloc, "too many %qs clauses", p);
		  bad = true;
		}
	      else
		*v = n;
	    }
	}
      else
	bad = true;
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);
  if (bad)
    return true;

  if (at_compilation == -1)
    at_compilation = 1;
  if (severity_fatal == -1)
    severity_fatal = 1;
  if (!at_compilation)
    {
      if (context != pragma_compound)
	{
	  error_at (loc, "%<#pragma omp error%> with %<at(execution)%> clause "
			 "may only be used in compound statements");
	  return true;
	}
      tree fndecl
	= builtin_decl_explicit (severity_fatal ? BUILT_IN_GOMP_ERROR
						: BUILT_IN_GOMP_WARNING);
      if (!message)
	message = build_zero_cst (const_string_type_node);
      tree stmt = build_call_expr_loc (loc, fndecl, 2, message,
				       build_all_ones_cst (size_type_node));
      add_stmt (stmt);
      return true;
    }

  if (in_discarded_stmt)
    return false;

  const char *msg = NULL;
  if (message)
    {
      msg = c_getstr (fold_for_warn (message));
      if (msg == NULL)
	msg = _("<message unknown at compile time>");
    }
  if (msg)
    emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
		     "%<pragma omp error%> encountered: %s", msg);
  else
    emit_diagnostic (severity_fatal ? DK_ERROR : DK_WARNING, loc, 0,
		     "%<pragma omp error%> encountered");
  return false;
}

/* OpenMP 4.5:
   #pragma omp taskloop taskloop-clause[optseq] new-line
     for-loop

   #pragma omp taskloop simd taskloop-simd-clause[optseq] new-line
     for-loop  */

#define OMP_TASKLOOP_CLAUSE_MASK				\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_SHARED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FIRSTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LASTPRIVATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEFAULT)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_GRAINSIZE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_TASKS)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_COLLAPSE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNTIED)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_FINAL)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MERGEABLE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NOGROUP)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_PRIORITY)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_ALLOCATE)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_REDUCTION)	\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION))

static tree
cp_parser_omp_taskloop (cp_parser *parser, cp_token *pragma_tok,
			char *p_name, omp_clause_mask mask, tree *cclauses,
			bool *if_p)
{
  tree clauses, sb, ret;
  unsigned int save;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  strcat (p_name, " taskloop");
  mask |= OMP_TASKLOOP_CLAUSE_MASK;
  /* #pragma omp parallel master taskloop{, simd} disallow in_reduction
     clause.  */
  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_NUM_THREADS)) != 0)
    mask &= ~(OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IN_REDUCTION);

  if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
    {
      tree id = cp_lexer_peek_token (parser->lexer)->u.value;
      const char *p = IDENTIFIER_POINTER (id);

      if (strcmp (p, "simd") == 0)
	{
	  tree cclauses_buf[C_OMP_CLAUSE_SPLIT_COUNT];
	  if (cclauses == NULL)
	    cclauses = cclauses_buf;

	  cp_lexer_consume_token (parser->lexer);
	  if (!flag_openmp)  /* flag_openmp_simd  */
	    return cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
				       cclauses, if_p);
	  sb = begin_omp_structured_block ();
	  save = cp_parser_begin_omp_structured_block (parser);
	  ret = cp_parser_omp_simd (parser, pragma_tok, p_name, mask,
				    cclauses, if_p);
	  cp_parser_end_omp_structured_block (parser, save);
	  tree body = finish_omp_structured_block (sb);
	  if (ret == NULL)
	    return ret;
	  ret = make_node (OMP_TASKLOOP);
	  TREE_TYPE (ret) = void_type_node;
	  OMP_FOR_BODY (ret) = body;
	  OMP_FOR_CLAUSES (ret) = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
	  SET_EXPR_LOCATION (ret, loc);
	  add_stmt (ret);
	  return ret;
	}
    }
  if (!flag_openmp)  /* flag_openmp_simd  */
    {
      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
      return NULL_TREE;
    }

  clauses = cp_parser_omp_all_clauses (parser, mask, p_name, pragma_tok,
				       cclauses == NULL);
  if (cclauses)
    {
      cp_omp_split_clauses (loc, OMP_TASKLOOP, mask, clauses, cclauses);
      clauses = cclauses[C_OMP_CLAUSE_SPLIT_TASKLOOP];
    }

  keep_next_level (true);
  sb = begin_omp_structured_block ();
  save = cp_parser_begin_omp_structured_block (parser);

  ret = cp_parser_omp_for_loop (parser, OMP_TASKLOOP, clauses, cclauses,
				if_p);

  cp_parser_end_omp_structured_block (parser, save);
  add_stmt (finish_omp_for_block (finish_omp_structured_block (sb), ret));

  return ret;
}


/* OpenACC 2.0:
   # pragma acc routine oacc-routine-clause[optseq] new-line
     function-definition

   # pragma acc routine ( name ) oacc-routine-clause[optseq] new-line
*/

#define OACC_ROUTINE_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_GANG)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_WORKER)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_VECTOR)		\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_SEQ)			\
	| (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_NOHOST) )

/* Parse the OpenACC routine pragma.  This has an optional '( name )'
   component, which must resolve to a declared namespace-scope
   function.  The clauses are either processed directly (for a named
   function), or defered until the immediatley following declaration
   is parsed.  */

static void
cp_parser_oacc_routine (cp_parser *parser, cp_token *pragma_tok,
			enum pragma_context context)
{
  gcc_checking_assert (context == pragma_external);
  /* The checking for "another pragma following this one" in the "no optional
     '( name )'" case makes sure that we dont re-enter.  */
  gcc_checking_assert (parser->oacc_routine == NULL);

  cp_oacc_routine_data data;
  data.error_seen = false;
  data.fndecl_seen = false;
  data.tokens = vNULL;
  data.clauses = NULL_TREE;
  data.loc = pragma_tok->location;
  /* It is safe to take the address of a local variable; it will only be
     used while this scope is live.  */
  parser->oacc_routine = &data;

  /* Look for optional '( name )'.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      matching_parens parens;
      parens.consume_open (parser); /* '(' */

      /* We parse the name as an id-expression.  If it resolves to
	 anything other than a non-overloaded function at namespace
	 scope, it's an error.  */
      location_t name_loc = cp_lexer_peek_token (parser->lexer)->location;
      tree name = cp_parser_id_expression (parser,
					   /*template_keyword_p=*/false,
					   /*check_dependency_p=*/false,
					   /*template_p=*/NULL,
					   /*declarator_p=*/false,
					   /*optional_p=*/false);
      tree decl = (identifier_p (name)
		   ? cp_parser_lookup_name_simple (parser, name, name_loc)
		   : name);
      if (name != error_mark_node && decl == error_mark_node)
	cp_parser_name_lookup_error (parser, name, decl, NLE_NULL, name_loc);

      if (decl == error_mark_node
	  || !parens.require_close (parser))
	{
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  parser->oacc_routine = NULL;
	  return;
	}

      data.clauses
	= cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
				      "#pragma acc routine",
				      cp_lexer_peek_token (parser->lexer));
      /* The clauses are in reverse order; fix that to make later diagnostic
	 emission easier.  */
      data.clauses = nreverse (data.clauses);

      if (decl && is_overloaded_fn (decl)
	  && (TREE_CODE (decl) != FUNCTION_DECL
	      || DECL_FUNCTION_TEMPLATE_P  (decl)))
	{
	  error_at (name_loc,
		    "%<#pragma acc routine%> names a set of overloads");
	  parser->oacc_routine = NULL;
	  return;
	}

      /* Perhaps we should use the same rule as declarations in different
	 namespaces?  */
      if (!DECL_NAMESPACE_SCOPE_P (decl))
	{
	  error_at (name_loc,
		    "%qD does not refer to a namespace scope function", decl);
	  parser->oacc_routine = NULL;
	  return;
	}

      if (TREE_CODE (decl) != FUNCTION_DECL)
	{
	  error_at (name_loc, "%qD does not refer to a function", decl);
	  parser->oacc_routine = NULL;
	  return;
	}

      cp_finalize_oacc_routine (parser, decl, false);
      parser->oacc_routine = NULL;
    }
  else /* No optional '( name )'.  */
    {
      /* Store away all pragma tokens.  */
      while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
	cp_lexer_consume_token (parser->lexer);
      cp_parser_require_pragma_eol (parser, pragma_tok);
      struct cp_token_cache *cp
	= cp_token_cache_new (pragma_tok, cp_lexer_peek_token (parser->lexer));
      parser->oacc_routine->tokens.safe_push (cp);

      /* Emit a helpful diagnostic if there's another pragma following this
	 one.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_PRAGMA))
	{
	  cp_ensure_no_oacc_routine (parser);
	  data.tokens.release ();
	  /* ..., and then just keep going.  */
	  return;
	}

      /* We only have to consider the pragma_external case here.  */
      cp_parser_declaration (parser, NULL_TREE);
      if (parser->oacc_routine
	  && !parser->oacc_routine->fndecl_seen)
	cp_ensure_no_oacc_routine (parser);
      else
	parser->oacc_routine = NULL;
      data.tokens.release ();
    }
}

/* Finalize #pragma acc routine clauses after direct declarator has
   been parsed.  */

static tree
cp_parser_late_parsing_oacc_routine (cp_parser *parser, tree attrs)
{
  struct cp_token_cache *ce;
  cp_oacc_routine_data *data = parser->oacc_routine;

  if (!data->error_seen && data->fndecl_seen)
    {
      error_at (data->loc,
		"%<#pragma acc routine%> not immediately followed by "
		"a single function declaration or definition");
      data->error_seen = true;
    }
  if (data->error_seen)
    return attrs;

  gcc_checking_assert (data->tokens.length () == 1);
  ce = data->tokens[0];

  cp_parser_push_lexer_for_tokens (parser, ce);
  parser->lexer->in_pragma = true;
  gcc_assert (cp_lexer_peek_token (parser->lexer)->type == CPP_PRAGMA);

  cp_token *pragma_tok = cp_lexer_consume_token (parser->lexer);
  gcc_checking_assert (parser->oacc_routine->clauses == NULL_TREE);
  parser->oacc_routine->clauses
    = cp_parser_oacc_all_clauses (parser, OACC_ROUTINE_CLAUSE_MASK,
				  "#pragma acc routine", pragma_tok);
  /* The clauses are in reverse order; fix that to make later diagnostic
     emission easier.  */
  parser->oacc_routine->clauses = nreverse (parser->oacc_routine->clauses);
  cp_parser_pop_lexer (parser);
  /* Later, cp_finalize_oacc_routine will process the clauses.  */
  parser->oacc_routine->fndecl_seen = true;

  return attrs;
}

/* Apply any saved OpenACC routine clauses to a just-parsed
   declaration.  */

static void
cp_finalize_oacc_routine (cp_parser *parser, tree fndecl, bool is_defn)
{
  if (UNLIKELY (parser->oacc_routine != NULL))
    {
      /* Keep going if we're in error reporting mode.  */
      if (parser->oacc_routine->error_seen
	  || fndecl == error_mark_node)
	return;

      if (TREE_CODE (fndecl) != FUNCTION_DECL)
	{
	  if (parser->oacc_routine->fndecl_seen)
	    {
	      error_at (parser->oacc_routine->loc,
			"%<#pragma acc routine%> not immediately followed by"
			" a single function declaration or definition");
	      parser->oacc_routine = NULL;
	      return;
	    }

	  cp_ensure_no_oacc_routine (parser);
	  return;
	}

      int compatible
	= oacc_verify_routine_clauses (fndecl, &parser->oacc_routine->clauses,
				       parser->oacc_routine->loc,
				       "#pragma acc routine");
      if (compatible < 0)
	{
	  parser->oacc_routine = NULL;
	  return;
	}
      if (compatible > 0)
	{
	}
      else
	{
	  if (TREE_USED (fndecl) || (!is_defn && DECL_SAVED_TREE (fndecl)))
	    {
	      error_at (parser->oacc_routine->loc,
			TREE_USED (fndecl)
			? G_("%<#pragma acc routine%> must be applied before"
			     " use")
			: G_("%<#pragma acc routine%> must be applied before"
			     " definition"));
	      parser->oacc_routine = NULL;
	      return;
	    }

	  /* Set the routine's level of parallelism.  */
	  tree dims = oacc_build_routine_dims (parser->oacc_routine->clauses);
	  oacc_replace_fn_attrib (fndecl, dims);

	  /* Add an "omp declare target" attribute.  */
	  DECL_ATTRIBUTES (fndecl)
	    = tree_cons (get_identifier ("omp declare target"),
			 parser->oacc_routine->clauses,
			 DECL_ATTRIBUTES (fndecl));
	}
    }
}

/* Main entry point to OpenMP statement pragmas.  */

static void
cp_parser_omp_construct (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
{
  tree stmt;
  char p_name[sizeof "#pragma omp teams distribute parallel for simd"];
  omp_clause_mask mask (0);

  switch (cp_parser_pragma_kind (pragma_tok))
    {
    case PRAGMA_OACC_ATOMIC:
      cp_parser_omp_atomic (parser, pragma_tok, true);
      return;
    case PRAGMA_OACC_CACHE:
      stmt = cp_parser_oacc_cache (parser, pragma_tok);
      break;
    case PRAGMA_OACC_DATA:
      stmt = cp_parser_oacc_data (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OACC_ENTER_DATA:
      stmt = cp_parser_oacc_enter_exit_data (parser, pragma_tok, true);
      break;
    case PRAGMA_OACC_EXIT_DATA:
      stmt = cp_parser_oacc_enter_exit_data (parser, pragma_tok, false);
      break;
    case PRAGMA_OACC_HOST_DATA:
      stmt = cp_parser_oacc_host_data (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OACC_KERNELS:
    case PRAGMA_OACC_PARALLEL:
    case PRAGMA_OACC_SERIAL:
      strcpy (p_name, "#pragma acc");
      stmt = cp_parser_oacc_compute (parser, pragma_tok, p_name, if_p);
      break;
    case PRAGMA_OACC_LOOP:
      strcpy (p_name, "#pragma acc");
      stmt = cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, NULL,
				  if_p);
      break;
    case PRAGMA_OACC_UPDATE:
      stmt = cp_parser_oacc_update (parser, pragma_tok);
      break;
    case PRAGMA_OACC_WAIT:
      stmt = cp_parser_oacc_wait (parser, pragma_tok);
      break;
    case PRAGMA_OMP_ALLOCATE:
      cp_parser_omp_allocate (parser, pragma_tok);
      return;
    case PRAGMA_OMP_ATOMIC:
      cp_parser_omp_atomic (parser, pragma_tok, false);
      return;
    case PRAGMA_OMP_CRITICAL:
      stmt = cp_parser_omp_critical (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OMP_DISTRIBUTE:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_distribute (parser, pragma_tok, p_name, mask, NULL,
				       if_p);
      break;
    case PRAGMA_OMP_FOR:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_for (parser, pragma_tok, p_name, mask, NULL,
				if_p);
      break;
    case PRAGMA_OMP_LOOP:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_loop (parser, pragma_tok, p_name, mask, NULL,
				 if_p);
      break;
    case PRAGMA_OMP_MASKED:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_masked (parser, pragma_tok, p_name, mask, NULL,
				   if_p);
      break;
    case PRAGMA_OMP_MASTER:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_master (parser, pragma_tok, p_name, mask, NULL,
				   if_p);
      break;
    case PRAGMA_OMP_PARALLEL:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_parallel (parser, pragma_tok, p_name, mask, NULL,
				     if_p);
      break;
    case PRAGMA_OMP_SCOPE:
      stmt = cp_parser_omp_scope (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OMP_SECTIONS:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_sections (parser, pragma_tok, p_name, mask, NULL);
      break;
    case PRAGMA_OMP_SIMD:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_simd (parser, pragma_tok, p_name, mask, NULL,
				 if_p);
      break;
    case PRAGMA_OMP_SINGLE:
      stmt = cp_parser_omp_single (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OMP_TASK:
      stmt = cp_parser_omp_task (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OMP_TASKGROUP:
      stmt = cp_parser_omp_taskgroup (parser, pragma_tok, if_p);
      break;
    case PRAGMA_OMP_TASKLOOP:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_taskloop (parser, pragma_tok, p_name, mask, NULL,
				     if_p);
      break;
    case PRAGMA_OMP_TEAMS:
      strcpy (p_name, "#pragma omp");
      stmt = cp_parser_omp_teams (parser, pragma_tok, p_name, mask, NULL,
				  if_p);
      break;
    case PRAGMA_OMP_ASSUME:
      cp_parser_omp_assume (parser, pragma_tok, if_p);
      return;
    default:
      gcc_unreachable ();
    }

  protected_set_expr_location (stmt, pragma_tok->location);
}

/* Transactional Memory parsing routines.  */

/* Parse a transaction attribute.

   txn-attribute:
	attribute
	[ [ identifier ] ]

   We use this instead of cp_parser_attributes_opt for transactions to avoid
   the pedwarn in C++98 mode.  */

static tree
cp_parser_txn_attribute_opt (cp_parser *parser)
{
  cp_token *token;
  tree attr_name, attr = NULL;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_ATTRIBUTE))
    return cp_parser_attributes_opt (parser);

  if (cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_SQUARE))
    return NULL_TREE;
  cp_lexer_consume_token (parser->lexer);
  if (!cp_parser_require (parser, CPP_OPEN_SQUARE, RT_OPEN_SQUARE))
    goto error1;

  token = cp_lexer_peek_token (parser->lexer);
  if (token->type == CPP_NAME || token->type == CPP_KEYWORD)
    {
      token = cp_lexer_consume_token (parser->lexer);

      attr_name = (token->type == CPP_KEYWORD
		   /* For keywords, use the canonical spelling,
		      not the parsed identifier.  */
		   ? ridpointers[(int) token->keyword]
		   : token->u.value);
      attr = build_tree_list (attr_name, NULL_TREE);
    }
  else
    cp_parser_error (parser, "expected identifier");

  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
 error1:
  cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE);
  return attr;
}

/* Parse a __transaction_atomic or __transaction_relaxed statement.

   transaction-statement:
     __transaction_atomic txn-attribute[opt] txn-noexcept-spec[opt]
       compound-statement
     __transaction_relaxed txn-noexcept-spec[opt] compound-statement
*/

static tree
cp_parser_transaction (cp_parser *parser, cp_token *token)
{
  unsigned char old_in = parser->in_transaction;
  unsigned char this_in = 1, new_in;
  enum rid keyword = token->keyword;
  tree stmt, attrs, noex;

  cp_lexer_consume_token (parser->lexer);

  if (keyword == RID_TRANSACTION_RELAXED
      || keyword == RID_SYNCHRONIZED)
    this_in |= TM_STMT_ATTR_RELAXED;
  else
    {
      attrs = cp_parser_txn_attribute_opt (parser);
      if (attrs)
	this_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
    }

  /* Parse a noexcept specification.  */
  if (keyword == RID_ATOMIC_NOEXCEPT)
    noex = boolean_true_node;
  else if (keyword == RID_ATOMIC_CANCEL)
    {
      /* cancel-and-throw is unimplemented.  */
      sorry ("%<atomic_cancel%>");
      noex = NULL_TREE;
    }
  else
    noex = cp_parser_noexcept_specification_opt (parser,
						 CP_PARSER_FLAGS_NONE,
						 /*require_constexpr=*/true,
						 /*consumed_expr=*/NULL,
						 /*return_cond=*/true);

  /* Keep track if we're in the lexical scope of an outer transaction.  */
  new_in = this_in | (old_in & TM_STMT_ATTR_OUTER);

  stmt = begin_transaction_stmt (token->location, NULL, this_in);

  parser->in_transaction = new_in;
  cp_parser_compound_statement (parser, NULL, BCS_TRANSACTION, false);
  parser->in_transaction = old_in;

  finish_transaction_stmt (stmt, NULL, this_in, noex);

  return stmt;
}

/* Parse a __transaction_atomic or __transaction_relaxed expression.

   transaction-expression:
     __transaction_atomic txn-noexcept-spec[opt] ( expression )
     __transaction_relaxed txn-noexcept-spec[opt] ( expression )
*/

static tree
cp_parser_transaction_expression (cp_parser *parser, enum rid keyword)
{
  unsigned char old_in = parser->in_transaction;
  unsigned char this_in = 1;
  cp_token *token;
  tree expr, noex;
  bool noex_expr;
  location_t loc = cp_lexer_peek_token (parser->lexer)->location;

  gcc_assert (keyword == RID_TRANSACTION_ATOMIC
      || keyword == RID_TRANSACTION_RELAXED);

  if (!flag_tm)
    error_at (loc,
	      keyword == RID_TRANSACTION_RELAXED
	      ? G_("%<__transaction_relaxed%> without transactional memory "
		  "support enabled")
	      : G_("%<__transaction_atomic%> without transactional memory "
		   "support enabled"));

  token = cp_parser_require_keyword (parser, keyword,
      (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
	  : RT_TRANSACTION_RELAXED));
  gcc_assert (token != NULL);

  if (keyword == RID_TRANSACTION_RELAXED)
    this_in |= TM_STMT_ATTR_RELAXED;

  /* Set this early.  This might mean that we allow transaction_cancel in
     an expression that we find out later actually has to be a constexpr.
     However, we expect that cxx_constant_value will be able to deal with
     this; also, if the noexcept has no constexpr, then what we parse next
     really is a transaction's body.  */
  parser->in_transaction = this_in;

  /* Parse a noexcept specification.  */
  noex = cp_parser_noexcept_specification_opt (parser,
					       CP_PARSER_FLAGS_NONE,
					       /*require_constexpr=*/false,
					       &noex_expr,
					       /*return_cond=*/true);

  if (!noex || !noex_expr
      || cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
    {
      matching_parens parens;
      parens.require_open (parser);

      expr = cp_parser_expression (parser);
      expr = finish_parenthesized_expr (expr);

      parens.require_close (parser);
    }
  else
    {
      /* The only expression that is available got parsed for the noexcept
         already.  noexcept is true then.  */
      expr = noex;
      noex = boolean_true_node;
    }

  expr = build_transaction_expr (token->location, expr, this_in, noex);
  parser->in_transaction = old_in;

  if (cp_parser_non_integral_constant_expression (parser, NIC_TRANSACTION))
    return error_mark_node;

  return (flag_tm ? expr : error_mark_node);
}

/* Parse a function-transaction-block.

   function-transaction-block:
     __transaction_atomic txn-attribute[opt] ctor-initializer[opt]
	 function-body
     __transaction_atomic txn-attribute[opt] function-try-block
     __transaction_relaxed ctor-initializer[opt] function-body
     __transaction_relaxed function-try-block
*/

static void
cp_parser_function_transaction (cp_parser *parser, enum rid keyword)
{
  unsigned char old_in = parser->in_transaction;
  unsigned char new_in = 1;
  tree compound_stmt, stmt, attrs;
  cp_token *token;

  gcc_assert (keyword == RID_TRANSACTION_ATOMIC
      || keyword == RID_TRANSACTION_RELAXED);
  token = cp_parser_require_keyword (parser, keyword,
      (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
	  : RT_TRANSACTION_RELAXED));
  gcc_assert (token != NULL);

  if (keyword == RID_TRANSACTION_RELAXED)
    new_in |= TM_STMT_ATTR_RELAXED;
  else
    {
      attrs = cp_parser_txn_attribute_opt (parser);
      if (attrs)
	new_in |= parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER);
    }

  stmt = begin_transaction_stmt (token->location, &compound_stmt, new_in);

  parser->in_transaction = new_in;

  if (cp_lexer_next_token_is_keyword (parser->lexer, RID_TRY))
    cp_parser_function_try_block (parser);
  else
    cp_parser_ctor_initializer_opt_and_function_body
      (parser, /*in_function_try_block=*/false);

  parser->in_transaction = old_in;

  finish_transaction_stmt (stmt, compound_stmt, new_in, NULL_TREE);
}

/* Parse a __transaction_cancel statement.

   cancel-statement:
     __transaction_cancel txn-attribute[opt] ;
     __transaction_cancel txn-attribute[opt] throw-expression ;

   ??? Cancel and throw is not yet implemented.  */

static tree
cp_parser_transaction_cancel (cp_parser *parser)
{
  cp_token *token;
  bool is_outer = false;
  tree stmt, attrs;

  token = cp_parser_require_keyword (parser, RID_TRANSACTION_CANCEL,
				     RT_TRANSACTION_CANCEL);
  gcc_assert (token != NULL);

  attrs = cp_parser_txn_attribute_opt (parser);
  if (attrs)
    is_outer = (parse_tm_stmt_attr (attrs, TM_STMT_ATTR_OUTER) != 0);

  /* ??? Parse cancel-and-throw here.  */

  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);

  if (!flag_tm)
    {
      error_at (token->location, "%<__transaction_cancel%> without "
		"transactional memory support enabled");
      return error_mark_node;
    }
  else if (parser->in_transaction & TM_STMT_ATTR_RELAXED)
    {
      error_at (token->location, "%<__transaction_cancel%> within a "
		"%<__transaction_relaxed%>");
      return error_mark_node;
    }
  else if (is_outer)
    {
      if ((parser->in_transaction & TM_STMT_ATTR_OUTER) == 0
	  && !is_tm_may_cancel_outer (current_function_decl))
	{
	  error_at (token->location, "outer %<__transaction_cancel%> not "
		    "within outer %<__transaction_atomic%>");
	  error_at (token->location,
		    "  or a %<transaction_may_cancel_outer%> function");
	  return error_mark_node;
	}
    }
  else if (parser->in_transaction == 0)
    {
      error_at (token->location, "%<__transaction_cancel%> not within "
		"%<__transaction_atomic%>");
      return error_mark_node;
    }

  stmt = build_tm_abort_call (token->location, is_outer);
  add_stmt (stmt);

  return stmt;
}


/* Special handling for the first token or line in the file.  The first
   thing in the file might be #pragma GCC pch_preprocess, which loads a
   PCH file, which is a GC collection point.  So we need to handle this
   first pragma without benefit of an existing lexer structure.

   Always returns one token to the caller in *FIRST_TOKEN.  This is
   either the true first token of the file, or the first token after
   the initial pragma.  */

static void
cp_parser_initial_pragma (cp_token *first_token)
{
  if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS)
    return;

  cp_lexer_get_preprocessor_token (0, first_token);

  tree name = NULL;
  if (first_token->type == CPP_STRING)
    {
      name = first_token->u.value;

      cp_lexer_get_preprocessor_token (0, first_token);
    }

  /* Skip to the end of the pragma.  */
  if (first_token->type != CPP_PRAGMA_EOL)
    {
      error_at (first_token->location,
		"malformed %<#pragma GCC pch_preprocess%>");
      do
	cp_lexer_get_preprocessor_token (0, first_token);
      while (first_token->type != CPP_PRAGMA_EOL);
    }

  /* Now actually load the PCH file.  */
  if (name)
    c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));

  /* Read one more token to return to our caller.  We have to do this
     after reading the PCH file in, since its pointers have to be
     live.  */
  cp_lexer_get_preprocessor_token (0, first_token);
}

/* Parse a pragma GCC ivdep.  */

static bool
cp_parser_pragma_ivdep (cp_parser *parser, cp_token *pragma_tok)
{
  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
  return true;
}

/* Parse a pragma GCC unroll.  */

static unsigned short
cp_parser_pragma_unroll (cp_parser *parser, cp_token *pragma_tok)
{
  location_t location = cp_lexer_peek_token (parser->lexer)->location;
  tree expr = cp_parser_constant_expression (parser);
  unsigned short unroll;
  expr = maybe_constant_value (expr);
  HOST_WIDE_INT lunroll = 0;
  if (!INTEGRAL_TYPE_P (TREE_TYPE (expr))
      || TREE_CODE (expr) != INTEGER_CST
      || (lunroll = tree_to_shwi (expr)) < 0
      || lunroll >= USHRT_MAX)
    {
      error_at (location, "%<#pragma GCC unroll%> requires an"
		" assignment-expression that evaluates to a non-negative"
		" integral constant less than %u", USHRT_MAX);
      unroll = 0;
    }
  else
    {
      unroll = (unsigned short)lunroll;
      if (unroll == 0)
	unroll = 1;
    }
  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
  return unroll;
}

/* Normal parsing of a pragma token.  Here we can (and must) use the
   regular lexer.  */

static bool
cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
{
  cp_token *pragma_tok;
  unsigned int id;
  tree stmt;
  bool ret = false;

  pragma_tok = cp_lexer_consume_token (parser->lexer);
  gcc_assert (pragma_tok->type == CPP_PRAGMA);
  parser->lexer->in_pragma = true;

  id = cp_parser_pragma_kind (pragma_tok);
  if (id != PRAGMA_OMP_DECLARE && id != PRAGMA_OACC_ROUTINE)
    cp_ensure_no_omp_declare_simd (parser);
  switch (id)
    {
    case PRAGMA_GCC_PCH_PREPROCESS:
      error_at (pragma_tok->location,
		"%<#pragma GCC pch_preprocess%> must be first");
      break;

    case PRAGMA_OMP_BARRIER:
      switch (context)
	{
	case pragma_compound:
	  cp_parser_omp_barrier (parser, pragma_tok);
	  return false;
	case pragma_stmt:
	  error_at (pragma_tok->location, "%<#pragma %s%> may only be "
		    "used in compound statements", "omp barrier");
	  ret = true;
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_DEPOBJ:
      switch (context)
	{
	case pragma_compound:
	  cp_parser_omp_depobj (parser, pragma_tok);
	  return false;
	case pragma_stmt:
	  error_at (pragma_tok->location, "%<#pragma %s%> may only be "
		    "used in compound statements", "omp depobj");
	  ret = true;
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_FLUSH:
      switch (context)
	{
	case pragma_compound:
	  cp_parser_omp_flush (parser, pragma_tok);
	  return false;
	case pragma_stmt:
	  error_at (pragma_tok->location, "%<#pragma %s%> may only be "
		    "used in compound statements", "omp flush");
	  ret = true;
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_TASKWAIT:
      switch (context)
	{
	case pragma_compound:
	  cp_parser_omp_taskwait (parser, pragma_tok);
	  return false;
	case pragma_stmt:
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "omp taskwait");
	  ret = true;
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_TASKYIELD:
      switch (context)
	{
	case pragma_compound:
	  cp_parser_omp_taskyield (parser, pragma_tok);
	  return false;
	case pragma_stmt:
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "omp taskyield");
	  ret = true;
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_CANCEL:
      switch (context)
	{
	case pragma_compound:
	  cp_parser_omp_cancel (parser, pragma_tok);
	  return false;
	case pragma_stmt:
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "omp cancel");
	  ret = true;
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_CANCELLATION_POINT:
      return cp_parser_omp_cancellation_point (parser, pragma_tok, context);

    case PRAGMA_OMP_THREADPRIVATE:
      cp_parser_omp_threadprivate (parser, pragma_tok);
      return false;

    case PRAGMA_OMP_DECLARE:
      return cp_parser_omp_declare (parser, pragma_tok, context);

    case PRAGMA_OACC_DECLARE:
      cp_parser_oacc_declare (parser, pragma_tok);
      return false;

    case PRAGMA_OACC_ENTER_DATA:
      if (context == pragma_stmt)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "acc enter data");
	  ret = true;
	  break;
	}
      else if (context != pragma_compound)
	goto bad_stmt;
      cp_parser_omp_construct (parser, pragma_tok, if_p);
      return true;

    case PRAGMA_OACC_EXIT_DATA:
      if (context == pragma_stmt)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "acc exit data");
	  ret = true;
	  break;
	}
      else if (context != pragma_compound)
	goto bad_stmt;
      cp_parser_omp_construct (parser, pragma_tok, if_p);
      return true;

    case PRAGMA_OACC_ROUTINE:
      if (context != pragma_external)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma acc routine%> must be at file scope");
	  ret = true;
	  break;
	}
      cp_parser_oacc_routine (parser, pragma_tok, context);
      return false;

    case PRAGMA_OACC_UPDATE:
      if (context == pragma_stmt)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "acc update");
	  ret = true;
	  break;
	}
      else if (context != pragma_compound)
	goto bad_stmt;
      cp_parser_omp_construct (parser, pragma_tok, if_p);
      return true;

    case PRAGMA_OACC_WAIT:
      if (context == pragma_stmt)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma %s%> may only be used in compound statements",
		    "acc wait");
	  ret = true;
	  break;
	}
      else if (context != pragma_compound)
	goto bad_stmt;
      cp_parser_omp_construct (parser, pragma_tok, if_p);
      return true;
    case PRAGMA_OMP_ALLOCATE:
      cp_parser_omp_allocate (parser, pragma_tok);
      return false;
    case PRAGMA_OACC_ATOMIC:
    case PRAGMA_OACC_CACHE:
    case PRAGMA_OACC_DATA:
    case PRAGMA_OACC_HOST_DATA:
    case PRAGMA_OACC_KERNELS:
    case PRAGMA_OACC_LOOP:
    case PRAGMA_OACC_PARALLEL:
    case PRAGMA_OACC_SERIAL:
    case PRAGMA_OMP_ASSUME:
    case PRAGMA_OMP_ATOMIC:
    case PRAGMA_OMP_CRITICAL:
    case PRAGMA_OMP_DISTRIBUTE:
    case PRAGMA_OMP_FOR:
    case PRAGMA_OMP_LOOP:
    case PRAGMA_OMP_MASKED:
    case PRAGMA_OMP_MASTER:
    case PRAGMA_OMP_PARALLEL:
    case PRAGMA_OMP_SCOPE:
    case PRAGMA_OMP_SECTIONS:
    case PRAGMA_OMP_SIMD:
    case PRAGMA_OMP_SINGLE:
    case PRAGMA_OMP_TASK:
    case PRAGMA_OMP_TASKGROUP:
    case PRAGMA_OMP_TASKLOOP:
    case PRAGMA_OMP_TEAMS:
      if (context != pragma_stmt && context != pragma_compound)
	goto bad_stmt;
      stmt = push_omp_privatization_clauses (false);
      cp_parser_omp_construct (parser, pragma_tok, if_p);
      pop_omp_privatization_clauses (stmt);
      return true;

    case PRAGMA_OMP_REQUIRES:
      if (context != pragma_external)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma omp requires%> may only be used at file or "
		    "namespace scope");
	  ret = true;
	  break;
	}
      return cp_parser_omp_requires (parser, pragma_tok);

    case PRAGMA_OMP_ASSUMES:
      if (context != pragma_external)
	{
	  error_at (pragma_tok->location,
		    "%<#pragma omp assumes%> may only be used at file or "
		    "namespace scope");
	  ret = true;
	  break;
	}
      return cp_parser_omp_assumes (parser, pragma_tok);

    case PRAGMA_OMP_NOTHING:
      cp_parser_omp_nothing (parser, pragma_tok);
      return false;

    case PRAGMA_OMP_ERROR:
      return cp_parser_omp_error (parser, pragma_tok, context);

    case PRAGMA_OMP_ORDERED:
      if (context != pragma_stmt && context != pragma_compound)
	goto bad_stmt;
      stmt = push_omp_privatization_clauses (false);
      ret = cp_parser_omp_ordered (parser, pragma_tok, context, if_p);
      pop_omp_privatization_clauses (stmt);
      return ret;

    case PRAGMA_OMP_TARGET:
      if (context != pragma_stmt && context != pragma_compound)
	goto bad_stmt;
      stmt = push_omp_privatization_clauses (false);
      ret = cp_parser_omp_target (parser, pragma_tok, context, if_p);
      pop_omp_privatization_clauses (stmt);
      return ret;

    case PRAGMA_OMP_BEGIN:
      cp_parser_omp_begin (parser, pragma_tok);
      return false;

    case PRAGMA_OMP_END:
      cp_parser_omp_end (parser, pragma_tok);
      return false;

    case PRAGMA_OMP_SCAN:
      error_at (pragma_tok->location,
		"%<#pragma omp scan%> may only be used in "
		"a loop construct with %<inscan%> %<reduction%> clause");
      break;

    case PRAGMA_OMP_SECTION:
      error_at (pragma_tok->location,
		"%<#pragma omp section%> may only be used in "
		"%<#pragma omp sections%> construct");
      break;

    case PRAGMA_IVDEP:
      {
	if (context == pragma_external)
	  {
	    error_at (pragma_tok->location,
		      "%<#pragma GCC ivdep%> must be inside a function");
	    break;
	  }
	const bool ivdep = cp_parser_pragma_ivdep (parser, pragma_tok);
	unsigned short unroll;
	cp_token *tok = cp_lexer_peek_token (the_parser->lexer);
	if (tok->type == CPP_PRAGMA
	    && cp_parser_pragma_kind (tok) == PRAGMA_UNROLL)
	  {
	    tok = cp_lexer_consume_token (parser->lexer);
	    unroll = cp_parser_pragma_unroll (parser, tok);
	    tok = cp_lexer_peek_token (the_parser->lexer);
	  }
	else
	  unroll = 0;
	if (tok->type != CPP_KEYWORD
	    || (tok->keyword != RID_FOR
		&& tok->keyword != RID_WHILE
		&& tok->keyword != RID_DO))
	  {
	    cp_parser_error (parser, "for, while or do statement expected");
	    return false;
	  }
	cp_parser_iteration_statement (parser, if_p, ivdep, unroll);
	return true;
      }

    case PRAGMA_UNROLL:
      {
	if (context == pragma_external)
	  {
	    error_at (pragma_tok->location,
		      "%<#pragma GCC unroll%> must be inside a function");
	    break;
	  }
	const unsigned short unroll
	  = cp_parser_pragma_unroll (parser, pragma_tok);
	bool ivdep;
	cp_token *tok = cp_lexer_peek_token (the_parser->lexer);
	if (tok->type == CPP_PRAGMA
	    && cp_parser_pragma_kind (tok) == PRAGMA_IVDEP)
	  {
	    tok = cp_lexer_consume_token (parser->lexer);
	    ivdep = cp_parser_pragma_ivdep (parser, tok);
	    tok = cp_lexer_peek_token (the_parser->lexer);
	  }
	else
	  ivdep = false;
	if (tok->type != CPP_KEYWORD
	    || (tok->keyword != RID_FOR
		&& tok->keyword != RID_WHILE
		&& tok->keyword != RID_DO))
	  {
	    cp_parser_error (parser, "for, while or do statement expected");
	    return false;
	  }
	cp_parser_iteration_statement (parser, if_p, ivdep, unroll);
	return true;
      }

    default:
      gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
      c_invoke_pragma_handler (id);
      break;

    bad_stmt:
      cp_parser_error (parser, "expected declaration specifiers");
      break;
    }

  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
  return ret;
}

/* The interface the pragma parsers have to the lexer.  */

enum cpp_ttype
pragma_lex (tree *value, location_t *loc)
{
  cp_token *tok = cp_lexer_peek_token (the_parser->lexer);
  enum cpp_ttype ret = tok->type;

  *value = tok->u.value;
  if (loc)
    *loc = tok->location;

  if (ret == CPP_PRAGMA_EOL)
    ret = CPP_EOF;
  else if (ret == CPP_STRING)
    *value = cp_parser_string_literal (the_parser, /*translate=*/false,
				       /*wide_ok=*/false);
  else
    {
      if (ret == CPP_KEYWORD)
	ret = CPP_NAME;
      cp_lexer_consume_token (the_parser->lexer);
    }

  return ret;
}


/* External interface.  */

/* Parse one entire translation unit.  */

void
c_parse_file (void)
{
  static bool already_called = false;

  if (already_called)
    fatal_error (input_location,
		 "multi-source compilation not implemented for C++");
  already_called = true;

  /* cp_lexer_new_main is called before doing any GC allocation
     because tokenization might load a PCH file.  */
  cp_lexer_new_main ();

  cp_parser_translation_unit (the_parser);
  class_decl_loc_t::diag_mismatched_tags ();

  the_parser = NULL;

  finish_translation_unit ();
}

/* Create an identifier for a generic parameter type (a synthesized
   template parameter implied by `auto' or a concept identifier). */

static GTY(()) int generic_parm_count;
static tree
make_generic_type_name ()
{
  char buf[32];
  sprintf (buf, "auto:%d", ++generic_parm_count);
  return get_identifier (buf);
}

/* Add an implicit template type parameter to the CURRENT_TEMPLATE_PARMS
   (creating a new template parameter list if necessary).  Returns the newly
   created template type parm.  */

static tree
synthesize_implicit_template_parm  (cp_parser *parser, tree constr)
{
  /* A requires-clause is not a function and cannot have placeholders.  */
  if (current_binding_level->requires_expression)
    {
      error ("placeholder type not allowed in this context");
      return error_mark_node;
    }

  gcc_assert (current_binding_level->kind == sk_function_parms);

  /* We are either continuing a function template that already contains implicit
     template parameters, creating a new fully-implicit function template, or
     extending an existing explicit function template with implicit template
     parameters.  */

  cp_binding_level *const entry_scope = current_binding_level;

  bool become_template = false;
  cp_binding_level *parent_scope = 0;

  if (parser->implicit_template_scope)
    {
      gcc_assert (parser->implicit_template_parms);

      current_binding_level = parser->implicit_template_scope;
    }
  else
    {
      /* Roll back to the existing template parameter scope (in the case of
	 extending an explicit function template) or introduce a new template
	 parameter scope ahead of the function parameter scope (or class scope
	 in the case of out-of-line member definitions).  The function scope is
	 added back after template parameter synthesis below.  */

      cp_binding_level *scope = entry_scope;

      while (scope->kind == sk_function_parms)
	{
	  parent_scope = scope;
	  scope = scope->level_chain;
	}
      if (current_class_type && !LAMBDA_TYPE_P (current_class_type))
	{
	  /* If not defining a class, then any class scope is a scope level in
	     an out-of-line member definition.  In this case simply wind back
	     beyond the first such scope to inject the template parameter list.
	     Otherwise wind back to the class being defined.  The latter can
	     occur in class member friend declarations such as:

	       class A {
		 void foo (auto);
	       };
	       class B {
		 friend void A::foo (auto);
	       };

	    The template parameter list synthesized for the friend declaration
	    must be injected in the scope of 'B'.  This can also occur in
	    erroneous cases such as:

	       struct A {
	         struct B {
		   void foo (auto);
		 };
		 void B::foo (auto) {}
	       };

	    Here the attempted definition of 'B::foo' within 'A' is ill-formed
	    but, nevertheless, the template parameter list synthesized for the
	    declarator should be injected into the scope of 'A' as if the
	    ill-formed template was specified explicitly.  */

	  while (scope->kind == sk_class && !scope->defining_class_p)
	    {
	      parent_scope = scope;
	      scope = scope->level_chain;
	    }
	}

      current_binding_level = scope;

      if (scope->kind != sk_template_parms
	  || !function_being_declared_is_template_p (parser))
	{
	  /* Introduce a new template parameter list for implicit template
	     parameters.  */

	  become_template = true;

	  parser->implicit_template_scope
	      = begin_scope (sk_template_parms, NULL);

	  ++processing_template_decl;

	  parser->fully_implicit_function_template_p = true;
	  ++parser->num_template_parameter_lists;
	}
      else
	{
	  /* Synthesize implicit template parameters at the end of the explicit
	     template parameter list.  */

	  gcc_assert (current_template_parms);

	  parser->implicit_template_scope = scope;

	  tree v = INNERMOST_TEMPLATE_PARMS (current_template_parms);
	  parser->implicit_template_parms
	    = TREE_VEC_ELT (v, TREE_VEC_LENGTH (v) - 1);
	}
    }

  /* Synthesize a new template parameter and track the current template
     parameter chain with implicit_template_parms.  */

  tree proto = constr ? DECL_INITIAL (constr) : NULL_TREE;
  tree synth_id = make_generic_type_name ();
  bool non_type = false;

  /* Synthesize the type template parameter.  */
  gcc_assert(!proto || TREE_CODE (proto) == TYPE_DECL);
  tree synth_tmpl_parm = finish_template_type_parm (class_type_node, synth_id);

  if (become_template)
    current_template_parms = tree_cons (size_int (current_template_depth + 1),
					NULL_TREE, current_template_parms);

  /* Attach the constraint to the parm before processing.  */
  tree node = build_tree_list (NULL_TREE, synth_tmpl_parm);
  TREE_TYPE (node) = constr;
  tree new_parm
    = process_template_parm (parser->implicit_template_parms,
			     input_location,
			     node,
			     /*non_type=*/non_type,
			     /*param_pack=*/false);
  // Process_template_parm returns the list of parms, and
  // parser->implicit_template_parms holds the final node of the parm
  // list.  We really want to manipulate the newly appended element.
  gcc_checking_assert (!parser->implicit_template_parms
		       || parser->implicit_template_parms == new_parm);
  if (parser->implicit_template_parms)
    new_parm = TREE_CHAIN (new_parm);
  gcc_checking_assert (!TREE_CHAIN (new_parm));

  // Record the last implicit parm node
  parser->implicit_template_parms = new_parm;

  /* Mark the synthetic declaration "virtual". This is used when
     comparing template-heads to determine if whether an abbreviated
     function template is equivalent to an explicit template.

     Note that DECL_ARTIFICIAL is used elsewhere for template
     parameters.  */
  if (TREE_VALUE (new_parm) != error_mark_node)
    DECL_VIRTUAL_P (TREE_VALUE (new_parm)) = true;

  tree new_decl = get_local_decls ();
  if (non_type)
    /* Return the TEMPLATE_PARM_INDEX, not the PARM_DECL.  */
    new_decl = DECL_INITIAL (new_decl);

  /* If creating a fully implicit function template, start the new implicit
     template parameter list with this synthesized type, otherwise grow the
     current template parameter list.  */

  if (become_template)
    {
      parent_scope->level_chain = current_binding_level;

      tree new_parms = make_tree_vec (1);
      TREE_VEC_ELT (new_parms, 0) = parser->implicit_template_parms;
      TREE_VALUE (current_template_parms) = new_parms;
    }
  else
    {
      tree& new_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms);
      int new_parm_idx = TREE_VEC_LENGTH (new_parms);
      new_parms = grow_tree_vec (new_parms, new_parm_idx + 1);
      TREE_VEC_ELT (new_parms, new_parm_idx) = parser->implicit_template_parms;
    }

  /* If the new parameter was constrained, we need to add that to the
     constraints in the template parameter list.  */
  if (tree req = TEMPLATE_PARM_CONSTRAINTS (new_parm))
    {
      tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
      reqs = combine_constraint_expressions (reqs, req);
      TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = reqs;
    }

  current_binding_level = entry_scope;

  return new_decl;
}

/* Finish the declaration of a fully implicit function template.  Such a
   template has no explicit template parameter list so has not been through the
   normal template head and tail processing.  synthesize_implicit_template_parm
   tries to do the head; this tries to do the tail.  MEMBER_DECL_OPT should be
   provided if the declaration is a class member such that its template
   declaration can be completed.  If MEMBER_DECL_OPT is provided the finished
   form is returned.  Otherwise NULL_TREE is returned. */

static tree
finish_fully_implicit_template (cp_parser *parser, tree member_decl_opt)
{
  gcc_assert (parser->fully_implicit_function_template_p);

  if (member_decl_opt && member_decl_opt != error_mark_node
      && DECL_VIRTUAL_P (member_decl_opt))
    {
      error_at (DECL_SOURCE_LOCATION (member_decl_opt),
		"implicit templates may not be %<virtual%>");
      DECL_VIRTUAL_P (member_decl_opt) = false;
    }

  if (member_decl_opt)
    member_decl_opt = finish_member_template_decl (member_decl_opt);
  end_template_decl ();

  parser->fully_implicit_function_template_p = false;
  parser->implicit_template_parms = 0;
  parser->implicit_template_scope = 0;
  --parser->num_template_parameter_lists;

  return member_decl_opt;
}

/* Like finish_fully_implicit_template, but to be used in error
   recovery, rearranging scopes so that we restore the state we had
   before synthesize_implicit_template_parm inserted the implement
   template parms scope.  */

static void
abort_fully_implicit_template (cp_parser *parser)
{
  cp_binding_level *return_to_scope = current_binding_level;

  if (parser->implicit_template_scope
      && return_to_scope != parser->implicit_template_scope)
    {
      cp_binding_level *child = return_to_scope;
      for (cp_binding_level *scope = child->level_chain;
	   scope != parser->implicit_template_scope;
	   scope = child->level_chain)
	child = scope;
      child->level_chain = parser->implicit_template_scope->level_chain;
      parser->implicit_template_scope->level_chain = return_to_scope;
      current_binding_level = parser->implicit_template_scope;
    }
  else
    return_to_scope = return_to_scope->level_chain;

  finish_fully_implicit_template (parser, NULL);

  gcc_assert (current_binding_level == return_to_scope);
}

/* Helper function for diagnostics that have complained about things
   being used with 'extern "C"' linkage.

   Attempt to issue a note showing where the 'extern "C"' linkage began.  */

void
maybe_show_extern_c_location (void)
{
  if (the_parser->innermost_linkage_specification_location != UNKNOWN_LOCATION)
    inform (the_parser->innermost_linkage_specification_location,
	    "%<extern \"C\"%> linkage started here");
}

#include "gt-cp-parser.h"
