/* -*- 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:
      /* GNU extensions.  */
    case RID_ATTRIBUTE:
    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;
	}
    }
}

/* 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_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_LITERAL_TYPE:
	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))
	      {
		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 && 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_LITERAL_TYPE:
      kind = CPTK_IS_LITERAL_TYPE;
      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);
	}
    }

  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_next_tokens_can_be_gnu_attribute_p (parser))
    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;

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

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

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

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

 restart:
  in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
  if (if_p != NULL)
    *if_p = false;
  /* There is no statement yet.  */
  statement = NULL_TREE;

  saved_token_sentinel saved_tokens (parser->lexer);
  attrs_loc = cp_lexer_peek_token (parser->lexer)->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;
    }

  if (std_attrs && (flag_openmp || flag_openmp_simd))
    std_attrs = cp_parser_handle_statement_omp_attributes (parser, std_attrs);

  /* Peek at the next token.  */
  token = cp_lexer_peek_token (parser->lexer);
  /* 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;
	  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 (std_attrs != NULL_TREE)
	    {
	      /* 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;
	  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)
    {
      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 (lexer->in_omp_attribute_pragma && !in_omp_attribute_pragma)
	{
	  gcc_assert (parser->lexer != lexer);
	  cp_lexer_destroy (lexer);
	}
      if (do_restart)
	goto restart;
      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 (std_attrs != NULL_TREE)
	    /* Attributes should be parsed as part of the declaration,
	       so let's un-parse them.  */
	    saved_tokens.rollback();

	  cp_parser_parse_tentatively (parser);
	  /* Try to parse the declaration-statement.  */
	  cp_parser_declaration_statement (parser);
	  /* If that worked, we're done.  */
	  if (cp_parser_parse_definitely (parser))
	    return;
	  /* It didn't work, restore the post-attribute position.  */
	  if (std_attrs)
	    cp_lexer_set_token_position (parser->lexer, statement_token);
	}
      /* 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)
{
  tree range_type, range_temp;

  /* Find out the type deduced by the declaration
     `auto &&__range = range_expr'.  */
  range_type = cp_build_reference_type (make_auto (), true);
  range_type = do_auto_deduction (range_type, range_expr,
				  type_uses_auto (range_type));

  /* Create the __range variable.  */
  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))
	{
	  error ("%<goto%> in %<constexpr%> function");
	  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));

  /* 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 if (token->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 %<;%>");
    }
  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);

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

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

/* 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 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->context->object_type = NULL_TREE;
	      return identifier;
	    }
	}
    }

  /* cp_parser_lookup_name clears OBJECT_TYPE.  */
  const bool scoped_p = ((parser->scope ? parser->scope
			  : parser->context->object_type) != NULL_TREE);

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

  /* If DECL is a template, then the name was a template-name.  */
  if (TREE_CODE (decl) == TEMPLATE_DECL)
    {
      if (TREE_DEPRECATED (decl)
	  && deprecated_state != DEPRECATED_SUPPRESS)
	{
	  tree d = DECL_TEMPLATE_RESULT (decl);
	  tree attr;
	  if (TREE_CODE (d) == TYPE_DECL)
	    attr = lookup_attribute ("deprecated",
				     TYPE_ATTRIBUTES (TREE_TYPE (d)));
	  else
	    attr = lookup_attribute ("deprecated",
				     DECL_ATTRIBUTES (d));
	  warn_deprecated_use (decl, attr);
	}
    }
  else
    {
      /* The standard does not explicitly indicate whether a name that
	 names a set of overloaded declarations, some of which are
	 templates, is a template-name.  However, such a name should
	 be a template-name; otherwise, there is no way to form a
	 template-id for the overloaded templates.  */
      bool found = false;

      for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (decl));
	   !found && iter; ++iter)
	if (TREE_CODE (*iter) == TEMPLATE_DECL)
	  found = true;

      if (!found
	  && (cxx_dialect > cxx17)
	  && !scoped_p
	  && cp_lexer_next_token_is (parser->lexer, CPP_LESS)
	  && tag_type == none_type)
	{
	  /* [temp.names] says "A name is also considered to refer to a template
	     if it is an unqualified-id followed by a < and name lookup finds
	     either one or more functions or finds nothing."  */

	  /* 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)
	    found = true;
	  /* Name lookup found nothing.  */
	  else if (decl == error_mark_node)
	    return identifier;
	}

      if (!found)
	{
	  /* The name does not name a template.  */
	  cp_parser_error (parser, "expected template-name");
	  return error_mark_node;
	}
    }

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

