/* -*- C++ -*- Parser.
   Copyright (C) 2000-2021 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_UNIQUE_PTR
#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"


/* The lexer.  */

/* The cp_lexer_* routines mediate between the lexer proper (in libcpp
   and c-lex.c) 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;
}

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

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 (0, &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);

  /* 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);
      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.  */
  done_lexing = 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.  */

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)
            {
              /* Warn about the C++0x 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_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_UNDERLYING_TYPE:
    case RID_CONSTEXPR:
      /* C++20 extensions.  */
    case RID_CONSTINIT:
    case RID_CONSTEVAL:
      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 ();
}

/* RAII wrapper around the above functions, with sanity checking.  Creating
   a variable saves tokens, which are committed when the variable is
   destroyed unless they are explicitly rolled back by calling the rollback
   member function.  */

struct saved_token_sentinel
{
  cp_lexer *lexer;
  unsigned len;
  bool commit;
  saved_token_sentinel(cp_lexer *lexer): lexer(lexer), commit(true)
  {
    len = lexer->saved_tokens.length ();
    cp_lexer_save_tokens (lexer);
  }
  void rollback ()
  {
    cp_lexer_rollback_tokens (lexer);
    commit = false;
  }
  ~saved_token_sentinel()
  {
    if (commit)
      cp_lexer_commit_tokens (lexer);
    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 (__builtin_expect (parser->omp_declare_simd != NULL, 0))
    {
      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, 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;

  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.  */

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,
		      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;

  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.  */
  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;
};

/* 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

static void
push_unparsed_function_queues (cp_parser *parser)
{
  cp_unparsed_functions_entry e = { NULL, make_tree_vector (), 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.  */

/* Constructors and destructors.  */

static cp_parser *cp_parser_new
  (cp_lexer *);

/* 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 cp_expr cp_parser_identifier
  (cp_parser *);
static cp_expr cp_parser_string_literal
  (cp_parser *, bool, bool, bool);
static cp_expr cp_parser_userdef_char_literal
  (cp_parser *);
static tree cp_parser_userdef_string_literal
  (tree);
static cp_expr cp_parser_userdef_numeric_literal
  (cp_parser *);

/* 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 };
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_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);
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);
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 *);


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_expr
  (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 void 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_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;
}

/* 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);
}

/* 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=*/false,
				/*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 (token->keyword != RID__EXPORT
	      && token->keyword != RID__MODULE
	      && token->keyword != RID__IMPORT)
	    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 (token->keyword != RID__EXPORT
	      && token->keyword != RID__MODULE
	      && token->keyword != RID__IMPORT)
	    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 (token->keyword != RID__EXPORT
	      && token->keyword != RID__MODULE
	      && token->keyword != RID__IMPORT)
	    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)
    {
      /* Ensure that the pragma is not parsed again.  */
      cp_lexer_purge_tokens_after (parser->lexer, 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 < sizeof (binops) / sizeof (binops[0]); 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;
}

/* Parse a sequence of adjacent string constants.  Returns 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
   invalid here.

   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.c.

   FUTURE: ObjC++ will need to handle @-strings here.  */
static cp_expr
cp_parser_string_literal (cp_parser *parser, bool translate, bool wide_ok,
			  bool lookup_udlit = true)
{
  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))
    {
      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))
	    {
	      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 = cp_parser_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);
}

/* 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 char *str = 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.  */
  SET_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.  */
  SET_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 = build_complex (build_complex_type (type),
			     fold_convert (type, integer_zero_node),
			     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
cp_parser_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_NORMAL, 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
	  && 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)
	      .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.  */
      return (cp_parser_string_literal (parser,
					parser->translate_strings_p,
					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);

	case RID_HAS_NOTHROW_ASSIGN:
	case RID_HAS_NOTHROW_CONSTRUCTOR:
	case RID_HAS_NOTHROW_COPY:
	case RID_HAS_TRIVIAL_ASSIGN:
	case RID_HAS_TRIVIAL_CONSTRUCTOR:
	case RID_HAS_TRIVIAL_COPY:
	case RID_HAS_TRIVIAL_DESTRUCTOR:
	case RID_HAS_UNIQUE_OBJ_REPRESENTATIONS:
	case RID_HAS_VIRTUAL_DESTRUCTOR:
	case RID_IS_ABSTRACT:
	case RID_IS_AGGREGATE:
	case RID_IS_BASE_OF:
	case RID_IS_CLASS:
	case RID_IS_EMPTY:
	case RID_IS_ENUM:
	case RID_IS_FINAL:
	case RID_IS_LAYOUT_COMPATIBLE:
	case RID_IS_LITERAL_TYPE:
	case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
	case RID_IS_POD:
	case RID_IS_POLYMORPHIC:
	case RID_IS_SAME_AS:
	case RID_IS_STD_LAYOUT:
	case RID_IS_TRIVIAL:
	case RID_IS_TRIVIALLY_ASSIGNABLE:
	case RID_IS_TRIVIALLY_CONSTRUCTIBLE:
	case RID_IS_TRIVIALLY_COPYABLE:
	case RID_IS_UNION:
	case RID_IS_ASSIGNABLE:
	case RID_IS_CONSTRUCTIBLE:
	case RID_IS_NOTHROW_ASSIGNABLE:
	case RID_IS_NOTHROW_CONSTRUCTIBLE:
	  return cp_parser_trait_expr (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_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);
}

