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


/* The lexer.  */

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

static cp_token eof_token =
{
  CPP_EOF, RID_MAX, 0, false, false, false, 0, { NULL }
};

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

/* 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
  (cp_lexer *, 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 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 and 'this' forbidden in "
			      "current context",
			      parser->local_variables_forbidden_p);
  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 a 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);
  if (parser->type_definition_forbidden_message)
    fprintf (file, "Error message for forbidden type definitions: %s\n",
	     parser->type_definition_forbidden_message);
  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)
{
  cp_lexer *lexer;

  c_common_no_more_pch ();

  /* Allocate the memory.  */
  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_lexer *lexer;
  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_parser_initial_pragma (&token);

  lexer = cp_lexer_alloc ();

  /* Put the first token in the buffer.  */
  lexer->buffer->quick_push (token);

  /* Get the remaining tokens from the preprocessor.  */
  while (token.type != CPP_EOF)
    {
      cp_lexer_get_preprocessor_token (lexer, &token);
      vec_safe_push (lexer->buffer, token);
    }

  lexer->last_token = lexer->buffer->address ()
                      + lexer->buffer->length ()
		      - 1;
  lexer->next_token = lexer->buffer->length ()
		      ? lexer->buffer->address ()
		      : &eof_token;

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

  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;
  lexer->next_token = first == last ? &eof_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);
  return lexer;
}

/* Frees all resources associated with LEXER.  */

static void
cp_lexer_destroy (cp_lexer *lexer)
{
  vec_free (lexer->buffer);
  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)
{
  gcc_assert (!previous_p || lexer->next_token != &eof_token);

  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)
{
  if (lexer->next_token == &eof_token)
    return lexer->last_token - 1;
  else
    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);
}

/* 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 (cp_lexer *lexer, 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,
			lexer == NULL ? 0 : C_LEX_STRING_NO_JOIN);
  token->keyword = RID_MAX;
  token->purged_p = false;
  token->error_reported = false;

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

	  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)
{
  if (token->type != CPP_EOF)
    {
      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_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++0x extensions.  */
    case RID_DECLTYPE:
    case RID_UNDERLYING_TYPE:
    case RID_CONSTEXPR:
      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;
  gcc_assert (!n || token != &eof_token);
  while (n != 0)
    {
      ++token;
      if (token == lexer->last_token)
	{
	  token = &eof_token;
	  break;
	}

      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;

  gcc_assert (token != &eof_token);
  gcc_assert (!lexer->in_pragma || token->type != CPP_PRAGMA_EOL);

  do
    {
      lexer->next_token++;
      if (lexer->next_token == lexer->last_token)
	{
	  lexer->next_token = &eof_token;
	  break;
	}

    }
  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 != &eof_token);
  tok->purged_p = true;
  tok->location = UNKNOWN_LOCATION;
  tok->u.value = NULL_TREE;
  tok->keyword = RID_MAX;

  do
    {
      tok++;
      if (tok == lexer->last_token)
	{
	  tok = &eof_token;
	  break;
	}
    }
  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;

  if (peek == &eof_token)
    peek = lexer->last_token;

  gcc_assert (tok < peek);

  for ( tok += 1; tok != peek; tok += 1)
    {
      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 simd%> not immediately followed by "
	     "function declaration or definition");
      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);
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)
{
  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;
  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 can not 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 or constexpr.  */
  CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR = 0x10,
  /* When parsing a decl-specifier-seq, allow missing typename.  */
  CP_PARSER_FLAGS_TYPENAME_OPTIONAL = 0x20
};

/* 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_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_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_classes \
  parser->unparsed_queues->last ().classes

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

/* 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);
static cp_expr cp_parser_constant_expression
  (cp_parser *, bool = false, 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 &);

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

static void cp_parser_declaration_seq_opt
  (cp_parser *);
static void cp_parser_declaration
  (cp_parser *);
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_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 tree cp_parser_alias_declaration
  (cp_parser *);
static void cp_parser_asm_definition
  (cp_parser *);
static void cp_parser_linkage_specification
  (cp_parser *);
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);
static cp_declarator *cp_parser_direct_declarator
  (cp_parser *, cp_parser_declarator_kind, cp_parser_flags, int *, 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 &, cp_cv_quals);
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 *);

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_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.exception] */

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 *);
static tree cp_parser_type_id_list
  (cp_parser *);

/* 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_requires_clause
  (cp_parser *);
static tree cp_parser_requires_clause_opt
  (cp_parser *);
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_list
  (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 *);

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 *, 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_check_class_key
  (enum tag_types, tree type);
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 *);

/* Concept-related syntactic transformations */

static tree cp_parser_maybe_concept_name       (cp_parser *, tree);
static tree cp_parser_maybe_partial_concept_id (cp_parser *, tree, tree);

// -------------------------------------------------------------------------- //
// 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.  */
	  while (1)
	    {
	      cp_lexer_consume_token (parser->lexer);
	      cp_token *next = cp_lexer_peek_token (parser->lexer);
	      if (next == NULL)
		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;
	}
    }

  gcc_rich_location richloc (input_location);

  bool added_matching_location = false;

  if (missing_token_desc != RT_NONE)
    {
      /* 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
	= cp_lexer_previous_token (parser->lexer)->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);
    }

  /* 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 (`%<', `%>')
	 in the message need to be interpreted.  */
      error (parser->type_definition_forbidden_message);
      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 (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 (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
	inform (location, "%<concept%> only available with -fconcepts");
      else if (processing_template_decl && current_class_type
	       && TYPE_BINFO (current_class_type))
	{
	  tree b;

	  for (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))
		{
		  tree field;
		  /* 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 (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);
			break;
		      }
		  if (field)
		    break;
		}
	    }
	}
    }
  /* 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;

	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;

	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;

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

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

  parser->lexer->in_pragma = false;

  do
    token = cp_lexer_consume_token (parser->lexer);
  while (token->type != CPP_PRAGMA_EOL && token->type != CPP_EOF);

  /* Ensure that the pragma is not parsed again.  */
  cp_lexer_purge_tokens_after (parser->lexer, pragma_tok);
}

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

/* 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 (void)
{
  cp_parser *parser;
  cp_lexer *lexer;
  unsigned i;

  /* cp_lexer_new_main is called before doing GC allocation because
     cp_lexer_new_main might load a PCH file.  */
  lexer = cp_lexer_new_main ();

  /* Initialize the binops_by_token so that we can get the tree
     directly from the token.  */
  for (i = 0; i < sizeof (binops) / sizeof (binops[0]); i++)
    binops_by_token[binops[i].token_type] = binops[i];

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

  /* 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,
			    "unsupported non-standard concatenation "
			    "of string literals");
		}
	    }

	  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:
	case CPP_UTF8STRING:
	  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.  */
  vec<tree, va_gc> *args = make_tree_vector ();
  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));
      release_tree_vector (args);
      return error_mark_node;
    }
  result = finish_call_expr (decl, &args, false, true, tf_warning_or_error);
  release_tree_vector (args);
  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;
  vec<tree, va_gc> *args;

  /* Look for a literal operator taking the exact type of numeric argument
     as the literal value.  */
  args = make_tree_vector ();
  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");
	}

      release_tree_vector (args);
      return result;
    }
  release_tree_vector (args);

  /* 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 = make_tree_vector ();
  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);
      release_tree_vector (args);
      return result;
    }
  release_tree_vector (args);

  /* 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 = make_tree_vector ();
  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);
      release_tree_vector (args);
      return result;
    }

  release_tree_vector (args);

  /* 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,
					  get_identifier ("complex_literals"),
					  0, false, 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 rargs;
  vec<tree, va_gc> *&args = rargs.get_ref();
  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);

  bool implicit_extern_c = false;

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

 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
   opertor, 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))
    {
      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) && TREE_NO_WARNING (expr1))
    /* 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);

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

    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
		&& !in_system_header_at (input_location))
	      pedwarn (input_location, 0, "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;
	expr.set_range (open_paren_loc, close_paren_loc);
	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)
	    {
	      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:
	  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_variable_p (decl))
	      {
		error_at (id_expression.get_location (),
			  "local variable %qD may not appear in this context",
			  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);
	decl.set_location (id_expression.get_location ());
	decl.set_range (id_expr_token->location, id_expression.get_finish ());
	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 (parser,
				  /*template_keyword_p=*/false,
				  /*check_dependency_p=*/true,
				  none_type,
				  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 (parser, template_keyword_p,
				    check_dependency_p,
				    none_type,
				    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 (parser, template_keyword_p,
				    check_dependency_p,
				    none_type,
				    declarator_p);

    case CPP_COMPL:
      {
	tree type_decl;
	tree qualifying_scope;
	tree object_scope;
	tree scope;
	bool done;

	/* 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;
	  }
	gcc_assert (!scope || TYPE_P (scope));

	/* If the name is of the form "X::~X" it's OK even if X is a
	   typedef.  */
	token = cp_lexer_peek_token (parser->lexer);
	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_nt (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 (input_location, 0,
		       "%<~auto%> only available with "
		       "-std=c++14 or -std=gnu++14");
	    cp_lexer_consume_token (parser->lexer);
	    return build_nt (BIT_NOT_EXPR, make_auto ());
	  }

	/* 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_nt (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_nt (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 (token->location,
			"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 (token->location,
		    "typedef-name %qD used as destructor declarator",
		    type_decl);

	return build_nt (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 (parser, template_keyword_p,
				      /*check_dependency_p=*/true,
				      none_type,
				      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;
    }
}

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

      /* 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);
	      error_at (token->location, "decltype evaluates to %qT, "
			"which is not a class or enumeration type",
			token->u.tree_check_value->value);
	      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);
		      error_at (token->location, "function template-id %qD "
				"in nested-name-specifier", tid);
		    }
		  else
		    {
		      /* Variable template.  */
		      tmpl = TREE_OPERAND (tid, 0);
		      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
	  && !(CLASS_TYPE_P (new_scope)
	       && ((CLASSTYPE_USE_TEMPLATE (new_scope)
		    && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (new_scope)))
		   || CLASSTYPE_IS_TEMPLATE (new_scope)))
	  && !(TREE_CODE (new_scope) == TYPENAME_TYPE
	       && (TREE_CODE (TYPENAME_TYPE_FULLNAME (new_scope))
		   == TEMPLATE_ID_EXPR)))
	permerror (input_location, TYPE_P (new_scope)
		   ? G_("%qT is not a template")
		   : G_("%qD is not a template"),
		   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->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;
	  }

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

	/* 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);
	postfix_expression.set_location (cp_cast_loc);
      }
      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_LAUNDER:
      {
	vec<tree, va_gc> *vec;
	unsigned int i;
	tree p;

	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_EACH_VEC_ELT (*vec, i, p)
	  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;

	  default:
	    gcc_unreachable ();
	  }
	break;
      }

    default:
      {
	tree type;

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

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

	    cp_parser_parse_tentatively (parser);

	    matching_parens parens;
	    parens.consume_open (parser);

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

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

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

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

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

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

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

	  idk = CP_ID_KIND_NONE;
          is_member_access = false;
	  break;

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

            is_member_access = false;

	    is_builtin_constant_p
	      = DECL_IS_BUILTIN_CONSTANT_P (postfix_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++2A, 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))
		  {
		    tree fn = get_first_fn (postfix_expression);
		    fn = STRIP_TEMPLATE (fn);

		    /* Do not do argument dependent lookup if regular
		       lookup finds a member function or a block-scope
		       function declaration.  [basic.lookup.argdep]/3  */
		    if (!DECL_FUNCTION_MEMBER_P (fn)
			&& !DECL_LOCAL_FUNCTION_P (fn))
		      {
			koenig_p = true;
			if (!any_type_dependent_arguments_p (args))
			  postfix_expression
			    = perform_koenig_lookup (postfix_expression, args,
						     complain);
		      }
		  }
	      }

	    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);
		    release_tree_vector (args);
		    break;
		  }

		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)
	      {
		location_t combined_loc = make_location (token->location,
							 start_loc,
							 close_paren_loc);
		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);
    }

  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)
    /* Tell cp_parser_lookup_name that there was an object, even though it's
       type-dependent.  */
    parser->context->object_type = unknown_type_node;

  /* 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 end_loc
	    = get_finish (cp_lexer_previous_token (parser->lexer)->location);
	  location_t combined_loc
	    = make_location (input_location, start_loc, end_loc);
	  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, 0,
		 "%<~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
     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);

	    if (TYPE_P (operand))
	      ret = cxx_sizeof_or_alignof_type (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 (operand, op, 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;
		  }
	      }

	    /* 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 finish_loc
	      = cp_lexer_previous_token (parser->lexer)->location;
	    location_t compound_loc
	      = make_location (start_loc, start_loc, finish_loc);

	    cp_expr ret_expr (ret);
	    ret_expr.set_location (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;

	    location_t finish_loc
	      = cp_lexer_peek_token (parser->lexer)->location;
	    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, finish_loc);

	    return cp_expr (finish_noexcept_expr (expr, tf_warning_or_error),
			    noexcept_loc);
	  }

	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.  */
	  location_t finish_loc
	    = get_finish (cp_lexer_peek_token (parser->lexer)->location);
	  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, finish_loc);
	  /* 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
	      && CONSTANT_CLASS_P (cast_expression)
	      && !integer_zerop (cast_expression)
	      && !TREE_OVERFLOW (cast_expression))
	    {
	      tree folded = fold_build1 (unary_operator,
					 TREE_TYPE (cast_expression),
					 cast_expression);
	      if (CONSTANT_CLASS_P (folded) && !TREE_OVERFLOW (folded))
		{
		  expression = cp_expr (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;
  /* And create the new one.  */
  const int kwd = RID_BUILTIN_HAS_ATTRIBUTE;
  char *tmp = concat ("types may not be defined in %<",
		      IDENTIFIER_POINTER (ridpointers[kwd]),
		      "%> expressions", NULL);
  parser->type_definition_forbidden_message = tmp;

  /* 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 the unary-expression production.  */
  if (!oper || oper == error_mark_node)
    oper = cp_parser_unary_expression (parser);

  /* Go back to evaluating expressions.  */
  --cp_unevaluated_operand;
  --c_inhibit_evaluation_warnings;

  /* Free the message we created.  */
  free (tmp);
  /* And restore the old one.  */
  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;

  /* 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)
	{
	  /* 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 finish_loc
    = cp_lexer_previous_token (parser->lexer)->location;
  location_t compound_loc
    = make_location (start_loc, start_loc, finish_loc);

  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.  */
      cp_token *end_tok = cp_lexer_previous_token (parser->lexer);
      location_t end_loc = get_finish (end_tok->location);
      location_t combined_loc = make_location (start_loc, start_loc, end_loc);

      /* Create a representation of the new-expression.  */
      ret = build_new (&placement, type, nelts, &initializer, global_scope_p,
		       tf_warning_or_error);
      protected_set_expr_location (ret, combined_loc);
    }

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

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

  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;

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

  return delete_sanity (expression, NULL_TREE, array_p, global_scope_p,
			tf_warning_or_error);
}