/* 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:
     using namespace :: [opt] nested-name-specifier [opt]
       namespace-name ;  */

static void
cp_parser_using_directive (cp_parser* parser)
{
  tree namespace_decl;
  tree attribs;

  /* 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 attributes.  */
  attribs = cp_parser_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");
	}
    }
}

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

  /* Gather the attributes that were provided with the
     decl-specifiers.  */
  prefix_attributes = decl_specifiers->attributes;

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

  /* 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.  */
      if (!decl_specifiers->type
	  && !decl_specifiers->any_type_specifiers_p
	  && ctor_dtor_or_conv_p <= 0
	  && cxx_dialect >= cxx17)
	{
	  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;
	    }
	}

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

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

		  /* 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
		       || current_binding_level->kind == sk_function_parms)
		{
		  /* 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;
}

/* 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 deprecated, so wait
	 and warn in grokparms if appropriate.  */
      deprecated_state = DEPRECATED_SUPPRESS;

      if (parameter)
	{
	  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
	 "(", 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_BRACE)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN))
	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;
  /* 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)) = TREE_PURPOSE (spec);

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

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

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

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

/* 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;
    }
  for (size_t n = cp_parser_skip_balanced_tokens (parser, 1) - 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);

  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));
      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.  */
	      || (cp_parser_allow_gnu_extensions_p (parser)
		  && cp_next_tokens_can_be_gnu_attribute_p (parser)))
	  /* A parameter declaration can also begin with [[attribute]].  */
	  && !cp_next_tokens_can_be_std_attribute_p (parser))
	{
	  tree type;
	  tree pushed_scope = NULL_TREE;
	  unsigned saved_num_template_parameter_lists;

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

  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 = 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 ("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 )

   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 (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 '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%> or %<shared%>");
    }

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

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;

  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_CHAIN (c) = list;

  return c;
}

/* OpenMP 4.5:
   grainsize ( 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;

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

static tree
cp_parser_omp_clause_order (cp_parser *parser, tree list, location_t location)
{
  tree c, id;
  const char *p;

  matching_parens parens;
  if (!parens.require_open (parser))
    return list;

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

static tree
cp_parser_omp_clause_allocate (cp_parser *parser, tree list)
{
  tree nlist, c, allocator = NULL_TREE;
  bool colon;

  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;
  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;
    }
  else
    {
      cp_parser_abort_tentative_parse (parser);
      allocator = NULL_TREE;
    }

  nlist = cp_parser_omp_var_list_no_open (parser, OMP_CLAUSE_ALLOCATE, list,
					  &colon);

  for (c = nlist; c != list; c = OMP_CLAUSE_CHAIN (c))
    OMP_CLAUSE_ALLOCATE_ALLOCATOR (c) = allocator;

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

      cp_lexer_consume_token (parser->lexer);
    }

  if (cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN) && 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);
  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 ) */

static tree
cp_parser_omp_clause_device (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_DEVICE,
			     "device", location);

  c = build_omp_clause (location, OMP_CLAUSE_DEVICE);
  OMP_CLAUSE_DEVICE_ID (c) = t;
  OMP_CLAUSE_CHAIN (c) = list;

  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:
     master | close | spread  */

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 ("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_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);

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

  where x and v are lvalue expressions with scalar type.  */

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

  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;

	  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 (!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, "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%>, %<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;
		}
	      cp_lexer_consume_token (parser->lexer);
	      continue;
	    }
	}
      break;
    }
  cp_parser_require_pragma_eol (parser, pragma_tok);

  if (code == ERROR_MARK)
    code = OMP_ATOMIC;
  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 */
	    case OMP_ATOMIC:
	      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_ACQ_REL
	    || memory_order == OMP_MEMORY_ORDER_RELEASE)
	  {
	    error_at (loc, "%<#pragma omp atomic read%> incompatible with "
			   "%<acq_rel%> or %<release%> clauses");
	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  }
	break;
      case NOP_EXPR: /* atomic write */
	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
	    || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
	  {
	    error_at (loc, "%<#pragma omp atomic write%> incompatible with "
			   "%<acq_rel%> or %<acquire%> clauses");
	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  }
	break;
      case OMP_ATOMIC:
	if (memory_order == OMP_MEMORY_ORDER_ACQ_REL
	    || memory_order == OMP_MEMORY_ORDER_ACQUIRE)
	  {
	    error_at (loc, "%<#pragma omp atomic update%> incompatible with "
			   "%<acq_rel%> or %<acquire%> clauses");
	    memory_order = OMP_MEMORY_ORDER_SEQ_CST;
	  }
	break;
      default:
	break;
      }

  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
	{
	  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;
	}
    default:
      break;
    }