/* 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);

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

      /* See if the next token is the `template' keyword.  */
      if (!template_p)
	template_p = &is_template;
      *template_p = cp_parser_optional_template_keyword (parser);
      /* Name lookup we do during the processing of the
	 unqualified-id might obliterate SCOPE.  */
      saved_scope = parser->scope;
      saved_object_scope = parser->object_scope;
      saved_qualifying_scope = parser->qualifying_scope;
      /* Process the final unqualified-id.  */
      unqualified_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 = saved_scope;
      parser->object_scope = saved_object_scope;
      parser->qualifying_scope = saved_qualifying_scope;

      return unqualified_id;
    }
  /* Otherwise, if we are in global scope, then we are looking at one
     of the other qualified-id productions.  */
  else if (global_scope_p)
    {
      cp_token *token;
      tree id;

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

      /* 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:
	  return cp_parser_identifier (parser);

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

	default:
	  cp_parser_error (parser, "expected id-expression");
	  return error_mark_node;
	}
    }
  else
    return cp_parser_unqualified_id (parser, template_keyword_p,
				     /*check_dependency_p=*/true,
				     declarator_p,
				     optional_p);
}

/* 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 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 IS_DECLARATION set to false, we will not have
	     resolved TYPENAME_TYPEs, so we must do so here.  */
	  if (is_declaration
	      && 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
	  && !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:
      {
	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_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);
	return cp_build_vec_convert (expression, type_location, type,
				     tf_warning_or_error);
      }

    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);
	return cp_build_bit_cast (type_location, type, expression,
				  tf_warning_or_error);
      }

    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;
	}
    }

  /* We should never get here.  */
  gcc_unreachable ();
  return error_mark_node;
}

/* 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)

   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;
  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 (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, decltype_p);

  /* 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)
	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 fold_expr_p = is_attribute_list != non_attr;
  tree identifier = NULL_TREE;
  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)
	  {
	    cp_token *token;

	    /* Consume the identifier.  */
	    token = cp_lexer_consume_token (parser->lexer);
	    /* Save the identifier.  */
	    identifier = token->u.value;
	  }
	else
	  {
	    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 (fold_expr_p)
	      expr = instantiate_non_dependent_expr (expr);

            /* 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);
              }

	    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;

  if (identifier)
    vec_safe_insert (expression_list, 0, identifier);

  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,
                                     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,
                                             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,
                                         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;

      /* 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_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));

      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, &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.

     ? 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 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,
					  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,
					      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)
    {
      /* Parse the binary expressions (logical-or-expression).  */
      expression = 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))
	expression = cp_parser_question_colon_clause (parser, expression);
    }
  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, false);
	  /* 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 trait expression.

   Returns a representation of the expression, the underlying type
   of the type at issue when KEYWORD is RID_UNDERLYING_TYPE.  */