/* 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 (dst_type, orig_expr, tf_none);
  if (trial != error_mark_node)
    return "const_cast";

  /* If that fails, try static_cast.  */
  trial = build_static_cast (dst_type, orig_expr, tf_none);
  if (trial != error_mark_node)
    return "static_cast";

  /* Finally, try reinterpret_cast.  */
  trial = build_reinterpret_cast (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_printf (&pp, "%s<", cast_suggestion);
  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 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)
	c_inhibit_evaluation_warnings +=
	  cp_fully_fold (current.lhs) == truthvalue_false_node;
      else if (current.tree_type == TRUTH_ORIF_EXPR)
	c_inhibit_evaluation_warnings +=
	  cp_fully_fold (current.lhs) == truthvalue_true_node;

      /* 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 (current.tree_type == TRUTH_ANDIF_EXPR)
	c_inhibit_evaluation_warnings -=
	  cp_fully_fold (current.lhs) == truthvalue_false_node;
      else if (current.tree_type == TRUTH_ORIF_EXPR)
	c_inhibit_evaluation_warnings -=
	  cp_fully_fold (current.lhs) == truthvalue_true_node;

      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 (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
		= 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
        {
          current.lhs = build_x_binary_op (combined_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

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

   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)
{
  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;
      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 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,
			       bool 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;
  /* 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 = potential_rvalue_constant_expression (decay);
      parser->non_integral_constant_expression_p = !is_const;
      if (!is_const && !allow_non_constant_p)
	require_potential_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 (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;
    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 cp_expr (finish_trait_expr (kind, type1, type2), trait_loc);
    }
}

/* Parse a lambda expression.

   lambda-expression:
     lambda-introducer 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 >= cxx2a)
    /* C++20 allows lambdas in unevaluated context.  */;
  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++2a or -std=gnu++2a");
	  token->error_reported = true;
	}
      ok = false;
    }
  else if (parser->in_template_argument_list_p)
    {
      if (!token->error_reported)
	{
	  error_at (token->location, "lambda-expression in template-argument"
		    " only available with -std=c++2a or -std=gnu++2a");
	  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;

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

    type = finish_struct (type, /*attributes=*/NULL_TREE);

    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.  */
  cp_token *end_tok = cp_lexer_previous_token (parser->lexer);
  LAMBDA_EXPR_LOCATION (lambda_expr) = make_location (token->location,
						      token->location,
						      end_tok->location);

  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_peek_nth_token (parser->lexer, 2)->type != CPP_NAME)
    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");
    }

  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 < cxx2a
	      && 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);
	  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, 0, "%<*this%> capture only available with "
			     "-std=c++17 or -std=gnu++17");
	  cp_lexer_consume_token (parser->lexer);
	  cp_lexer_consume_token (parser->lexer);
	  add_capture (lambda_expr,
		       /*id=*/this_identifier,
		       /*initializer=*/finish_this_expr (),
		       /*by_reference_p=*/false,
		       explicit_init_p);
	  continue;
	}

      bool init_pack_expansion = false;
      if (cp_lexer_next_token_is (parser->lexer, CPP_ELLIPSIS))
	{
	  location_t loc = cp_lexer_peek_token (parser->lexer)->location;
	  if (cxx_dialect < cxx2a)
	    pedwarn (loc, 0, "pack init-capture only available with "
			     "-std=c++2a or -std=gnu++2a");
	  cp_lexer_consume_token (parser->lexer);
	  init_pack_expansion = true;
	}

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

      /* 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, 0,
		     "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))
	    {
	      cp_lexer_consume_token (parser->lexer);
	      capture_init_expr = make_pack_expansion (capture_init_expr);
	    }
	}

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

      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:
     < template-parameter-list [opt] >
     ( parameter-declaration-clause [opt] )
       attribute-specifier [opt]
       decl-specifier-seq [opt]
       exception-specification [opt]
       lambda-return-type-clause [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 attributes = NULL_TREE;
  tree exception_spec = NULL_TREE;
  tree template_param_list = NULL_TREE;
  tree tx_qual = NULL_TREE;
  tree return_type = NULL_TREE;
  cp_decl_specifier_seq lambda_specs;
  clear_decl_specs (&lambda_specs);

  /* 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, 0,
		 "lambda templates are only available with "
		 "-std=c++14 or -std=gnu++14");
      else if (cxx_dialect < cxx2a)
	pedwarn (parser->lexer->next_token->location, OPT_Wpedantic,
		 "lambda templates are only available with "
		 "-std=c++2a or -std=gnu++2a");

      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 just processed one more parameter list.  */
      ++parser->num_template_parameter_lists;
    }

  /* The parameter-declaration-clause is optional (unless
     template-parameter-list was given), but must begin with an
     opening parenthesis if present.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_PAREN))
    {
      matching_parens parens;
      parens.consume_open (parser);

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

      /* Parse parameters.  */
      param_list
	= cp_parser_parameter_declaration_clause
	    (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL);

      /* Default arguments shall not be specified in the
	 parameter-declaration-clause of a lambda-declarator.  */
      if (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_Wpedantic,
		     "default argument specified for lambda parameter");

      parens.require_close (parser);

      /* In the decl-specifier-seq of the lambda-declarator, each
	 decl-specifier shall either be mutable or constexpr.  */
      int declares_class_or_enum;
      if (cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
	cp_parser_decl_specifier_seq (parser,
				      CP_PARSER_FLAGS_ONLY_MUTABLE_OR_CONSTEXPR,
				      &lambda_specs, &declares_class_or_enum);
      if (lambda_specs.storage_class == sc_mutable)
	{
	  LAMBDA_EXPR_MUTABLE_P (lambda_expr) = 1;
	  if (lambda_specs.conflicting_specifiers_p)
	    error_at (lambda_specs.locations[ds_storage_class],
		      "duplicate %<mutable%>");
	}

      tx_qual = cp_parser_tx_qualifier_opt (parser);

      /* Parse optional exception specification.  */
      exception_spec = cp_parser_exception_specification_opt (parser);

      attributes = cp_parser_std_attribute_spec_seq (parser);

      /* Parse optional trailing return type.  */
      if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
        {
          cp_lexer_consume_token (parser->lexer);
          return_type = cp_parser_trailing_type_id (parser);
        }

      /* 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 ();
    }
  else if (template_param_list != NULL_TREE) // generate diagnostic
    cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN);

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

    p = obstack_alloc (&declarator_obstack, 0);

    declarator = make_id_declarator (NULL_TREE, call_op_identifier, sfk_none,
				     LAMBDA_EXPR_LOCATION (lambda_expr));

    quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
	     ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);
    declarator = make_call_declarator (declarator, param_list, quals,
				       VIRT_SPEC_UNSPECIFIED,
                                       REF_QUAL_NONE,
				       tx_qual,
				       exception_spec,
                                       return_type,
                                       /*requires_clause*/NULL_TREE);
    declarator->std_attributes = attributes;

    fco = grokmethod (&return_type_specs,
		      declarator,
		      NULL_TREE);
    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_LAMBDA_FUNCTION (fco) = 1;
      }
    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);
  bool 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 = false;
  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);
    matching_braces braces;

    if (braces.require_open (parser))
      {
	tree compound_stmt = begin_compound_stmt (0);

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

	while (cp_lexer_next_token_is_keyword (parser->lexer, RID_LABEL))
	  cp_parser_label_declaration (parser);
	cp_parser_statement_seq_opt (parser, NULL_TREE);
	braces.require_close (parser);

	finish_compound_stmt (compound_stmt);
      }

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

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

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

  saved_token_sentinel saved_tokens (parser->lexer);
  attrs_location = 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 (c_dialect_objc ())
    {
      if (!cp_parser_parse_definitely (parser))
	std_attrs = NULL_TREE;
    }

  /* 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);
	  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);
	  statement = cp_parser_iteration_statement (parser, if_p, false, 0);
	  break;

	case RID_BREAK:
	case RID_CONTINUE:
	case RID_RETURN:
	case RID_GOTO:
	  std_attrs = process_stmt_hotness_attribute (std_attrs);
	  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);
	  statement = cp_parser_objc_statement (parser);
	  break;

	case RID_TRY:
	  std_attrs = process_stmt_hotness_attribute (std_attrs);
	  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 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);
	  statement = cp_parser_transaction (parser, token);
	  break;
	case RID_TRANSACTION_CANCEL:
	  std_attrs = process_stmt_hotness_attribute (std_attrs);
	  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)
    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)
    {
      /* 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))
	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);

      /* 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_location,
		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);
  /* Finish the compound-statement.  */
  finish_compound_stmt (compound_stmt);
  /* Consume the `}'.  */
  braces.require_close (parser);

  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 && !in_system_header_at (tok->location))
	      pedwarn (tok->location, 0, "%<if constexpr%> only available "
		       "with -std=c++17 or -std=gnu++17");
	  }

	/* 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, 0,
		       "init-statement in selection statements only available "
		       "with -std=c++17 or -std=gnu++17");
	    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.  */
			delete chain;
			chain = NULL;
		      }
		  }
		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.  */
		    delete chain;
		    chain = NULL;
		  }
	      }

	    /* 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, then we must be looking at a declaration.
   (After "int (" we might be looking at a functional cast.)  */