restart:
  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;
      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;
      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;
	      break;
	    }
	}
      /* FALLTHRU */
    default:
      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 (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;
		default:
		  break;
		}
	      cp_parser_abort_tentative_parse (parser);
	      if (structured_block && code == OMP_ATOMIC_CAPTURE_OLD)
		{
		  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)
		{
		  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;
	    default:
	      cp_parser_error (parser,
			       "invalid operator for %<#pragma omp atomic%>");
	      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;
	  goto stmt_done;
	  /* FALLTHROUGH */
	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)
    {
      if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
	goto saw_error;
      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)
    {
      cp_parser_consume_semicolon_at_end_of_statement (parser);
      cp_parser_require (parser, CPP_CLOSE_BRACE, RT_CLOSE_BRACE);
    }
done:
  clauses = finish_omp_clauses (clauses, C_ORT_OMP);
  finish_omp_atomic (pragma_tok->location, code, opcode, lhs, rhs, v, lhs1,
		     rhs1, clauses, memory_order);
  if (!structured_block)
    cp_parser_consume_semicolon_at_end_of_statement (parser);
  return;

 saw_error:
  cp_parser_skip_to_end_of_block_or_statement (parser);
  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, "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 %<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);
}

/* 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 (parser, NULL);
  substmt = build2 (OMP_SCAN, void_type_node, substmt, NULL_TREE);
  add_stmt (substmt);

  cp_token *tok = cp_lexer_peek_token (parser->lexer);
  if (cp_parser_pragma_kind (tok) == PRAGMA_OMP_SCAN)
    {
      enum omp_clause_code clause = OMP_CLAUSE_ERROR;

      cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_next_token_is (parser->lexer, CPP_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 (parser, NULL);
  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 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 false;
	    }
	  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)
    {
      substmt = cp_parser_omp_structured_block (parser, NULL);
      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_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 (parser, NULL);
      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, "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);
  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 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);
  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 void
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;
    }

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

  clauses = cp_parser_omp_all_clauses (parser,
				       OMP_CANCELLATION_POINT_CLAUSE_MASK,
				       "#pragma omp cancellation point",
				       pragma_tok);
  finish_omp_cancellation_point (clauses);
}

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

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

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

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

  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);
  return add_stmt (stmt);
}

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

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

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

  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);
  return add_stmt (stmt);
}

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

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

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

/* 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);
	  cp_parser_omp_target_enter_data (parser, pragma_tok, context);
	  return false;
	}
      else if (strcmp (p, "exit") == 0)
	{
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_omp_target_exit_data (parser, pragma_tok, context);
	  return false;
	}
      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.in_omp_attribute_pragma = parser->lexer->in_omp_attribute_pragma;
      data.tokens = vNULL;
      data.clauses = NULL_TREE;
      /* 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, bool in_omp_attribute_pragma)
{
  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 (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 = c_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 (data->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);

	  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,
					     data->in_omp_attribute_pragma);
	}
      cp_parser_pop_lexer (parser);
    }

  data->fndecl_seen = true;
  return attrs;
}


/* 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
    {
      cp_parser_require_pragma_eol (parser, pragma_tok);
      scope_chain->omp_declare_target_attribute++;
      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), id;
      tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
      tree at2 = lookup_attribute ("omp declare target link",
				   DECL_ATTRIBUTES (t));
      only_device_type = false;
      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);
	  continue;
	}
      if (!at1)
	{
	  DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
	  if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
	    continue;

	  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)
	continue;
      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));
	    }
	}
    }
  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 = "";
  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 (!scope_chain->omp_declare_target_attribute)
    error_at (pragma_tok->location,
	      "%<#pragma omp end declare target%> without corresponding "
	      "%<#pragma omp declare target%>");
  else
    scope_chain->omp_declare_target_attribute--;
}

/* 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%>");
		      if (cp_lexer_nth_token_is (parser->lexer, 2,
						 CPP_CLOSE_PAREN))
			cp_lexer_consume_token (parser->lexer);
		    }
		  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 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_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_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;

  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");
	  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");
	  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");
	  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");
	  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");
	  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");
	  break;
	default:
	  goto bad_stmt;
	}
      break;

    case PRAGMA_OMP_CANCELLATION_POINT:
      cp_parser_omp_cancellation_point (parser, pragma_tok, context);
      return false;

    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");
	  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");
	  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");
	  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");
	  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");
	  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_MASTER:
    case PRAGMA_OMP_PARALLEL:
    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");
	  break;
	}
      return cp_parser_omp_requires (parser, pragma_tok);

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

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