static cp_expr
cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
{
  cp_trait_kind kind;
  tree type1, type2 = NULL_TREE;
  bool binary = false;
  bool variadic = false;

  switch (keyword)
    {
    case RID_HAS_NOTHROW_ASSIGN:
      kind = CPTK_HAS_NOTHROW_ASSIGN;
      break;
    case RID_HAS_NOTHROW_CONSTRUCTOR:
      kind = CPTK_HAS_NOTHROW_CONSTRUCTOR;
      break;
    case RID_HAS_NOTHROW_COPY:
      kind = CPTK_HAS_NOTHROW_COPY;
      break;
    case RID_HAS_TRIVIAL_ASSIGN:
      kind = CPTK_HAS_TRIVIAL_ASSIGN;
      break;
    case RID_HAS_TRIVIAL_CONSTRUCTOR:
      kind = CPTK_HAS_TRIVIAL_CONSTRUCTOR;
      break;
    case RID_HAS_TRIVIAL_COPY:
      kind = CPTK_HAS_TRIVIAL_COPY;
      break;
    case RID_HAS_TRIVIAL_DESTRUCTOR:
      kind = CPTK_HAS_TRIVIAL_DESTRUCTOR;
      break;
    case RID_HAS_UNIQUE_OBJ_REPRESENTATIONS:
      kind = CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS;
      break;
    case RID_HAS_VIRTUAL_DESTRUCTOR:
      kind = CPTK_HAS_VIRTUAL_DESTRUCTOR;
      break;
    case RID_IS_ABSTRACT:
      kind = CPTK_IS_ABSTRACT;
      break;
    case RID_IS_AGGREGATE:
      kind = CPTK_IS_AGGREGATE;
      break;
    case RID_IS_BASE_OF:
      kind = CPTK_IS_BASE_OF;
      binary = true;
      break;
    case RID_IS_CLASS:
      kind = CPTK_IS_CLASS;
      break;
    case RID_IS_EMPTY:
      kind = CPTK_IS_EMPTY;
      break;
    case RID_IS_ENUM:
      kind = CPTK_IS_ENUM;
      break;
    case RID_IS_FINAL:
      kind = CPTK_IS_FINAL;
      break;
    case RID_IS_LAYOUT_COMPATIBLE:
      kind = CPTK_IS_LAYOUT_COMPATIBLE;
      binary = true;
      break;
    case RID_IS_LITERAL_TYPE:
      kind = CPTK_IS_LITERAL_TYPE;
      break;
    case RID_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
      kind = CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF;
      binary = true;
      break;
    case RID_IS_POD:
      kind = CPTK_IS_POD;
      break;
    case RID_IS_POLYMORPHIC:
      kind = CPTK_IS_POLYMORPHIC;
      break;
    case RID_IS_SAME_AS:
      kind = CPTK_IS_SAME_AS;
      binary = true;
      break;
    case RID_IS_STD_LAYOUT:
      kind = CPTK_IS_STD_LAYOUT;
      break;
    case RID_IS_TRIVIAL:
      kind = CPTK_IS_TRIVIAL;
      break;
    case RID_IS_TRIVIALLY_ASSIGNABLE:
      kind = CPTK_IS_TRIVIALLY_ASSIGNABLE;
      binary = true;
      break;
    case RID_IS_TRIVIALLY_CONSTRUCTIBLE:
      kind = CPTK_IS_TRIVIALLY_CONSTRUCTIBLE;
      variadic = true;
      break;
    case RID_IS_TRIVIALLY_COPYABLE:
      kind = CPTK_IS_TRIVIALLY_COPYABLE;
      break;
    case RID_IS_UNION:
      kind = CPTK_IS_UNION;
      break;
    case RID_UNDERLYING_TYPE:
      kind = CPTK_UNDERLYING_TYPE;
      break;
    case RID_BASES:
      kind = CPTK_BASES;
      break;
    case RID_DIRECT_BASES:
      kind = CPTK_DIRECT_BASES;
      break;
    case RID_IS_ASSIGNABLE:
      kind = CPTK_IS_ASSIGNABLE;
      binary = true;
      break;
    case RID_IS_CONSTRUCTIBLE:
      kind = CPTK_IS_CONSTRUCTIBLE;
      variadic = true;
      break;
    case RID_IS_NOTHROW_ASSIGNABLE:
      kind = CPTK_IS_NOTHROW_ASSIGNABLE;
      binary = true;
      break;
    case RID_IS_NOTHROW_CONSTRUCTIBLE:
      kind = CPTK_IS_NOTHROW_CONSTRUCTIBLE;
      variadic = true;
      break;
    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_UNDERLYING_TYPE:
      return cp_expr (finish_underlying_type (type1), trait_loc);
    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:
      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);

  /* 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
	      && LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) == CPLD_COPY)
	    pedwarn (loc, 0, "explicit by-copy capture of %<this%> redundant "
		     "with by-copy capture default");
	  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_skip_to_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))
    {
      bool is_consteval = false;
      /* For C++20, before parsing the parameter list check if there is
	 a consteval specifier in the corresponding decl-specifier-seq.  */
      if (cxx_dialect >= cxx20)
	{
	  for (size_t n = cp_parser_skip_balanced_tokens (parser, 1);
	       cp_lexer_nth_token_is (parser->lexer, n, CPP_KEYWORD); n++)
	    {
	      if (cp_lexer_peek_nth_token (parser->lexer, n)->keyword
		  == RID_CONSTEVAL)
		{
		  is_consteval = true;
		  break;
		}
	    }
	}

      matching_parens parens;
      parens.consume_open (parser);

      begin_scope (sk_function_parms, /*entity=*/NULL_TREE);

      if (is_consteval)
	current_binding_level->immediate_fn_ctx_p = true;

      /* 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;
      if (lambda_specs.conflicting_specifiers_p)
	error_at (lambda_specs.locations[ds_storage_class],
		  "duplicate %<mutable%>");
    }

  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];

    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,
				       UNKNOWN_LOCATION);
    declarator->std_attributes = std_attrs;

    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;
	/* 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);

    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 clause.  */
		if (directive[1] && strcmp (directive[1], "depend") == 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)
		  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;
}

/* 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

  TM Extension:

   statement:
     atomic-statement

  IN_COMPOUND is true when the statement is nested inside a
  cp_parser_compound_statement; this matters for certain pragmas.

  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.  */

static void
cp_parser_statement (cp_parser* parser, tree in_statement_expr,
		     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;

 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);
  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 = 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);
	  in_compound = 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)
	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.commit)
		cp_lexer_commit_tokens (lexer);
	      gcc_assert (lexer->saved_tokens.length () == saved_tokens.len);
	      saved_tokens.lexer = parser->lexer;
	      saved_tokens.commit = false;
	      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);

      /* 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;
	}
    }

  /* Set the line number for the statement.  */
  if (statement && STATEMENT_CODE_P (TREE_CODE (statement)))
    SET_EXPR_LOCATION (statement, statement_location);

  /* Allow "[[fallthrough]];", 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.  */