static void
cp_parser_maybe_commit_to_declaration (cp_parser* parser,
				       bool any_specifiers_p)
{
  if (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))
    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;

  cp_parser_maybe_commit_to_declaration (parser,
					 type_specifiers.any_specifiers_p);

  /* 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);
      /* 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=*/NULL_TREE,
			     &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);
	}
    }
}

/* 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.  */
  cp_finish_decl (range_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 (range_decl) && DECL_DECOMPOSITION_P (range_decl))
    cp_finish_decomp (range_decl, decomp_first_name, decomp_cnt);

  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.  */
	  vec<tree, va_gc> *vec;
	  vec = make_tree_vector ();

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

	  release_tree_vector (vec);
	}

      /* 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;
  vec<tree, va_gc> *vec;

  member = finish_class_member_access_expr (range, identifier,
					    false, tf_warning_or_error);
  if (member == error_mark_node)
    return error_mark_node;

  vec = make_tree_vector ();
  res = finish_call_expr (member, &vec,
			  /*disallow_virtual=*/false,
			  /*koenig_p=*/false,
			  tf_warning_or_error);
  release_tree_vector (vec);
  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 < cxx2a)
	    {
	      pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
		       "range-based %<for%> loops with initializer only "
		       "available with -std=c++2a or -std=gnu++2a");
	      *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, 0,
		     "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 ;
     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_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.  */
	if (current_function_auto_return_pattern && 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);
    }
}

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

/* Parse an optional declaration-sequence.

   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

   GNU extension:

   declaration:
      __extension__ declaration */

static void
cp_parser_declaration (cp_parser* parser)
{
  cp_token token1;
  cp_token token2;
  int saved_pedantic;
  void *p;
  tree attributes = NULL_TREE;

  /* Check for the `__extension__' keyword.  */
  if (cp_parser_extension_opt (parser, &saved_pedantic))
    {
      /* Parse the qualified declaration.  */
      cp_parser_declaration (parser);
      /* Restore the PEDANTIC flag.  */
      pedantic = saved_pedantic;

      return;
    }

  /* Try to figure out what kind of declaration is present.  */
  token1 = *cp_lexer_peek_token (parser->lexer);

  if (token1.type != CPP_EOF)
    token2 = *cp_lexer_peek_nth_token (parser->lexer, 2);
  else
    {
      token2.type = CPP_EOF;
      token2.keyword = RID_MAX;
    }

  /* Get the high-water mark for the DECLARATOR_OBSTACK.  */
  p = obstack_alloc (&declarator_obstack, 0);

  /* 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);
  /* 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', then we have a template
     declaration.  */
  else if (token1.keyword == RID_EXPORT)
    cp_parser_template_declaration (parser, /*member_p=*/false);
  /* 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)
	   && (token1.keyword == RID_EXTERN
	       || token1.keyword == RID_STATIC
	       || token1.keyword == RID_INLINE)
	   && token2.keyword == RID_TEMPLATE)
    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 (token1.keyword == RID_INLINE
	   && token2.keyword == RID_NAMESPACE)
    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, NULL_TREE);
  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)
    {
      /* A declaration consisting of a single semicolon is
	 invalid.  Allow it unless we're being pedantic.  */
      cp_lexer_consume_token (parser->lexer);
      if (!in_system_header_at (input_location))
	pedwarn (input_location, OPT_Wpedantic, "extra %<;%>");
    }
  else
    /* Parse the declaration itself.  */
    cp_parser_declaration (parser);
}

/* 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)
{
  cp_token *token1;
  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.  */
  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);
      /* 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.any_specifiers_p);

  /* 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 %<,%> 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;
	  }
      }
    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, 0, "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_INITIALIZED,
			       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 (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 */
	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_CONCEPT:
          ds = ds_concept;
          cp_lexer_consume_token (parser->lexer);
          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);
	  /* 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)
	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, 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;

	  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;

      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++2A 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 < cxx2a)
	      pedwarn (token->location, 0,
		       "%<explicit(bool)%> only available with -std=c++2a "
		       "or -std=gnu++2a");

	    /* 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 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 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);
      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 (cxx_dialect < cxx17)
	pedwarn (input_location, OPT_Wpedantic,
		 "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);
}

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

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

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

      /* Commit to the tentative_firewall so we get syntax errors.  */
      cp_parser_commit_to_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.

   simple-type-specifier:
     decltype ( expression )
   C++14 proposal:
     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;

  push_deferring_access_checks (dk_deferred);

  tree expr = NULL_TREE;
  
  if (cxx_dialect >= cxx14
      && cp_lexer_next_token_is_keyword (parser->lexer, RID_AUTO))
    /* decltype (auto) */
    cp_lexer_consume_token (parser->lexer);
  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);

      /* 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 (!parens.require_close (parser))
    {
      cp_parser_skip_to_closing_parenthesis (parser, true, false,
					     /*consume_paren=*/true);
      pop_deferring_access_checks ();
      return error_mark_node;
    }

  if (!expr)
    {
      /* Build auto.  */
      expr = make_decltype_auto ();
      AUTO_IS_DECLTYPE (expr) = true;
    }
  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->u.tree_check_value->value = expr;
  start_token->u.tree_check_value->checks = get_deferred_access_checks ();
  start_token->keyword = RID_MAX;
  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.  */
  cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
				/*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);
      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;

  return member ? build_tree_list (member, expression_list) : error_mark_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);

  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' or `delete'.  */
	if (token->keyword == RID_NEW)
	  op = NEW_EXPR;
	else if (token->keyword == RID_DELETE)
	  op = DELETE_EXPR;
	else
	  break;

	/* Consume the `new' or `delete' 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)
	  {
	    /* 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_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_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);
	  }
	start_loc = make_location (start_loc, start_loc, get_finish (end_loc));
	return cp_expr (id, start_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 we do not support `export'.  */
      warning (0, "keyword %<export%> not implemented, and will be ignored");
    }

  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;

  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 DECL represents a constrained-parameter.  */

static inline bool
is_constrained_parameter (tree decl)
{
  return (decl
          && TREE_CODE (decl) == TYPE_DECL
          && CONSTRAINED_PARM_CONCEPT (decl)
          && DECL_P (CONSTRAINED_PARM_CONCEPT (decl)));
}