static 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.

   identifier :
   case constant-expression :
   default :

   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;
	}
    }

  /* 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] }

   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);

  if (function_body)
    maybe_splice_retval_cleanup (compound_stmt);

  /* 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);

	  /* 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);

  /* 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);
    }
  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 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,
					    tf_warning_or_error);
	  TREE_TYPE (decl) = do_auto_deduction (TREE_TYPE (decl),
						iter_decl, auto_node,
						tf_warning_or_error,
						adc_variable_type);
	}
    }
}

/* 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_directly_p (type, expr))
	{
	  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;

  tree rtype = cp_build_reference_type (type, /*rval*/false);
  /* If we could initialize the reference directly, it wouldn't involve any
     copies.  */
  if (!ref_conv_binds_directly_p (rtype, expr))
    return;

  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, 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,
					   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, 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 a 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  */

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;

      /* Try to parse the init-statement.  */
      if (cp_parser_range_based_for_with_init_p (parser))
	{
	  tree dummy;
	  cp_parser_parse_tentatively (parser);
	  /* Parse the declaration.  */
	  cp_parser_simple_declaration (parser,
					/*function_definition_allowed_p=*/false,
					&dummy);
	  cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
	  if (!cp_parser_parse_definitely (parser))
	    /* That didn't work, try to parse it as an expression-statement.  */
	    cp_parser_expression_statement (parser, NULL_TREE);

	  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;
	    }
	}

      /* 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);
      /* 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
	/* 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_GLOBAL;
      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_interface_p () || module_partition_p ())
	error_at (token->location,
		  "private module fragment only permitted in purview"
		  " of module interface or partition");
      else
	{
	  mp_state = MP_PRIVATE_IMPORTS;
	  sorry_at (token->location, "private module fragment");
	}
    }
  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_IMPORTS
      && mp_state != MP_PRIVATE_IMPORTS
      && module_purview_p ()
      && !global_purview_p ())
    {
      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");

      /* Module-purview imports must not be from source inclusion
	 [cpp.import]/7  */
      if (attrs && module_purview_p () && !global_purview_p ()
	  && private_lookup_attribute ("__translated",
				       strlen ("__translated"), attrs))
	error_at (token->location, "post-module-declaration imports"
		  " must not be include-translated");
      else if ((mp_state == MP_PURVIEW_IMPORTS
		|| mp_state == MP_PRIVATE_IMPORTS)
	       && !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)
	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 (token1->keyword == RID__EXPORT
	   || token1->keyword == RID__IMPORT
	   || token1->keyword == RID__MODULE)
    {
      bool exporting = token1->keyword == RID__EXPORT;
      cp_token *next = exporting ? token2 : token1;
      if (exporting)
	cp_lexer_consume_token (parser->lexer);
      if (next->keyword == RID__MODULE)
	cp_parser_module_declaration (parser, MP_NOT_MODULE, exporting);
      else
	cp_parser_import_declaration (parser, MP_NOT_MODULE, 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;
}

/* 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 (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)
		pedwarn (next->location, 0, "the %<bool%> keyword is not "
			 "allowed in a C++20 concept definition");
	      else
		pedwarn (token->location, 0, "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)
            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 ("%<decl-specifier%> invalid in condition");

      if (found_decl_spec
	  && (flags & CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR)
	  && token->keyword != RID_MUTABLE
	  && token->keyword != RID_CONSTEXPR
	  && token->keyword != RID_CONSTEVAL)
	error_at (token->location, "%qD invalid in lambda",
		  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)
{
  tree linkage;

  /* 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);
  linkage = cp_parser_string_literal (parser, false, 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 (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.  */
  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 ();

  /* 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;

      /* 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:
      {
	cp_expr str;
	tree string_tree;
	int sz, len;

	if (cxx_dialect == cxx98)
	  maybe_warn_cpp0x (CPP0X_USER_DEFINED_LITERALS);

	/* Consume the string.  */
	str = cp_parser_string_literal (parser, /*translate=*/true,
				      /*wide_ok=*/true, /*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_type_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).  */

  /* 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;
	}

      /* "in a type-only context" */
      if (!found && scope
	  && 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 == error_mark_node)
	/* 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)
{
  tree fixed_args[10];
  unsigned n_args = 0;
  unsigned alloced = 10;
  tree *arg_ary = fixed_args;
  tree vec;
  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.  */
  do
    {
      tree argument;

      if (n_args)
	/* Consume the comma.  */
	cp_lexer_consume_token (parser->lexer);

      /* Parse the template-argument.  */
      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);
        }

      if (n_args == alloced)
	{
	  alloced *= 2;

	  if (arg_ary == fixed_args)
	    {
	      arg_ary = XNEWVEC (tree, alloced);
	      memcpy (arg_ary, fixed_args, sizeof (tree) * n_args);
	    }
	  else
	    arg_ary = XRESIZEVEC (tree, arg_ary, alloced);
	}
      arg_ary[n_args++] = argument;
    }
  while (cp_lexer_next_token_is (parser->lexer, CPP_COMMA));

  vec = make_tree_vec (n_args);

  while (n_args--)
    TREE_VEC_ELT (vec, n_args) = arg_ary[n_args];

  if (arg_ary != fixed_args)
    free (arg_ary);
  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))
    {
      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,
					     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;

  timevar_push (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);

  timevar_pop (TV_TEMPLATE_INST);

  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_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 %<-fconcepts-ts%>");
	}
      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;

    case RID_UNDERLYING_TYPE:
      type = cp_parser_trait_expr (parser, RID_UNDERLYING_TYPE);
      if (decl_specs)
	cp_parser_set_decl_spec_type (decl_specs, type,
				      token,
				      /*type_definition_p=*/false);

      return type;

    case RID_BASES:
    case RID_DIRECT_BASES:
      type = cp_parser_trait_expr (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.  */

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);
    }
  if (args == NULL_TREE)
    /* 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)
	{
	  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)
    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))
    {
      timevar_push (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)
	    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 ();
      timevar_pop (TV_PARSE_ENUM);
    }
  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 (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 && 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%>");
      qscope = make_pack_expansion (qscope);
    }

  /* 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 string;
  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.  */
  string = cp_parser_string_literal (parser, false, 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 `(', or an '{' in C++0x, indicates an initializer.  */
  if (token->type == CPP_EQ
      || token->type == CPP_OPEN_PAREN
      || token->type == CPP_OPEN_BRACE)
    {
      is_initialized = SD_INITIALIZED;
      initialization_kind = token->type;
      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);

	      /* Signal we are in the immediate function context.  */
	      if (flags & CP_PARSER_FLAGS_CONSTEVAL)
		current_binding_level->immediate_fn_ctx_p = true;

	      /* 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,
						     parens_loc);
		  declarator->std_attributes = attrs;
		  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
	  {
	    location_t loc = type_specifier_seq.locations[ds_type_spec];
	    if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node))
	      {
		if (!cp_parser_simulate_error (parser))
		  {
		    error_at (loc, "missing template arguments after %qT",
			      auto_node);
		    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;
    }

  /* Parse the parameter-declaration-list.  */
  parameters = cp_parser_parameter_declaration_list (parser, flags);
  /* 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;

  /* 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.

   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)
{
  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))
	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);

  /* 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 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;

  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, 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)
{
  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--)
	    {
	      cp_lexer_consume_token (parser->lexer);
	      return true;
	    }
	  break;

	default:
	  break;
	}

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

/* 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.  */

static tree
cp_parser_class_specifier_1 (cp_parser* parser)
{
  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:
        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);
      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;
}

static tree
cp_parser_class_specifier (cp_parser* parser)
{
  tree ret;
  timevar_push (TV_PARSE_STRUCT);
  ret = cp_parser_class_specifier_1 (parser);
  timevar_pop (TV_PARSE_STRUCT);
  return ret;
}

/* 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 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;

  push_deferring_access_checks (dk_no_check);

  /* 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.

	 It is OK to define an inaccessible class; for example:

	   class A { class B; };
	   class A::B {};

	 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)
    {
      tree class_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 (TREE_TYPE (type)) == TYPENAME_TYPE)
	{
	  class_type = resolve_typename_type (TREE_TYPE (type),
					      /*only_current_p=*/false);
	  if (TREE_CODE (class_type) != TYPENAME_TYPE)
	    type = TYPE_NAME (class_type);
	  else
	    {
	      cp_parser_error (parser, "could not resolve typename type");
	      type = error_mark_node;
	    }
	}

      if (maybe_process_partial_specialization (TREE_TYPE (type))
	  == error_mark_node)
	{
	  type = NULL_TREE;
	  goto done;
	}

      class_type = current_class_type;
      /* 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 (TREE_TYPE (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)
    {
      /* 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);
		  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;
		  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)
{
  cp_token *token;
  tree asm_specification;

  /* Peek at the next 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.  */
  asm_specification = cp_parser_string_literal (parser, false, 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 string_literal;
      tree expression;
      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.  */
      string_literal = cp_parser_string_literal (parser, false, false);

      /* Look for the `('.  */
      matching_parens parens;
      parens.require_open (parser);
      /* Parse the expression.  */
      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)
    {
      tree string_literal;

      /* Look for the string literal.  */
      string_literal = cp_parser_string_literal (parser, false, 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)
{
  if (cp_next_tokens_can_be_gnu_attribute_p (parser))
    return cp_parser_gnu_attributes_opt (parser);
  return cp_parser_std_attribute_spec_seq (parser);
}

/* 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);
	      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;
      /* 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 (attr_ns == gnu_identifier
	&& attribute_takes_identifier_p (attr_id))
      /* A GNU attribute that takes an identifier in parameter.  */
      attr_flag = id_attr;

    if (as == NULL)
      {
	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.  Note that
   carries_dependency ([dcl.attr.depend]) isn't implemented yet in GCC.
   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" };
  if (attributes)
    for (const auto &a : alist)
      if (is_attribute_p (a, get_attribute_name (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;
}

/* Parse a standard C++-11 attribute specifier.

   attribute-specifier:
     [ [ attribute-using-prefix [opt] attribute-list ] ]
     alignment-specifier

   attribute-using-prefix:
     using attribute-namespace :

   alignment-specifier:
     alignas ( type-id ... [opt] )
     alignas ( alignment-expression ... [opt] ).  */

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;

      cp_lexer_consume_token (parser->lexer);
      cp_lexer_consume_token (parser->lexer);

      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);

      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;
    }

  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);
}

// -------------------------------------------------------------------------- //
// 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;
  temp_override<int> ovr (processing_template_decl);
  if (!processing_template_decl)
    /* Adjust processing_template_decl so that we always obtain template
       trees here.  We don't do the usual ++processing_template_decl
       because that would skew the template parameter depth of a lambda
       within if we're already inside a template.  */
    processing_template_decl = 1;
  cp_expr expr = cp_parser_constraint_logical_or_expression (parser, lambda_p);
  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;
  temp_override<int> ovr (processing_template_decl);
  if (!processing_template_decl)
    /* As in cp_parser_requires_clause_expression.  */
    processing_template_decl = 1;
  cp_expr expr = cp_parser_binary_expression (parser, false, true,
					      PREC_NOT_OPERATOR, NULL);
  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_block, NULL_TREE);
      }

      ~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. */
    temp_override<int> ovr (processing_template_decl);
    if (!processing_template_decl)
      /* As in cp_parser_requires_clause_expression.  */
      processing_template_decl = 1;
    reqs = cp_parser_requirement_body (parser);
    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))
    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)
    {
      /* Look up the name in the scope of the OBJECT_TYPE, unless the
	 OBJECT_TYPE is not a class.  */
      if (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 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
    {
      timevar_id_t tv;
      if (DECL_DECLARED_INLINE_P (current_function_decl))
        tv = TV_PARSE_INLINE;
      else
        tv = TV_PARSE_FUNC;
      timevar_push (tv);
      fn = cp_parser_function_definition_after_declarator (parser,
							 /*inline_p=*/false);
      timevar_pop (tv);
    }

  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 (cxx_dialect >= cxx20 /* Implies flag_concept.  */
           && cp_lexer_next_token_is_keyword (parser->lexer, RID_CONCEPT)
           && !cp_lexer_nth_token_is_keyword (parser->lexer, 2, RID_BOOL))
    /* Allow 'concept bool' to be handled as per the TS.  */
    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;

  cp_token *start_token = cp_lexer_peek_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.  */
  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;

  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_skip_to_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))
	{
	  /* 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 (decl_specifiers.type);

	  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;

	  /* 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))
    {
      decl = cp_parser_init_declarator (parser,
					CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
				        &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))
    arguments = NULL_TREE;
  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");
	}
    }
  else
    cp_parser_skip_to_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)
{
  timevar_push (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.  */
  if (DECL_PENDING_INLINE_P (member_function))
    {
      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);
  timevar_pop (TV_PARSE_INMETH);
}