/* 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
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,
                              bool *is_parameter_pack)
{
  tree decl = parmdecl->decl_specifiers.type;
  tree id = get_unqualified_id (parmdecl->declarator);
  tree def = parmdecl->default_argument;
  tree proto = DECL_INITIAL (decl);

  /* A template parameter constrained by a variadic concept shall also
     be declared as a template parameter pack.  */
  bool is_variadic = template_parameter_pack_p (proto);
  if (is_variadic && !*is_parameter_pack)
    cp_parser_error (parser, "variadic constraint introduced without %<...%>");

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

  /* 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.
  if (is_constrained_parameter (parameter_declarator))
    return finish_constrained_parameter (parser,
                                         parameter_declarator,
                                         is_non_type,
                                         is_parameter_pack);

  // 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 r = cp_parser_requires_clause_opt (parser))
              reqs = conjoin_constraints (reqs, normalize_expression (r));
	    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);
  if (templ == error_mark_node || is_identifier)
    {
      pop_deferring_access_checks ();
      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);

  /* 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++2A 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++2a; 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 finish_loc
    = get_finish (cp_lexer_previous_token (parser->lexer)->location);
  location_t combined_loc
    = make_location (token->location, token->location, finish_loc);

  /* Check for concepts autos where they don't belong.  We could
     identify types in some cases of idnetifier 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);
    }
  /* A template-like identifier may be a partial concept id. */
  else if (flag_concepts
           && (template_id = (cp_parser_maybe_partial_concept_id
			      (parser, templ, arguments))))
    return template_id;
  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 ((DECL_FUNCTION_TEMPLATE_P (templ)
		   || TREE_CODE (templ) == OVERLOAD
		   || TREE_CODE (templ) == FUNCTION_DECL
		   || 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->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;
}

/* 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)
	warn_deprecated_use (decl, NULL_TREE);
    }
  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;

  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);
      /* Handle a constrained-type-specifier for a non-type template
	 parameter.  */
      if (tree decl = cp_parser_maybe_concept_name (parser, argument))
	argument = decl;
      else 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
    {
      /* 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;

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

	  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)
{
  bool need_lang_pop;
  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.  */
  if (current_lang_name == lang_name_c)
    {
      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);
      need_lang_pop = true;
    }
  else
    need_lang_pop = false;
  /* Let the front end know that we are beginning a specialization.  */
  if (!begin_specialization ())
    {
      end_specialization ();
      return;
    }

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

/* 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);
      /* Look for the class-specifier.  */
      type_spec = cp_parser_class_specifier (parser);
      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_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;
	}
      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");
	}
      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 >= cxx2a
			       && (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) || cxx_dialect >= cxx17)
	cp_parser_parse_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 = NULL_TREE;
		}
	    }
	}
      /* Otherwise, look for a type-name.  */
      else
	type = cp_parser_type_name (parser, (qualified_p && typename_p));

      /* 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 it didn't work out, we don't have a TYPE.  */
      if (((flags & CP_PARSER_FLAGS_OPTIONAL) || cxx_dialect >= cxx17)
	  && !cp_parser_parse_definitely (parser))
	type = NULL_TREE;
      if (!type && cxx_dialect >= cxx17)
	{
	  if (flags & CP_PARSER_FLAGS_OPTIONAL)
	    cp_parser_parse_tentatively (parser);

	  cp_parser_global_scope_opt (parser,
				      /*current_scope_valid_p=*/false);
	  cp_parser_nested_name_specifier_opt (parser,
					       /*typename_keyword_p=*/false,
					       /*check_dependency_p=*/true,
					       /*type_p=*/false,
					       /*is_declaration=*/false);
	  tree name = cp_parser_identifier (parser);
	  if (name && TREE_CODE (name) == IDENTIFIER_NODE
	      && parser->scope != error_mark_node)
	    {
	      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
		  && (DECL_CLASS_TEMPLATE_P (tmpl)
		      || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)))
		type = make_template_placeholder (tmpl);
	      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 ((flags & CP_PARSER_FLAGS_OPTIONAL)
	      && !cp_parser_parse_definitely (parser))
	    type = NULL_TREE;
	}
      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 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 if (is_constrained_parameter (type_decl))
        /* Don't do anything. */ ;
      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;
}

/*  Check if DECL and ARGS can form a constrained-type-specifier.
    If ARGS is non-null, we try to form a concept check of the
    form DECL<?, ARGS> where ? is a wildcard that matches any
    kind of template argument. If ARGS is NULL, then we try to
    form a concept check of the form DECL<?>. */

static tree
cp_parser_maybe_constrained_type_specifier (cp_parser *parser,
					    tree decl, tree args)
{
  gcc_assert (args ? TREE_CODE (args) == TREE_VEC : true);

  /* If we a constrained-type-specifier cannot be deduced. */
  if (parser->prevent_constrained_type_specifiers)
    return NULL_TREE;

  /* A constrained type specifier can only be found in an
     overload set or as a reference to a template declaration.

     FIXME: This might be masking a bug.  It's possible that
     that the deduction below is causing template specializations
     to be formed with the wildcard as an argument.  */
  if (TREE_CODE (decl) != OVERLOAD && TREE_CODE (decl) != TEMPLATE_DECL)
    return NULL_TREE;

  /* Try to build a call expression that evaluates the
     concept. This can fail if the overload set refers
     only to non-templates. */
  tree placeholder = build_nt (WILDCARD_DECL);
  tree check = build_concept_check (decl, placeholder, args);
  if (check == error_mark_node)
    return NULL_TREE;

  /* Deduce the checked constraint and the prototype parameter.

     FIXME: In certain cases, failure to deduce should be a
     diagnosable error.  */
  tree conc;
  tree proto;
  if (!deduce_constrained_parameter (check, conc, proto))
    return NULL_TREE;

  /* In template parameter scope, this results in a constrained
     parameter. Return a descriptor of that parm. */
  if (processing_template_parmlist)
    return build_constrained_parameter (conc, proto, args);

  /* In a parameter-declaration-clause, constrained-type
     specifiers result in invented template parameters.  */
  if (parser->auto_is_implicit_function_template_parm_p)
    {
      tree x = build_constrained_parameter (conc, proto, args);
      return synthesize_implicit_template_parm (parser, x);
    }
  else
    {
     /* Otherwise, we're in a context where the constrained
        type name is deduced and the constraint applies
        after deduction. */
      return make_constrained_auto (conc, args);
    }

  return NULL_TREE;
}

/* If DECL refers to a concept, return a TYPE_DECL representing
   the result of using the constrained type specifier in the
   current context.  DECL refers to a concept if

  - it is an overload set containing a function concept taking a single
    type argument, or

  - it is a variable concept taking a single type argument.  */

static tree
cp_parser_maybe_concept_name (cp_parser* parser, tree decl)
{
  if (flag_concepts
      && (TREE_CODE (decl) == OVERLOAD
	  || BASELINK_P (decl)
	  || variable_concept_p (decl)))
    return cp_parser_maybe_constrained_type_specifier (parser, decl, NULL_TREE);
  else
    return NULL_TREE;
}

/* Check if DECL and ARGS form a partial-concept-id.  If so,
   assign ID to the resulting constrained placeholder.

   Returns true if the partial-concept-id designates a placeholder
   and false otherwise. Note that *id is set to NULL_TREE in
   this case. */

static tree
cp_parser_maybe_partial_concept_id (cp_parser *parser, tree decl, tree args)
{
  return cp_parser_maybe_constrained_type_specifier (parser, decl, args);
}