/* 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);
}

/* 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);
  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;

  /* 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;

  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)
    {
      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]);
    }

  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 ();
    }
  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 = 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;
    }
}

/* An error message is produced if the next token is not '>'.
   All further tokens are skipped until the desired token is
   found or '{', '}', ';' or an unbalanced ')' or ']'.  */

static void
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;

  /* Are we ready, yet?  If not, issue error message.  */
  if (cp_parser_require (parser, CPP_GREATER, RT_GREATER))
    return;

  /* 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;
	    }
          /* 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;
	    }
	  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;
	  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;

	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));
}

/* 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
			    || 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 hdeader.
	     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 (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);
		  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;
	  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 ("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.  */

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)
{
  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
	{
	  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:
	      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,
							      decl, 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:
	      while (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_SQUARE))
		{
		  tree low_bound = NULL_TREE, length = NULL_TREE;

		  parser->colon_corrects_to_scope_p = false;
		  cp_lexer_consume_token (parser->lexer);
		  if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON))
		    {
		      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;
		  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);
		      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;
		    }

		  decl = tree_cons (low_bound, 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 ) */

static tree
cp_parser_omp_clause_num_teams (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_TEAMS,
			     "num_teams", location);

  c = build_omp_clause (location, OMP_CLAUSE_NUM_TEAMS);
  OMP_CLAUSE_NUM_TEAMS_EXPR (c) = t;
  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 ) */

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;

  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);
      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)
    {
      step = NULL_TREE;
      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;
    }

  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_depend_sink (cp_parser *parser, location_t clause_loc,
				  tree list)
{
  tree vec = NULL;

  if (cp_lexer_next_token_is_not (parser->lexer, CPP_NAME))
    {
      cp_parser_error (parser, "expected identifier");
      return list;
    }

  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_DEPEND_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_DEPEND);
      OMP_CLAUSE_DEPEND_KIND (u) = OMP_CLAUSE_DEPEND_SINK;
      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;

  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 ("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)
	kind = OMP_CLAUSE_DEPEND_SINK;
      else if (strcmp ("source", p) == 0)
	kind = OMP_CLAUSE_DEPEND_SOURCE;
      else
	goto invalid_kind;
      break;
    }
  while (1);

  cp_lexer_consume_token (parser->lexer);

  if (iterators
      && (kind == OMP_CLAUSE_DEPEND_SOURCE || kind == OMP_CLAUSE_DEPEND_SINK))
    {
      poplevel (0, 1, 0);
      error_at (loc, "%<iterator%> modifier incompatible with %qs",
		kind == OMP_CLAUSE_DEPEND_SOURCE ? "source" : "sink");
      iterators = NULL_TREE;
    }

  if (kind == OMP_CLAUSE_DEPEND_SOURCE)
    {
      c = build_omp_clause (loc, OMP_CLAUSE_DEPEND);
      OMP_CLAUSE_DEPEND_KIND (c) = kind;
      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 (kind == OMP_CLAUSE_DEPEND_SINK)
    {
      nlist = cp_parser_omp_clause_depend_sink (parser, loc, list);
      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 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);

  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
	  /* OpenMP 5.1 allows optional comma in between directive-name and
	     clauses everywhere, but as we aren't done with OpenMP 5.0
	     implementation yet, let's allow it for now only in C++11
	     attributes.  */
	  || (parser->lexer->in_omp_attribute_pragma && 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_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 = "to";
	  break;
	case PRAGMA_OMP_CLAUSE_TO:
	  if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK)) != 0)
	    clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE,
					      clauses);
	  else
	    clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO, clauses);
	  c_name = "to";
	  break;
	case PRAGMA_OMP_CLAUSE_FROM:
	  clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_FROM, clauses);
	  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_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;
	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);

  /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
  if (parser->lexer->in_omp_attribute_pragma
      && 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;
  bool first = true;
  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))
    {
      /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
      if ((!first || parser->lexer->in_omp_attribute_pragma)
	  && 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);

      first = false;

      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 && !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_SOURCE;
  location_t c_loc = cp_lexer_peek_token (parser->lexer)->location;
  /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
  if (parser->lexer->in_omp_attribute_pragma
      && 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);

      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;
		}
	      if (kind == OMP_CLAUSE_DEPEND_SOURCE)
		{
		  clause = error_mark_node;
		  error_at (c2_loc, "expected %<in%>, %<out%>, %<inout%> or "
				    "%<mutexinoutset%>");
		}
	      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_SOURCE)
    {
      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;
  /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
  if (parser->lexer->in_omp_attribute_pragma
      && 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,
			    /*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,
					tf_warning_or_error);
	    }
	  else
	    lhs = build_x_binary_op (input_location, op, lhs, ERROR_MARK, rhs,
				     ERROR_MARK, 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,
						 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;

  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;
	  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);
	    }
	  do_range_for_auto_deduction (d, init);
	}
      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, 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,
				     tf_none);
      if (!error_operand_p (t))
	TREE_TYPE (orig_decl) = do_auto_deduction (TREE_TYPE (orig_decl),
						   t, auto_node);
    }

  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;
  for (unsigned i = 0; i < decomp_cnt; i++)
    {
      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;
      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,
					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 (parser->lexer->in_omp_attribute_pragma
	  && 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;
    }
  if (ordered)
    {
      for (tree *pc = &clauses; *pc; )
	if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_LINEAR)
	  {
	    error_at (OMP_CLAUSE_LOCATION (*pc),
		      "%<linear%> clause may not be specified together "
		      "with %<ordered%> clause with a parameter");
	    *pc = OMP_CLAUSE_CHAIN (*pc);
	  }
	else
	  pc = &OMP_CLAUSE_CHAIN (*pc);
    }

  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];
      tree c = omp_find_clause (cclauses[C_OMP_CLAUSE_SPLIT_FOR],
				OMP_CLAUSE_ORDERED);
      if (c && OMP_CLAUSE_ORDERED_EXPR (c))
	{
	  error_at (OMP_CLAUSE_LOCATION (c),
		    "%<ordered%> clause with parameter may not be specified "
		    "on %qs construct", p_name);
	  OMP_CLAUSE_ORDERED_EXPR (c) = NULL_TREE;
	}
    }

  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)

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;

  /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
  if (parser->lexer->in_omp_attribute_pragma
      && 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)
	{
	  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 "
			"%<depend%> clause may only be used in compound "
			"statements");
	      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_REDUCTION)	\
	| (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)

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)
{
  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;
    }

  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_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%> 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;
    }

  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_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%>, %<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;
    }

  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_IS_DEVICE_PTR))

static bool
cp_parser_omp_target (cp_parser *parser, cp_token *pragma_tok,
		      enum pragma_context context, bool *if_p)
{
  tree *pc = NULL, stmt;

  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.  */
	      tree c;
	      for (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)
		    && TREE_CODE (OMP_CLAUSE_OPERAND (c, 0)) != INTEGER_CST)
		  {
		    tree expr = OMP_CLAUSE_OPERAND (c, 0);
		    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, 0) = 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;
		  }
	    }
	  tree stmt = make_node (OMP_TARGET);
	  TREE_TYPE (stmt) = void_type_node;
	  OMP_TARGET_CLAUSES (stmt) = cclauses[C_OMP_CLAUSE_SPLIT_TARGET];
	  c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);
	  OMP_TARGET_BODY (stmt) = body;
	  OMP_TARGET_COMBINED (stmt) = 1;
	  SET_EXPR_LOCATION (stmt, pragma_tok->location);
	  add_stmt (stmt);
	  pc = &OMP_TARGET_CLAUSES (stmt);
	  goto check_clauses;
	}
      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;
    }

  stmt = make_node (OMP_TARGET);
  TREE_TYPE (stmt) = void_type_node;

  OMP_TARGET_CLAUSES (stmt)
    = cp_parser_omp_all_clauses (parser, OMP_TARGET_CLAUSE_MASK,
				 "#pragma omp target", pragma_tok, false);
  for (tree c = OMP_TARGET_CLAUSES (stmt); 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;
      }
  OMP_TARGET_CLAUSES (stmt)
    = finish_omp_clauses (OMP_TARGET_CLAUSES (stmt), C_ORT_OMP_TARGET);
  c_omp_adjust_map_clauses (OMP_TARGET_CLAUSES (stmt), true);

  pc = &OMP_TARGET_CLAUSES (stmt);
  keep_next_level (true);
  OMP_TARGET_BODY (stmt) = cp_parser_omp_structured_block (parser, if_p);

  SET_EXPR_LOCATION (stmt, pragma_tok->location);
  add_stmt (stmt);