/* 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 we found an overload set, then it may refer to a concept-name. */
  if (tree decl = cp_parser_maybe_concept_name (parser, type_decl))
    type_decl = 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;

  /* 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, RID_CLASS)
	  || cp_parser_is_keyword (token, RID_STRUCT))
	{
	  gcc_rich_location richloc (token->location);
	  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);
	}
      /* 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
    {
      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)
	{
	  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 && !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_scope ts;
	  bool template_p;

	  if (is_friend)
	    /* Friends have special name lookup rules.  */
	    ts = ts_within_enclosing_non_class;
	  else if (is_declaration
		   && cp_lexer_next_token_is (parser->lexer,
					      CPP_SEMICOLON))
	    /* This is a `class-key identifier ;' */
	    ts = ts_current;
	  else
	    ts = ts_global;

	  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, ts, 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 && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
	       && ! processing_explicit_instantiation)
	warning (OPT_Wattributes,
		 "attributes ignored on template instantiation");
      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)
    {
      /* Indicate whether this class was declared as a `class' or as a
	 `struct'.  */
      if (CLASS_TYPE_P (type))
	CLASSTYPE_DECLARED_CLASS (type) = (tag_type == class_type);
      cp_parser_check_class_key (tag_type, 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;
  bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p;

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

      /* 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))
	{
	  cp_parser_error (parser, "expected %<{%>");
	  if (has_underlying_type)
	    {
	      type = NULL_TREE;
	      goto out;
	    }
	}
      /* An opaque-enum-specifier must have a ';' here.  */
      if ((scoped_enum_p || underlying_type)
	  && cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
	{
	  cp_parser_error (parser, "expected %<;%> or %<{%>");
	  if (has_underlying_type)
	    {
	      type = NULL_TREE;
	      goto out;
	    }
	}
    }

  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
	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);
	}
    }
 out:
  parser->colon_corrects_to_scope_p = saved_colon_corrects_to_scope_p;
  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 && !in_system_header_at (input_location))
	    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 (cxx_dialect < cxx2a)
	    pedwarn (cp_lexer_peek_token (parser->lexer)->location,
		     OPT_Wpedantic, "nested inline namespace definitions only "
		     "available with -std=c++2a or -std=gnu++2a");
	  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 && cxx_dialect < cxx17)
        pedwarn (input_location, OPT_Wpedantic,
                 "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);
  /* 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);
}

/* 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 decl;
  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;
  else if (UNSCOPED_ENUM_P (qscope))
    qscope = CP_TYPE_CONTEXT (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
	  && !in_system_header_at (ell->location))
	pedwarn (ell->location, 0,
		 "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
    {
      if (at_class_scope_p ())
	{
	  /* Create the USING_DECL.  */
	  decl = do_class_using_decl (qscope, identifier);

	  if (decl && typename_p)
	    USING_DECL_TYPENAME_P (decl) = 1;

	  if (check_for_bare_parameter_packs (decl))
	    {
	      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
	      return false;
	    }
	  else
	    /* Add it to the list of members in this class.  */
	    finish_member_declaration (decl);
	}
      else
	{
	  decl = cp_parser_lookup_name_simple (parser,
					       identifier,
					       token->location);
	  if (decl == error_mark_node)
	    cp_parser_name_lookup_error (parser, identifier,
					 decl, NLE_NULL,
					 token->location);
	  else if (check_for_bare_parameter_packs (decl))
	    {
	      cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
	      return false;
	    }
	  else if (!at_namespace_scope_p ())
	    finish_local_using_decl (decl, qscope, identifier);
	  else
	    finish_namespace_using_decl (decl, qscope, identifier);
	}
    }

  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, 0,
		 "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;
}

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

  // Attach constraints to the alias declaration.
  if (flag_concepts && current_template_parms)
    {
      tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
      tree constr = build_constraints (reqs, NULL_TREE);
      set_constraints (decl, constr);
    }

  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);
  /* And any specified attributes.  */
  attribs = cp_parser_attributes_opt (parser);

  /* Update the symbol table.  */
  if (namespace_bindings_p ())
    finish_namespace_using_directive (namespace_decl, attribs);
  else
    finish_local_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 volatile_p = false;
  bool extended_p = false;
  bool invalid_inputs_p = false;
  bool invalid_outputs_p = false;
  bool inline_p = false;
  bool goto_p = false;
  required_token missing = RT_NONE;

  /* Look for the `asm' keyword.  */
  cp_parser_require_keyword (parser, RID_ASM, RT_ASM);

  if (parser->in_function_body
      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
    {
      error ("%<asm%> in %<constexpr%> function");
      cp_function_chain->invalid_constexpr = true;
    }

  /* See if the next token is `volatile'.  */
  if (cp_parser_allow_gnu_extensions_p (parser))
    for (bool done = false; !done ; )
      switch (cp_lexer_peek_token (parser->lexer)->keyword)
	{
	case RID_VOLATILE:
	  if (!volatile_p)
	    {
	      /* Remember that we saw the `volatile' keyword.  */
	      volatile_p = true;
	      /* Consume the token.  */
	      cp_lexer_consume_token (parser->lexer);
	    }
	  else
	    done = true;
	  break;
	case RID_INLINE:
	  if (!inline_p && parser->in_function_body)
	    {
	      /* Remember that we saw the `inline' keyword.  */
	      inline_p = true;
	      /* Consume the token.  */
	      cp_lexer_consume_token (parser->lexer);
	    }
	  else
	    done = true;
	  break;
	case RID_GOTO:
	  if (!goto_p && parser->in_function_body)
	    {
	      /* Remember that we saw the `goto' keyword.  */
	      goto_p = true;
	      /* Consume the token.  */
	      cp_lexer_consume_token (parser->lexer);
	    }
	  else
	    done = true;
	  break;
	default:
	  done = true;
	}

  /* 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)
	      && !goto_p)
            {
              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 (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;
}

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

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

      /* 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.  The former involves deferring
	     parsing of the initializer until end of class as with default
	     arguments.  So right here we only handle the latter.  */
	  if (!member_p && processing_template_decl && decl != error_mark_node)
	    start_lambda_scope (decl);
	  initializer = cp_parser_initializer (parser,
					       &is_direct_init,
					       &is_non_constant_init);
	  if (!member_p && processing_template_decl && decl != error_mark_node)
	    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 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)
{
  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 = true;
      /* 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,
					 CP_PARSER_FLAGS_NONE,
					 /*ctor_dtor_or_conv_p=*/NULL,
					 /*parenthesized_p=*/NULL,
					 /*member_p=*/false,
					 friend_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);
    }

  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, and FRIEND_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)
{
  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 `('.  */
	      matching_parens parens;
	      parens.consume_open (parser);
	      if (first)
		{
		  /* If this is going to be an abstract declarator, we're
		     in a declarator and we can't have default args.  */
		  parser->default_arg_ok_p = false;
		  parser->in_declarator_p = true;
		}

	      begin_scope (sk_function_parms, NULL_TREE);

	      /* Parse the parameter-declaration-clause.  */
	      params
		= cp_parser_parameter_declaration_clause (parser, flags);

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

		  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);
		  /* And the exception-specification.  */
		  exception_specification
		    = cp_parser_exception_specification_opt (parser);

		  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,
				  memfn ? cv_quals : -1));

		  /* Parse the virt-specifier-seq.  */
		  virt_specifiers = cp_parser_virt_specifier_seq_opt (parser);

		  /* Create the function-declarator.  */
		  declarator = make_call_declarator (declarator,
						     params,
						     cv_quals,
						     virt_specifiers,
						     ref_qual,
						     tx_qual,
						     exception_specification,
						     late_return,
						     requires_clause);
		  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;
		}

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

	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 = open_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 (!strncmp (p, "transaction_safe", len))
	{
	  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_cv_quals quals)
{
  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;

  tree save_ccp = current_class_ptr;
  tree save_ccr = current_class_ref;
  if (quals >= 0)
    {
      /* DR 1207: 'this' is in scope in the trailing return type.  */
      inject_this_parameter (current_class_type, quals);
    }

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

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

  if (quals >= 0)
    {
      current_class_ptr = save_ccp;
      current_class_ref = save_ccr;
    }

  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);
  /* Check to see if there really was a declarator.  */
  if (!cp_parser_parse_definitely (parser))
    abstract_declarator = NULL;

  if (type_specifier_seq.type
      /* The concepts TS allows 'auto' as a type-id.  */
      && (!flag_concepts || parser->in_type_id_in_expr_p)
      /* 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))
	      {
		error_at (loc, "missing template arguments after %qT",
			  auto_node);
		inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here",
			tmpl);
	      }
	    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))
	{
	  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;

  temp_override<bool> cleanup
    (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 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);

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

  /* 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;
  bool 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 = true;
  /* 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;

  /* 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=*/true,
					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))
    {
      /* Parse the initializer list.  */
      CONSTRUCTOR_ELTS (initializer)
	= cp_parser_initializer_list (parser, non_constant_p);
      /* 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++2A 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.  */

static vec<constructor_elt, va_gc> *
cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
{
  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;

  /* 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++2A syntax, '. id ='.  */
      if ((cxx_dialect >= cxx2a
	   || 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 (cxx_dialect < cxx2a)
	    pedwarn (loc, OPT_Wpedantic,
		     "C++ designated initializers only available with "
		     "-std=c++2a or -std=gnu++2a");
	  /* 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 >= cxx2a
	       && 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 < cxx2a && !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 >= cxx2a)
	    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;

      /* 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_loc (val, input_location),
			  "%<.%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;
    }

  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 scope;
  bool typename_p;
  cp_token *token;
  tree identifier = NULL_TREE;

  /* All class-names start with an identifier.  */
  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.  */
  scope = parser->scope;
  if (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.  */
  typename_p = (typename_keyword_p && scope && TYPE_P (scope)
		&& dependent_type_p (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;
}

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

  // Associate constraints with the type.
  if (flag_concepts)
    type = associate_classtype_constraints (type);

  /* Start the class.  */
  if (nested_name_specifier_p)
    {
      scope = CP_DECL_CONTEXT (TYPE_MAIN_DECL (type));
      old_scope = push_inner_scope (scope);
    }
  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;
      tree save_ccp, save_ccr;

      if (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_classes, 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);
      /* Now parse any NSDMIs.  */
      save_ccp = current_class_ptr;
      save_ccr = current_class_ref;
      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 do some post-NSDMI bookkeeping.  */
      FOR_EACH_VEC_SAFE_ELT (unparsed_classes, ix, class_type)
	after_nsdmi_defaulted_late_checks (class_type);
      vec_safe_truncate (unparsed_classes, 0);
      after_nsdmi_defaulted_late_checks (type);

      /* 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);
    }
  else
    vec_safe_push (unparsed_classes, type);

  /* 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");
	  nested_name_specifier = NULL_TREE;
	  num_templates = 0;
	}
    }
  /* 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_scope tag_scope = (parser->in_type_id_in_expr_p
			     ? ts_within_enclosing_non_class
			     : ts_current);
      type = xref_tag (class_key, id, tag_scope,
		       parser->num_template_parameter_lists);
    }

  /* 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);
  cp_parser_check_class_key (class_key, type);

  /* If this type was already complete, and we see another definition,
     that's an error.  */
  if (type != error_mark_node && COMPLETE_TYPE_P (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);
    }

  /* 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.  */
  if (cp_lexer_next_token_is (parser->lexer, CPP_COLON))
    {
      /* PR59482: enter the class scope so that base-specifiers are looked
	 up correctly.  */
      if (type)
	pushclass (type);
      bases = cp_parser_base_clause (parser);
      /* PR59482: get out of the previously pushed class scope so that the
	 subsequent pops pop the right thing.  */
      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);

 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_Wpedantic, 
		 "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);
	  return;
	}
      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
	{
	  tree type;

	  /* 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.  */
	  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);
		 }
	       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++2A 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 < cxx2a
		      && !in_system_header_at (loc)
		      && identifier != NULL_TREE)
		    pedwarn (loc, 0,
			     "default member initializers for bit-fields "
			     "only available with -std=c++2a or "
			     "-std=gnu++2a");

		  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;

	      /* Parse the declarator.  */
	      declarator
		= cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
					CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
					&ctor_dtor_or_conv_p,
					/*parenthesized_p=*/NULL,
					/*member_p=*/true,
					friend_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);
		}
	      /* 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 (TREE_CODE (decl) == FUNCTION_DECL)
		cp_parser_save_default_args (parser, 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] */

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

static tree
cp_parser_noexcept_specification_opt (cp_parser* parser,
				      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;
      cp_lexer_consume_token (parser->lexer);

      if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
	{
	  matching_parens parens;
	  parens.consume_open (parser);

	  tree save_ccp = current_class_ptr;
	  tree save_ccr = current_class_ref;

	  if (current_class_type)
	    inject_this_parameter (current_class_type, TYPE_UNQUALIFIED);

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

	      expr = cp_parser_constant_expression (parser);

	      /* Restore the saved message.  */
	      parser->type_definition_forbidden_message = saved_message;
	    }
	  else
	    {
	      expr = cp_parser_expression (parser);
	      *consumed_expr = true;
	    }

	  parens.require_close (parser);

	  current_class_ptr = save_ccp;
	  current_class_ref = save_ccr;
	}
      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.  */

static tree
cp_parser_exception_specification_opt (cp_parser* parser)
{
  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, true, NULL,
						       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 && !in_system_header_at (loc))
	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))
    error ("%<try%> in %<constexpr%> function");

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

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

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

  return build_throw (expression);
}

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

  temp_override<bool> cleanup
    (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;
      outer_parens.require_open (parser);
      matching_parens inner_parens;
      inner_parens.require_open (parser);

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

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

  temp_override<bool> cleanup
    (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_consume_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;
	}

      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);
      /* C++11 noreturn attribute is equivalent to GNU's.  */
      if (is_attribute_p ("noreturn", attr_id))
	TREE_PURPOSE (TREE_PURPOSE (attribute)) = gnu_identifier;
      /* C++14 deprecated attribute is equivalent to GNU's.  */
      else 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)
    return attribute;

  {
    vec<tree, va_gc> *vec;
    int attr_flag = normal_attr;

    if (attr_ns == gnu_identifier
	&& attribute_takes_identifier_p (attr_id))
      /* A GNU attribute that takes an identifier in parameter.  */
      attr_flag = id_attr;

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

/* Check that the attribute ATTRIBUTE appears at most once in the
   attribute-list ATTRIBUTES.  This is enforced for noreturn (7.6.3)
   and deprecated (7.6.5).  Note that carries_dependency (7.6.4)
   isn't implemented yet in GCC.  */

static void
cp_parser_check_std_attribute (tree attributes, tree attribute)
{
  if (attributes)
    {
      tree name = get_attribute_name (attribute);
      if (is_attribute_p ("noreturn", name)
	  && lookup_attribute ("noreturn", attributes))
	error ("attribute %<noreturn%> can appear at most once "
	       "in an attribute-list");
      else if (is_attribute_p ("deprecated", name)
	       && lookup_attribute ("deprecated", attributes))
	error ("attribute %<deprecated%> can appear at most once "
	       "in an attribute-list");
    }
}

/* 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)
    {
      attribute = cp_parser_std_attribute (parser, attr_ns);
      if (attribute == error_mark_node)
	break;
      if (attribute != NULL_TREE)
	{
	  cp_parser_check_std_attribute (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
		  && !in_system_header_at (input_location))
		pedwarn (input_location, 0,
			 "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;

      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;

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

// -------------------------------------------------------------------------- //
// Requires Clause

// Parse a requires clause.
//
//    requires-clause:
//      'requires' 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_requires_clause (cp_parser *parser)
{
  // Parse the requires clause so that it is not automatically folded.
  ++processing_template_decl;
  tree expr = cp_parser_binary_expression (parser, false, false,
					   PREC_NOT_OPERATOR, NULL);
  if (check_for_bare_parameter_packs (expr))
    expr = error_mark_node;
  --processing_template_decl;
  return expr;
}

// Optionally parse a requires clause:
static tree
cp_parser_requires_clause_opt (cp_parser *parser)
{
  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 -fconcepts");
	  /* Parse and discard the requires-clause.  */
	  cp_lexer_consume_token (parser->lexer);
	  cp_parser_requires_clause (parser);
	}
      return NULL_TREE;
    }
  cp_lexer_consume_token (parser->lexer);
  return cp_parser_requires_clause (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;

  /* A requires-expression shall appear only within a concept
     definition or a requires-clause.

     TODO: Implement this diagnostic correctly. */
  if (!processing_template_decl)
    {
      error_at (loc, "a requires expression cannot appear outside a template");
      cp_parser_skip_to_end_of_statement (parser);
      return error_mark_node;
    }

  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. */
    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);
  return finish_requires_expr (parms, reqs);
}

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

  if (!parens.require_close (parser))
    return error_mark_node;

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

  if (!braces.require_close (parser))
    return error_mark_node;

  return reqs;
}

/* Parse a list of requirements.

   requirement-list:
       requirement
       requirement-list ';' requirement[opt] */
static tree
cp_parser_requirement_list (cp_parser *parser)
{
  tree result = NULL_TREE;
  while (true)
    {
      tree req = cp_parser_requirement (parser);
      if (req == error_mark_node)
        return error_mark_node;

      result = tree_cons (NULL_TREE, req, result);

      /* If we see a semi-colon, consume it. */
      if (cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
	cp_lexer_consume_token (parser->lexer);

      /* Stop processing at the end of the list. */
      if (cp_lexer_next_token_is (parser->lexer, CPP_CLOSE_BRACE))
        break;
    }

  /* Reverse the order of requirements so they are analyzed in
     declaration 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)
{
  tree expr = cp_parser_expression (parser, NULL, false, false);
  if (!expr || expr == error_mark_node)
    return error_mark_node;

  if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
    return error_mark_node;

  return finish_simple_requirement (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_lexer_consume_token (parser->lexer);

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

  if (!cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
    return error_mark_node;
  if (type == error_mark_node)
    return error_mark_node;

  return finish_type_requirement (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;

  tree expr = cp_parser_expression (parser, NULL, false, false);
  if (!expr || expr == error_mark_node)
    return error_mark_node;

  if (!braces.require_close (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);
      bool saved_result_type_constraint_p = parser->in_result_type_constraint_p;
      parser->in_result_type_constraint_p = true;
      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;
    }

  return finish_compound_requirement (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)
{
  cp_lexer_consume_token (parser->lexer);
  tree req = cp_parser_requires_clause (parser);
  if (req == error_mark_node)
    return error_mark_node;
  return finish_nested_requirement (req);
}

/* Support Functions */

/* Return the appropriate prefer_type argument for lookup_name_real based on
   tag_type and template_mem_access.  */

static inline int
prefer_type_arg (tag_types tag_type, bool template_mem_access = false)
{
  /* DR 141: When looking in the current enclosing context for a template-name
     after -> or ., only consider class templates.  */
  if (template_mem_access)
    return 2;
  switch (tag_type)
    {
    case none_type:  return 0;	// No preference.
    case scope_type: return 1;	// Type or namespace.
    default:         return 2;	// 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;

      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 we have a single function from a using decl, pull it out.  */
	  if (TREE_CODE (decl) == OVERLOAD
	      && !really_overloaded_fn (decl))
	    decl = OVL_FUNCTION (decl);

	  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_arg (tag_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_real (name, prefer_type_arg (tag_type, is_template),
				 /*nonclass=*/0,
				 /*block_p=*/true, is_namespace, 0);
      if (object_type == unknown_type_node)
	/* The object is type-dependent, so we can't look anything up; we used
	   this to get the DR 141 behavior.  */
	object_type = NULL_TREE;
      parser->object_scope = object_type;
      parser->qualifying_scope = NULL_TREE;
    }
  else
    {
      decl = lookup_name_real (name, prefer_type_arg (tag_type),
			       /*nonclass=*/0,
			       /*block_p=*/true, is_namespace, 0);
      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;

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

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

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

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

static bool
cp_parser_constructor_declarator_p (cp_parser *parser, 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
      && next_token->type != CPP_TEMPLATE_ID)
    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))
	{
	  tree type;
	  tree pushed_scope = NULL_TREE;
	  unsigned saved_num_template_parameter_lists;

	  /* 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.  */
	  cp_parser_type_specifier (parser,
				    CP_PARSER_FLAGS_NONE,
				    /*decl_specs=*/NULL,
				    /*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);
  /* 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
    {
      /* There are no access checks when parsing a template, as we do not
	 know if a specialization will be a friend.  */
      push_deferring_access_checks (dk_no_check);
      cp_token *token = cp_lexer_peek_token (parser->lexer);
      decl = cp_parser_single_declaration (parser,
					   checks,
					   member_p,
                                           /*explicit_specialization_p=*/false,
					   &friend_p);
      pop_deferring_access_checks ();

      /* 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 (CLASS_TYPE_P (TREE_TYPE (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 (parm == error_mark_node
		  || 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 ("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 ("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;

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

  /* Look for opening brace for introduction.  */
  matching_braces braces;
  braces.require_open (parser);

  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.  */
  tree parms = finish_template_introduction (tmpl_decl, introduction_list);
  if (parms && parms != error_mark_node)
    {
      cp_parser_template_declaration_after_parameters (parser, parms,
						       member_p);
      return true;
    }

  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 r = cp_parser_requires_clause_opt (parser))
      reqs = conjoin_constraints (reqs, normalize_expression (r));
    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 finish_loc
	= get_finish (cp_lexer_previous_token (parser->lexer)->location);
      location_t combined_loc = make_location (start_loc, start_loc,
					       finish_loc);
      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);
    }

  cast = build_functional_cast (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;

  /* 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 finish_loc
    = get_finish (cp_lexer_previous_token (parser->lexer)->location);
  location_t combined_loc = make_location (start_loc, start_loc, finish_loc);
  cast.set_location (combined_loc);
  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 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 DEFAULT_ARG.  */

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

      /* Don't do access checking if it is a templated function.  */
      if (processing_template_decl)
	push_deferring_access_checks (dk_no_check);

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

      if (processing_template_decl)
	pop_deferring_access_checks ();

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

/* 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 = DEFARG_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 DEFAULT_ARG.  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)
{
  bool saved_local_variables_forbidden_p;
  tree parm, parmdecl;

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

  push_defarg_context (fn);

  for (parm = TYPE_ARG_TYPES (TREE_TYPE (fn)),
	 parmdecl = DECL_ARGUMENTS (fn);
       parm && parm != void_list_node;
       parm = TREE_CHAIN (parm),
	 parmdecl = DECL_CHAIN (parmdecl))
    {
      tree default_arg = TREE_PURPOSE (parm);
      tree parsed_arg;
      vec<tree, va_gc> *insts;
      tree copy;
      unsigned ix;

      if (!default_arg)
	continue;

      if (TREE_CODE (default_arg) != DEFAULT_ARG)
	/* 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 (insts = DEFARG_INSTANTIATIONS (default_arg), ix = 0;
	   vec_safe_iterate (insts, ix, &copy); ix++)
	TREE_PURPOSE (copy) = parsed_arg;
    }

  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;
  char *tmp;
  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;
  /* And create the new one.  */
  tmp = concat ("types may not be defined in %<",
		IDENTIFIER_POINTER (ridpointers[keyword]),
		"%> expressions", NULL);
  parser->type_definition_forbidden_message = tmp;

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

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

  /* If the type-id production did not work out, then we must be
     looking at the unary-expression production.  */
  if (!expr)
    expr = cp_parser_unary_expression (parser);

  /* Go back to evaluating expressions.  */
  --cp_unevaluated_operand;
  --c_inhibit_evaluation_warnings;

  /* Free the message we created.  */
  free (tmp);
  /* And restore the old one.  */
  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;

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

/* Issue an error message if the CLASS_KEY does not match the TYPE.  */

static void
cp_parser_check_class_key (enum tag_types class_key, tree type)
{
  if (type == error_mark_node)
    return;
  if ((TREE_CODE (type) == UNION_TYPE) != (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);
    }
}

/* 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);
		      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 DEFAULT_ARG to represent the unparsed default
     argument.  */
  default_argument = make_node (DEFAULT_ARG);
  DEFARG_TOKENS (default_argument)
    = cp_token_cache_new (first_token, token);
  DEFARG_INSTANTIATIONS (default_argument) = NULL;

  return default_argument;
}

/* A location to use for diagnostics about an unparsed DEFAULT_ARG.  */

location_t
defarg_location (tree default_argument)
{
  cp_token_cache *tokens = DEFARG_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;

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

  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,
                     cp_lexer_previous_token (parser->lexer)->location);

  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,
                     cp_lexer_previous_token (parser->lexer)->location);
  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,
                     cp_lexer_previous_token (parser->lexer)->location);
  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);
  /* 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)
{
  cp_token *token = cp_lexer_peek_token (parser->lexer);

  while (token->keyword != RID_AT_END && token->type != CPP_EOF)
    {
      tree meth;

      if (token->type == CPP_PLUS || token->type == CPP_MINUS)
	{
	  cp_token *ptk;
	  tree sig, attribute;
	  bool is_class_method;
	  if (token->type == CPP_PLUS)
	    is_class_method = true;
	  else
	    is_class_method = false;
	  push_deferring_access_checks (dk_deferred);
	  sig = cp_parser_objc_method_signature (parser, &attribute);
	  if (sig == error_mark_node)
	    {
	      cp_parser_skip_to_end_of_block_or_statement (parser);
	      token = cp_lexer_peek_token (parser->lexer);
	      continue;
	    }
	  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);

	  ptk = cp_lexer_peek_token (parser->lexer);
	  if (!(ptk->type == CPP_PLUS || ptk->type == CPP_MINUS 
		|| ptk->type == CPP_EOF || ptk->keyword == RID_AT_END))
	    {
	      perform_deferred_access_checks (tf_warning_or_error);
	      stop_deferring_access_checks ();
	      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);

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

	  /* 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'.  */
  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, 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);
  *attrib = cp_parser_attributes_opt (parser);
  gcc_assert (*attrib);
  if (OBJC_IS_AT_KEYWORD (cp_lexer_peek_token (parser->lexer)->keyword))
    {
      cp_lexer_commit_tokens (parser->lexer);
      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);

      /* 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)
{
  /* The following variables hold the attributes of the properties as
     parsed.  They are 'false' or 'NULL_TREE' if the attribute was not
     seen.  When we see an attribute, we set them to 'true' (if they
     are boolean properties) or to the identifier (if they have an
     argument, ie, for getter and setter).  Note that here we only
     parse the list of attributes, check the syntax and accumulate the
     attributes that we find.  objc_add_property_declaration() will
     then process the information.  */
  bool property_assign = false;
  bool property_copy = false;
  tree property_getter_ident = NULL_TREE;
  bool property_nonatomic = false;
  bool property_readonly = false;
  bool property_readwrite = false;
  bool property_retain = false;
  tree property_setter_ident = NULL_TREE;

  /* '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).  */
  tree properties;
  location_t loc;

  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;
      parens.consume_open (parser);

      while (true)
	{
	  bool syntax_error = false;
	  cp_token *token = cp_lexer_peek_token (parser->lexer);
      	  enum rid keyword;

	  if (token->type != CPP_NAME)
	    {
	      cp_parser_error (parser, "expected identifier");
	      break;
	    }
	  keyword = C_RID_CODE (token->u.value);
	  cp_lexer_consume_token (parser->lexer);
	  switch (keyword)
	    {
	    case RID_ASSIGN:    property_assign = true;    break;
	    case RID_COPY:      property_copy = true;      break;
	    case RID_NONATOMIC: property_nonatomic = true; break;
	    case RID_READONLY:  property_readonly = true;  break;
	    case RID_READWRITE: property_readwrite = true; break;
	    case RID_RETAIN:    property_retain = true;    break;

	    case RID_GETTER:
	    case RID_SETTER:
	      if (cp_lexer_next_token_is_not (parser->lexer, CPP_EQ))
		{
		  if (keyword == RID_GETTER)
		    cp_parser_error (parser,
				     "missing %<=%> (after %<getter%> attribute)");
		  else
		    cp_parser_error (parser,
				     "missing %<=%> (after %<setter%> attribute)");
		  syntax_error = true;
		  break;
		}
	      cp_lexer_consume_token (parser->lexer); /* eat the = */
	      if (!cp_parser_objc_selector_p (cp_lexer_peek_token (parser->lexer)->type))
		{
		  cp_parser_error (parser, "expected identifier");
		  syntax_error = true;
		  break;
		}
	      if (keyword == RID_SETTER)
		{
		  if (property_setter_ident != NULL_TREE)
		    {
		      cp_parser_error (parser, "the %<setter%> attribute may only be specified once");
		      cp_lexer_consume_token (parser->lexer);
		    }
		  else
		    property_setter_ident = cp_parser_objc_selector (parser);
		  if (cp_lexer_next_token_is_not (parser->lexer, CPP_COLON))
		    cp_parser_error (parser, "setter name must terminate with %<:%>");
		  else
		    cp_lexer_consume_token (parser->lexer);
		}
	      else
		{
		  if (property_getter_ident != NULL_TREE)
		    {
		      cp_parser_error (parser, "the %<getter%> attribute may only be specified once");
		      cp_lexer_consume_token (parser->lexer);
		    }
		  else
		    property_getter_ident = cp_parser_objc_selector (parser);
		}
	      break;
	    default:
	      cp_parser_error (parser, "unknown property attribute");
	      syntax_error = true;
	      break;
	    }

	  if (syntax_error)
	    break;

	  if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	    cp_lexer_consume_token (parser->lexer);
	  else
	    break;
	}

      /* FIXME: "@property (setter, assign);" will generate a spurious
	 "error: expected ‘)’ before ‘,’ token".  This is because
	 cp_parser_require, unlike the C counterpart, will produce an
	 error even if we are in error recovery.  */
      if (!parens.require_close (parser))
	{
	  cp_parser_skip_to_closing_parenthesis (parser,
						 /*recovering=*/true,
						 /*or_comma=*/false,
						 /*consume_paren=*/true);
	}
    }

  /* ... and the property declaration(s).  */
  properties = cp_parser_objc_struct_declaration (parser);

  if (properties == error_mark_node)
    {
      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);
      return;
    }

  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),
				       property_readonly, property_readwrite,
				       property_assign, property_retain,
				       property_copy, property_nonatomic,
				       property_getter_ident, property_setter_ident);
    }
  
  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 ("aligned", p))
	    result = PRAGMA_OMP_CLAUSE_ALIGNED;
	  else if (!strcmp ("async", p))
	    result = PRAGMA_OACC_CLAUSE_ASYNC;
	  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 ("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 ("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 ("nogroup", p))
	    result = PRAGMA_OMP_CLAUSE_NOGROUP;
	  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;
	  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_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)
{
  tree c;

  for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
    if (OMP_CLAUSE_CODE (c) == code)
      {
	error_at (location, "too many %qs clauses", name);
	break;
      }
}

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

static tree
cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
				tree list, bool *colon)
{
  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)
	cp_parser_parse_tentatively (parser);
      token = cp_lexer_peek_token (parser->lexer);
      if (kind != 0
	  && current_class_ptr
	  && 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
	{
	  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
		  && 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
		  && cp_parser_simulate_error (parser))
		goto depend_lvalue;
	      cp_parser_name_lookup_error (parser, name, decl, NLE_NULL,
					   token->location);
	    }
	}
      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))
		{
		  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, CPP_DOT,
							      decl, false,
							      &idk, loc);
		}
	      /* FALLTHROUGH.  */
	    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);
		  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
			      && cp_parser_simulate_error (parser))
			    goto depend_lvalue;
			  goto skip_comma;
			}
		      if (kind == OMP_CLAUSE_DEPEND)
			cp_parser_commit_to_tentative_parse (parser);
		      if (!cp_lexer_next_token_is (parser->lexer,
						   CPP_CLOSE_SQUARE))
			length = cp_parser_expression (parser);
		    }
		  /* Look for the closing `]'.  */
		  if (!cp_parser_require (parser, CPP_CLOSE_SQUARE,
					  RT_CLOSE_SQUARE))
		    {
		      if (kind == OMP_CLAUSE_DEPEND
			  && 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)
	    {
	      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)
{
  if (cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
    return cp_parser_omp_var_list_no_open (parser, kind, list, NULL);
  return list;
}

/* OpenACC 2.0:
   copy ( variable-list )
   copyin ( variable-list )
   copyout ( variable-list )
   create ( variable-list )
   delete ( variable-list )
   present ( 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_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_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_PRESENT:
      kind = GOMP_MAP_FORCE_PRESENT;
      break;
    default:
      gcc_unreachable ();
    }
  tree nl, c;
  nl = cp_parser_omp_var_list (parser, OMP_CLAUSE_MAP, list);

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

 /* 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, 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;
  location_t loc = cp_lexer_peek_token (lexer)->location;

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

  list = cp_parser_oacc_wait_list (parser, location, list);

  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 = "enter data"; break;
	      case OMP_TARGET_EXIT_DATA: p = "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
      || !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 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;
	      sorry ("%<inscan%> modifier on %<reduction%> clause "
		     "not supported yet");
	    }
	  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);

  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;
      cp_lexer_consume_token (parser->lexer);
      if (nmodifiers++ == 0
	  && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);
      else
	{
	  cp_parser_require (parser, CPP_COLON, RT_COLON);
	  break;
	}
    }

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

static tree
cp_parser_omp_clause_map (cp_parser *parser, tree list)
{
  tree nlist, c;
  enum gomp_map_kind kind = GOMP_MAP_TOFROM;
  bool always = false;

  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 ("always", p) == 0)
	{
	  int nth = 2;
	  if (cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_COMMA)
	    nth++;
	  if ((cp_lexer_peek_nth_token (parser->lexer, nth)->type == CPP_NAME
	       || (cp_lexer_peek_nth_token (parser->lexer, nth)->keyword
		   == RID_DELETE))
	      && (cp_lexer_peek_nth_token (parser->lexer, nth + 1)->type
		  == CPP_COLON))
	    {
	      always = true;
	      cp_lexer_consume_token (parser->lexer);
	      if (nth == 3)
		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 ? GOMP_MAP_ALWAYS_TO : GOMP_MAP_TO;
      else if (strcmp ("from", p) == 0)
	kind = always ? GOMP_MAP_ALWAYS_FROM : GOMP_MAP_FROM;
      else if (strcmp ("tofrom", p) == 0)
	kind = always ? 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);
  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;
}

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

  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 (parser, OMP_CLAUSE_AUTO,
						 clauses, here);
	  c_name = "auto";
	  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_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 (parser, OMP_CLAUSE_FINALIZE,
						  clauses, here);
	  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, 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 (parser,
						  OMP_CLAUSE_IF_PRESENT,
						  clauses, here);
	  c_name = "if_present";
	  break;
	case PRAGMA_OACC_CLAUSE_INDEPENDENT:
	  clauses = cp_parser_oacc_simple_clause (parser,
						  OMP_CLAUSE_INDEPENDENT,
						  clauses, here);
	  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_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 (parser, OMP_CLAUSE_SEQ,
						 clauses, here);
	  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, 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, 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; the result
   of clause default goes in *pdefault.  */

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)
{
  tree clauses = NULL;
  bool first = true;
  cp_token *token = NULL;

  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 (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	cp_lexer_consume_token (parser->lexer);

      token = cp_lexer_peek_token (parser->lexer);
      c_kind = cp_parser_omp_clause_name (parser);

      switch (c_kind)
	{
	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_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_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_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_DEPEND:
	  clauses = cp_parser_omp_clause_depend (parser, clauses,
						 token->location);
	  c_name = "depend";
	  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_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:
  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 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)
{
  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))
    {
      if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	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 (!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)
		{
		  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 (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);
    }
  else
    cp_parser_require_pragma_eol (parser, 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;
  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))
	{
	  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;
  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_loc (cond, input_location),
			    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,
			     vec<tree, va_gc> *&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);
      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);
}

/* 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;
  vec<tree, va_gc> *for_block = make_tree_vector ();
  auto_vec<tree, 4> orig_inits;
  bool tiling = 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));
      }

  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;

      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)
	{
	  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)
		c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
	      else if (collapse == 1)
		c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
	      else
		c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
	      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);
	  if (!EXPR_HAS_LOCATION (incr))
	    protected_set_expr_location (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);
	  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 ();
  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);
    }
  release_tree_vector (for_block);

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

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

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

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;
	  return c_finish_omp_master (loc, body);
	}
    }
  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;

  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, "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_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_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 (cclauses == NULL && 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, "master") == 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);
	  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);
	  OMP_PARALLEL_COMBINED (stmt) = 1;
	  if (ret == NULL_TREE)
	    return ret;
	  return stmt;
	}
      else if (!flag_openmp)  /* flag_openmp_simd  */
	{
	  cp_parser_skip_to_pragma_eol (parser, pragma_tok);
	  return NULL_TREE;
	}
      else if (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_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_IN_REDUCTION))

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

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);
  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:
	    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)
	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%> or %<use_device_ptr%> 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);
  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:
	    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);
  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:
	    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_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];
	  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);
  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:
	    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)
{
  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_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_IF)			\
	| (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) )

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;

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

#define OACC_KERNELS_CLAUSE_MASK					\
	( (OMP_CLAUSE_MASK_1 << PRAGMA_OACC_CLAUSE_ASYNC)		\
	| (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_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_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_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) )