check_clauses:
  while (*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:
	  case GOMP_MAP_FIRSTPRIVATE_POINTER:
	  case GOMP_MAP_FIRSTPRIVATE_REFERENCE:
	  case GOMP_MAP_ALWAYS_POINTER:
	  case GOMP_MAP_ATTACH_DETACH:
	    break;
	  default:
	    error_at (OMP_CLAUSE_LOCATION (*pc),
		      "%<#pragma omp target%> with map-type other "
		      "than %<to%>, %<from%>, %<tofrom%> or %<alloc%> "
		      "on %<map%> clause");
	    *pc = OMP_CLAUSE_CHAIN (*pc);
	    continue;
	  }
      pc = &OMP_CLAUSE_CHAIN (*pc);
    }
  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))
	      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, false, 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);
}

/* 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);

  /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
  if (parser->lexer->in_omp_attribute_pragma
      && 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)
	{
	  /* For now only in C++ attributes, do it always for OpenMP 5.1.
	  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);  */

	  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)
    {
      error_at (OMP_CLAUSE_LOCATION (c),
		"%qD specified both in declare target %<link%> and %<to%>"
		" 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_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)
      /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
      || (parser->lexer->in_omp_attribute_pragma
	  && 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_TO_DECLARE,
					clauses);
      clauses = finish_omp_clauses (clauses, C_ORT_OMP);
      cp_parser_require_pragma_eol (parser, pragma_tok);
    }
  else
    {
      struct omp_declare_target_attr a
	= { parser->lexer->in_omp_attribute_pragma };
      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))
	handle_omp_declare_target_clause (c, DECL_LOCAL_DECL_ALIAS (t),
					  device_type);
    }
  if (device_type && only_device_type)
    warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
		"directive with only %<device_type%> clauses ignored");
}