static tree
cp_parser_oacc_kernels_parallel (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;
    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;
	  cp_parser_oacc_loop (parser, pragma_tok, p_name, mask, &clauses,
			       if_p);
	  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 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.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;
    }

  /* Store away all pragma tokens.  */
  while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
	 && cp_lexer_next_token_is_not (parser->lexer, CPP_EOF))
    cp_lexer_consume_token (parser->lexer);
  if (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
    parser->omp_declare_simd->error_seen = true;
  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);
	  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 simd%> not immediately followed by "
		  "function declaration or definition");
      data.tokens.release ();
      parser->omp_declare_simd = NULL;
    }
}

/* 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 simd%> not immediately followed by "
	     "a single function declaration or definition");
      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);
      cp_lexer_consume_token (parser->lexer);
      cl = cp_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
				      "#pragma omp declare simd", pragma_tok);
      cp_parser_pop_lexer (parser);
      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;
    }

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

static void
cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
  tree clauses = NULL_TREE;
  if (cp_lexer_next_token_is (parser->lexer, 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;
    }
  if (scope_chain->omp_declare_target_attribute)
    error_at (pragma_tok->location,
	      "%<#pragma omp declare target%> with clauses in between "
	      "%<#pragma omp declare target%> without clauses and "
	      "%<#pragma omp end declare target%>");
  for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
    {
      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));
      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);
		}
	    }
	}
    }
}

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);
  add_stmt (block);

  if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN))
    return false;

  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);
	  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);
      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 (TREE_CODE (type) == FUNCTION_TYPE
	       || TREE_CODE (type) == METHOD_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));
      if (processing_template_decl)
	fndecl = push_template_decl (fndecl);
      bool block_scope = false;
      tree block = NULL_TREE;
      if (current_function_decl)
	{
	  block_scope = true;
	  DECL_CONTEXT (fndecl) = global_namespace;
	  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_next_token_is_not (parser->lexer, CPP_EOF))
		cp_lexer_consume_token (parser->lexer);
	      if (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
		goto fail;
	      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;
	  pushdecl (fndecl);
	}
      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;
	}
      if (!cp_parser_omp_declare_reduction_exprs (fndecl, parser))
	{
	  if (!block_scope)
	    finish_function (/*inline_p=*/false);
	  else
	    DECL_CONTEXT (fndecl) = current_function_decl;
	  if (cp)
	    cp_parser_pop_lexer (parser);
	  goto fail;
	}
      if (cp)
	cp_parser_pop_lexer (parser);
      if (!block_scope)
	finish_function (/*inline_p=*/false);
      else
	{
	  DECL_CONTEXT (fndecl) = current_function_decl;
	  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  */

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);
	  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%> or %<reduction%> "
			   "or %<target%>");
  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))
    {
      if (!first && cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
	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_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))


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

      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_next_token_is_not (parser->lexer, CPP_EOF))
	cp_lexer_consume_token (parser->lexer);
      if (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
	parser->oacc_routine->error_seen = true;
      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);
      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);
  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;
	}

      if (oacc_get_fn_attrib (fndecl))
	{
	  error_at (parser->oacc_routine->loc,
		    "%<#pragma acc routine%> already applied to %qD", fndecl);
	  parser->oacc_routine = NULL;
	  return;
	}

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

      /* Process the routine's dimension clauses.  */
      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"),
		     NULL_TREE, 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);
      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:
      strcpy (p_name, "#pragma acc");
      stmt = cp_parser_oacc_kernels_parallel (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_ATOMIC:
      cp_parser_omp_atomic (parser, pragma_tok);
      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_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, true, NULL, 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, false, &noex_expr,
					       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)
{
  tree name = NULL;

  cp_lexer_get_preprocessor_token (NULL, first_token);
  if (cp_parser_pragma_kind (first_token) != PRAGMA_GCC_PCH_PREPROCESS)
    return;

  cp_lexer_get_preprocessor_token (NULL, first_token);
  if (first_token->type == CPP_STRING)
    {
      name = first_token->u.value;

      cp_lexer_get_preprocessor_token (NULL, first_token);
      if (first_token->type != CPP_PRAGMA_EOL)
	error_at (first_token->location,
		  "junk at end of %<#pragma GCC pch_preprocess%>");
    }
  else
    error_at (first_token->location, "expected string literal");

  /* Skip to the end of the pragma.  */
  while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF)
    cp_lexer_get_preprocessor_token (NULL, first_token);

  /* 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 (NULL, 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_OACC_ATOMIC:
    case PRAGMA_OACC_CACHE:
    case PRAGMA_OACC_DATA:
    case PRAGMA_OACC_HOST_DATA:
    case PRAGMA_OACC_KERNELS:
    case PRAGMA_OACC_PARALLEL:
    case PRAGMA_OACC_LOOP:
    case PRAGMA_OMP_ATOMIC:
    case PRAGMA_OMP_CRITICAL:
    case PRAGMA_OMP_DISTRIBUTE:
    case PRAGMA_OMP_FOR:
    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:
      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_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)
    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,
		 "inter-module optimizations not implemented for C++");
  already_called = true;

  the_parser = cp_parser_new ();
  push_deferring_access_checks (flag_access_control
				? dk_no_deferred : dk_no_check);
  cp_parser_translation_unit (the_parser);
  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)
{
  gcc_assert (current_binding_level->kind == sk_function_parms);

   /* Before committing to modifying any scope, if we're in an
      implicit template scope, and we're trying to synthesize a
      constrained parameter, try to find a previous parameter with
      the same name.  This is the same-type rule for abbreviated
      function templates.

      NOTE: We can generate implicit parameters when tentatively
      parsing a nested name specifier, only to reject that parse
      later. However, matching the same template-id as part of a
      direct-declarator should generate an identical template
      parameter, so this rule will merge them. */
  if (parser->implicit_template_scope && constr)
    {
      tree t = parser->implicit_template_parms;
      while (t)
        {
          if (equivalent_placeholder_constraints (TREE_TYPE (t), constr))
	    {
	      tree d = TREE_VALUE (t);
	      if (TREE_CODE (d) == PARM_DECL)
		/* Return the TEMPLATE_PARM_INDEX.  */
		d = DECL_INITIAL (d);
	      return d;
	    }
          t = TREE_CHAIN (t);
        }
    }

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

  if (proto == NULL_TREE || TREE_CODE (proto) == TYPE_DECL)
    synth_tmpl_parm
      = finish_template_type_parm (class_type_node, synth_id);
  else if (TREE_CODE (proto) == TEMPLATE_DECL)
    synth_tmpl_parm
      = finish_constrained_template_template_parm (proto, synth_id);
  else
    {
      synth_tmpl_parm = copy_decl (proto);
      DECL_NAME (synth_tmpl_parm) = synth_id;
      non_type = true;
    }

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

  // 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 = conjoin_constraints (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"