static void
cp_parser_omp_end_declare_target (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;
	}
    }
  else
    {
      cp_parser_error (parser, "expected %<declare%>");
      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%>");
  else
    {
      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,
		      "%<declare target%> in attribute syntax terminated "
		      "with %<end declare target%> in pragma syntax");
	  else
	    error_at (pragma_tok->location,
		      "%<declare target%> in pragma syntax terminated "
		      "with %<end declare target%> in attribute syntax");
	}
    }
}

/* 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;

  /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
  if (parser->lexer->in_omp_attribute_pragma
      && 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)
{
  bool first = true;
  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))
    {
      /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
      if ((!first || parser->lexer->in_omp_attribute_pragma)
	  && 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);

      first = 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);
	  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)
	    sorry_at (cloc, "%qs clause on %<requires%> directive not "
			    "supported yet", p);
	  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 first = true;
  bool bad = false;
  location_t loc = pragma_tok->location;

  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    {
      /* For now only in C++ attributes, do it always for OpenMP 5.1.  */
      if ((!first || parser->lexer->in_omp_attribute_pragma)
	  && 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);

      first = false;

      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, and then set
     fndecl_seen.  */

  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 (__builtin_expect (parser->oacc_routine != NULL, 0))
    {
      /* Keep going if we're in error reporting mode.  */
      if (parser->oacc_routine->error_seen
	  || fndecl == error_mark_node)
	return;

      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;
	}
      if (TREE_CODE (fndecl) != FUNCTION_DECL)
	{
	  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));
	}

      /* Don't unset parser->oacc_routine here: we may still need it to
	 diagnose wrong usage.  But, remember that we've used this "#pragma acc
	 routine".  */
      parser->oacc_routine->fndecl_seen = true;
    }
}

/* 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;
    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;
}

/* The parser.  */

static GTY (()) cp_parser *the_parser;


/* 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_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_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_END_DECLARE_TARGET:
      cp_parser_omp_end_declare_target (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, false, 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 *lexer = cp_lexer_new_main ();

  the_parser = cp_parser_new (lexer);

  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->kind == sk_block)
    {
      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 ();
  tree synth_tmpl_parm;
  bool non_type = false;

  /* Synthesize the type template parameter.  */
  gcc_assert(!proto || TREE_CODE (proto) == TYPE_DECL);
  synth_tmpl_parm = finish_template_type_parm (class_type_node, synth_id);

  /* 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);

  /* 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.  */
  DECL_VIRTUAL_P (TREE_VALUE (new_parm)) = true;

  // Chain the new parameter to the list of implicit parameters.
  if (parser->implicit_template_parms)
    parser->implicit_template_parms
      = TREE_CHAIN (parser->implicit_template_parms);
  else
    parser->implicit_template_parms = new_parm;

  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;
      current_template_parms = tree_cons (size_int (processing_template_decl),
					  new_parms, current_template_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 (tree_last (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"
