/* Process declarations and variables for C++ compiler.
   Copyright (C) 1988-2018 Free Software Foundation, Inc.
   Contributed by Michael Tiemann (tiemann@cygnus.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/>.  */


/* Process declarations and symbol lookup for C++ front end.
   Also constructs types; the standard scalar types at initialization,
   and structure, union, array and enum types when they are declared.  */

/* ??? not all decl nodes are given the most useful possible
   line numbers.  For example, the CONST_DECLs for enum values.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "c-family/c-target.h"
#include "cp-tree.h"
#include "timevar.h"
#include "stringpool.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "varasm.h"
#include "attribs.h"
#include "flags.h"
#include "tree-iterator.h"
#include "decl.h"
#include "intl.h"
#include "toplev.h"
#include "c-family/c-objc.h"
#include "c-family/c-pragma.h"
#include "c-family/c-ubsan.h"
#include "debug.h"
#include "plugin.h"
#include "builtins.h"
#include "gimplify.h"
#include "asan.h"
#include "gcc-rich-location.h"
#include "langhooks.h"

/* Possible cases of bad specifiers type used by bad_specifiers. */
enum bad_spec_place {
  BSP_VAR,    /* variable */
  BSP_PARM,   /* parameter */
  BSP_TYPE,   /* type */
  BSP_FIELD   /* field */
};

static const char *redeclaration_error_message (tree, tree);

static int decl_jump_unsafe (tree);
static void require_complete_types_for_parms (tree);
static tree grok_reference_init (tree, tree, tree, int);
static tree grokvardecl (tree, tree, tree, const cp_decl_specifier_seq *,
			 int, int, int, bool, int, tree);
static void check_static_variable_definition (tree, tree);
static void record_unknown_type (tree, const char *);
static tree builtin_function_1 (tree, tree, bool);
static int member_function_or_else (tree, tree, enum overload_flags);
static tree local_variable_p_walkfn (tree *, int *, void *);
static const char *tag_name (enum tag_types);
static tree lookup_and_check_tag (enum tag_types, tree, tag_scope, bool);
static void maybe_deduce_size_from_array_init (tree, tree);
static void layout_var_decl (tree);
static tree check_initializer (tree, tree, int, vec<tree, va_gc> **);
static void make_rtl_for_nonlocal_decl (tree, tree, const char *);
static void save_function_data (tree);
static void copy_type_enum (tree , tree);
static void check_function_type (tree, tree);
static void finish_constructor_body (void);
static void begin_destructor_body (void);
static void finish_destructor_body (void);
static void record_key_method_defined (tree);
static tree create_array_type_for_decl (tree, tree, tree, location_t);
static tree get_atexit_node (void);
static tree get_dso_handle_node (void);
static tree start_cleanup_fn (void);
static void end_cleanup_fn (void);
static tree cp_make_fname_decl (location_t, tree, int);
static void initialize_predefined_identifiers (void);
static tree check_special_function_return_type
       (special_function_kind, tree, tree, int, const location_t*);
static tree push_cp_library_fn (enum tree_code, tree, int);
static tree build_cp_library_fn (tree, enum tree_code, tree, int);
static void store_parm_decls (tree);
static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);

/* The following symbols are subsumed in the cp_global_trees array, and
   listed here individually for documentation purposes.

   C++ extensions
	tree wchar_decl_node;

	tree vtable_entry_type;
	tree delta_type_node;
	tree __t_desc_type_node;

	tree class_type_node;
	tree unknown_type_node;

   Array type `vtable_entry_type[]'

	tree vtbl_type_node;
	tree vtbl_ptr_type_node;

   Namespaces,

	tree std_node;
	tree abi_node;

   A FUNCTION_DECL which can call `abort'.  Not necessarily the
   one that the user will declare, but sufficient to be called
   by routines that want to abort the program.

	tree abort_fndecl;

   Used by RTTI
	tree type_info_type_node, tinfo_decl_id, tinfo_decl_type;
	tree tinfo_var_id;  */

tree cp_global_trees[CPTI_MAX];

/* A list of objects which have constructors or destructors
   which reside in the global scope.  The decl is stored in
   the TREE_VALUE slot and the initializer is stored
   in the TREE_PURPOSE slot.  */
tree static_aggregates;

/* Like static_aggregates, but for thread_local variables.  */
tree tls_aggregates;

/* -- end of C++ */

/* A node for the integer constant 2.  */

tree integer_two_node;

/* vector of static decls.  */
vec<tree, va_gc> *static_decls;

/* vector of keyed classes.  */
vec<tree, va_gc> *keyed_classes;

/* Used only for jumps to as-yet undefined labels, since jumps to
   defined labels can have their validity checked immediately.  */

struct GTY((chain_next ("%h.next"))) named_label_use_entry {
  struct named_label_use_entry *next;
  /* The binding level to which this entry is *currently* attached.
     This is initially the binding level in which the goto appeared,
     but is modified as scopes are closed.  */
  cp_binding_level *binding_level;
  /* The head of the names list that was current when the goto appeared,
     or the inner scope popped.  These are the decls that will *not* be
     skipped when jumping to the label.  */
  tree names_in_scope;
  /* The location of the goto, for error reporting.  */
  location_t o_goto_locus;
  /* True if an OpenMP structured block scope has been closed since
     the goto appeared.  This means that the branch from the label will
     illegally exit an OpenMP scope.  */
  bool in_omp_scope;
};

/* A list of all LABEL_DECLs in the function that have names.  Here so
   we can clear out their names' definitions at the end of the
   function, and so we can check the validity of jumps to these labels.  */

struct GTY((for_user)) named_label_entry {

  tree name;  /* Name of decl. */

  tree label_decl; /* LABEL_DECL, unless deleted local label. */

  named_label_entry *outer; /* Outer shadowed chain.  */

  /* The binding level to which the label is *currently* attached.
     This is initially set to the binding level in which the label
     is defined, but is modified as scopes are closed.  */
  cp_binding_level *binding_level;

  /* The head of the names list that was current when the label was
     defined, or the inner scope popped.  These are the decls that will
     be skipped when jumping to the label.  */
  tree names_in_scope;

  /* A vector of all decls from all binding levels that would be
     crossed by a backward branch to the label.  */
  vec<tree, va_gc> *bad_decls;

  /* A list of uses of the label, before the label is defined.  */
  named_label_use_entry *uses;

  /* The following bits are set after the label is defined, and are
     updated as scopes are popped.  They indicate that a jump to the
     label will illegally enter a scope of the given flavor.  */
  bool in_try_scope;
  bool in_catch_scope;
  bool in_omp_scope;
  bool in_transaction_scope;
  bool in_constexpr_if;
};

#define named_labels cp_function_chain->x_named_labels

/* The number of function bodies which we are currently processing.
   (Zero if we are at namespace scope, one inside the body of a
   function, two inside the body of a function in a local class, etc.)  */
int function_depth;

/* Whether the exception-specifier is part of a function type (i.e. C++17).  */
bool flag_noexcept_type;

/* States indicating how grokdeclarator() should handle declspecs marked
   with __attribute__((deprecated)).  An object declared as
   __attribute__((deprecated)) suppresses warnings of uses of other
   deprecated items.  */
enum deprecated_states deprecated_state = DEPRECATED_NORMAL;


/* A list of VAR_DECLs whose type was incomplete at the time the
   variable was declared.  */

struct GTY(()) incomplete_var {
  tree decl;
  tree incomplete_type;
};


static GTY(()) vec<incomplete_var, va_gc> *incomplete_vars;

/* Returns the kind of template specialization we are currently
   processing, given that it's declaration contained N_CLASS_SCOPES
   explicit scope qualifications.  */

tmpl_spec_kind
current_tmpl_spec_kind (int n_class_scopes)
{
  int n_template_parm_scopes = 0;
  int seen_specialization_p = 0;
  int innermost_specialization_p = 0;
  cp_binding_level *b;

  /* Scan through the template parameter scopes.  */
  for (b = current_binding_level;
       b->kind == sk_template_parms;
       b = b->level_chain)
    {
      /* If we see a specialization scope inside a parameter scope,
	 then something is wrong.  That corresponds to a declaration
	 like:

	    template <class T> template <> ...

	 which is always invalid since [temp.expl.spec] forbids the
	 specialization of a class member template if the enclosing
	 class templates are not explicitly specialized as well.  */
      if (b->explicit_spec_p)
	{
	  if (n_template_parm_scopes == 0)
	    innermost_specialization_p = 1;
	  else
	    seen_specialization_p = 1;
	}
      else if (seen_specialization_p == 1)
	return tsk_invalid_member_spec;

      ++n_template_parm_scopes;
    }

  /* Handle explicit instantiations.  */
  if (processing_explicit_instantiation)
    {
      if (n_template_parm_scopes != 0)
	/* We've seen a template parameter list during an explicit
	   instantiation.  For example:

	     template <class T> template void f(int);

	   This is erroneous.  */
	return tsk_invalid_expl_inst;
      else
	return tsk_expl_inst;
    }

  if (n_template_parm_scopes < n_class_scopes)
    /* We've not seen enough template headers to match all the
       specialized classes present.  For example:

	 template <class T> void R<T>::S<T>::f(int);

       This is invalid; there needs to be one set of template
       parameters for each class.  */
    return tsk_insufficient_parms;
  else if (n_template_parm_scopes == n_class_scopes)
    /* We're processing a non-template declaration (even though it may
       be a member of a template class.)  For example:

	 template <class T> void S<T>::f(int);

       The `class T' matches the `S<T>', leaving no template headers
       corresponding to the `f'.  */
    return tsk_none;
  else if (n_template_parm_scopes > n_class_scopes + 1)
    /* We've got too many template headers.  For example:

	 template <> template <class T> void f (T);

       There need to be more enclosing classes.  */
    return tsk_excessive_parms;
  else
    /* This must be a template.  It's of the form:

	 template <class T> template <class U> void S<T>::f(U);

       This is a specialization if the innermost level was a
       specialization; otherwise it's just a definition of the
       template.  */
    return innermost_specialization_p ? tsk_expl_spec : tsk_template;
}

/* Exit the current scope.  */

void
finish_scope (void)
{
  poplevel (0, 0, 0);
}

/* When a label goes out of scope, check to see if that label was used
   in a valid manner, and issue any appropriate warnings or errors.  */

static void
check_label_used (tree label)
{
  if (!processing_template_decl)
    {
      if (DECL_INITIAL (label) == NULL_TREE)
	{
	  location_t location;

	  error ("label %q+D used but not defined", label);
	  location = input_location;
	    /* FIXME want (LOCATION_FILE (input_location), (line)0) */
	  /* Avoid crashing later.  */
	  define_label (location, DECL_NAME (label));
	}
      else 
	warn_for_unused_label (label);
    }
}

/* Helper function to sort named label entries in a vector by DECL_UID.  */

static int
sort_labels (const void *a, const void *b)
{
  tree label1 = *(tree const *) a;
  tree label2 = *(tree const *) b;

  /* DECL_UIDs can never be equal.  */
  return DECL_UID (label1) > DECL_UID (label2) ? -1 : +1;
}

/* At the end of a function, all labels declared within the function
   go out of scope.  BLOCK is the top-level block for the
   function.  */

static void
pop_labels (tree block)
{
  if (!named_labels)
    return;

  /* We need to add the labels to the block chain, so debug
     information is emitted.  But, we want the order to be stable so
     need to sort them first.  Otherwise the debug output could be
     randomly ordered.  I guess it's mostly stable, unless the hash
     table implementation changes.  */
  auto_vec<tree, 32> labels (named_labels->elements ());
  hash_table<named_label_hash>::iterator end (named_labels->end ());
  for (hash_table<named_label_hash>::iterator iter
	 (named_labels->begin ()); iter != end; ++iter)
    {
      named_label_entry *ent = *iter;

      gcc_checking_assert (!ent->outer);
      if (ent->label_decl)
	labels.quick_push (ent->label_decl);
      ggc_free (ent);
    }
  named_labels = NULL;
  labels.qsort (sort_labels);

  while (labels.length ())
    {
      tree label = labels.pop ();

      DECL_CHAIN (label) = BLOCK_VARS (block);
      BLOCK_VARS (block) = label;

      check_label_used (label);
    }
}

/* At the end of a block with local labels, restore the outer definition.  */

static void
pop_local_label (tree id, tree label)
{
  check_label_used (label);
  named_label_entry **slot = named_labels->find_slot_with_hash
    (id, IDENTIFIER_HASH_VALUE (id), NO_INSERT);
  named_label_entry *ent = *slot;

  if (ent->outer)
    ent = ent->outer;
  else
    {
      ent = ggc_cleared_alloc<named_label_entry> ();
      ent->name = id;
    }
  *slot = ent;
}

/* The following two routines are used to interface to Objective-C++.
   The binding level is purposely treated as an opaque type.  */

void *
objc_get_current_scope (void)
{
  return current_binding_level;
}

/* The following routine is used by the NeXT-style SJLJ exceptions;
   variables get marked 'volatile' so as to not be clobbered by
   _setjmp()/_longjmp() calls.  All variables in the current scope,
   as well as parent scopes up to (but not including) ENCLOSING_BLK
   shall be thusly marked.  */

void
objc_mark_locals_volatile (void *enclosing_blk)
{
  cp_binding_level *scope;

  for (scope = current_binding_level;
       scope && scope != enclosing_blk;
       scope = scope->level_chain)
    {
      tree decl;

      for (decl = scope->names; decl; decl = TREE_CHAIN (decl))
	objc_volatilize_decl (decl);

      /* Do not climb up past the current function.  */
      if (scope->kind == sk_function_parms)
	break;
    }
}

/* True if B is the level for the condition of a constexpr if.  */

static bool
level_for_constexpr_if (cp_binding_level *b)
{
  return (b->kind == sk_cond && b->this_entity
	  && TREE_CODE (b->this_entity) == IF_STMT
	  && IF_STMT_CONSTEXPR_P (b->this_entity));
}

/* Update data for defined and undefined labels when leaving a scope.  */

int
poplevel_named_label_1 (named_label_entry **slot, cp_binding_level *bl)
{
  named_label_entry *ent = *slot;
  cp_binding_level *obl = bl->level_chain;

  if (ent->binding_level == bl)
    {
      tree decl;

      /* ENT->NAMES_IN_SCOPE may contain a mixture of DECLs and
	 TREE_LISTs representing OVERLOADs, so be careful.  */
      for (decl = ent->names_in_scope; decl; decl = (DECL_P (decl)
						     ? DECL_CHAIN (decl)
						     : TREE_CHAIN (decl)))
	if (decl_jump_unsafe (decl))
	  vec_safe_push (ent->bad_decls, decl);

      ent->binding_level = obl;
      ent->names_in_scope = obl->names;
      switch (bl->kind)
	{
	case sk_try:
	  ent->in_try_scope = true;
	  break;
	case sk_catch:
	  ent->in_catch_scope = true;
	  break;
	case sk_omp:
	  ent->in_omp_scope = true;
	  break;
	case sk_transaction:
	  ent->in_transaction_scope = true;
	  break;
	case sk_block:
	  if (level_for_constexpr_if (bl->level_chain))
	    ent->in_constexpr_if = true;
	  break;
	default:
	  break;
	}
    }
  else if (ent->uses)
    {
      struct named_label_use_entry *use;

      for (use = ent->uses; use ; use = use->next)
	if (use->binding_level == bl)
	  {
	    use->binding_level = obl;
	    use->names_in_scope = obl->names;
	    if (bl->kind == sk_omp)
	      use->in_omp_scope = true;
	  }
    }

  return 1;
}

/* Saved errorcount to avoid -Wunused-but-set-{parameter,variable} warnings
   when errors were reported, except for -Werror-unused-but-set-*.  */
static int unused_but_set_errorcount;

/* Exit a binding level.
   Pop the level off, and restore the state of the identifier-decl mappings
   that were in effect when this level was entered.

   If KEEP == 1, this level had explicit declarations, so
   and create a "block" (a BLOCK node) for the level
   to record its declarations and subblocks for symbol table output.

   If FUNCTIONBODY is nonzero, this level is the body of a function,
   so create a block as if KEEP were set and also clear out all
   label names.

   If REVERSE is nonzero, reverse the order of decls before putting
   them into the BLOCK.  */

tree
poplevel (int keep, int reverse, int functionbody)
{
  tree link;
  /* The chain of decls was accumulated in reverse order.
     Put it into forward order, just for cleanliness.  */
  tree decls;
  tree subblocks;
  tree block;
  tree decl;
  scope_kind kind;

  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
 restart:

  block = NULL_TREE;

  gcc_assert (current_binding_level->kind != sk_class
	      && current_binding_level->kind != sk_namespace);

  if (current_binding_level->kind == sk_cleanup)
    functionbody = 0;
  subblocks = functionbody >= 0 ? current_binding_level->blocks : 0;

  gcc_assert (!vec_safe_length (current_binding_level->class_shadowed));

  /* We used to use KEEP == 2 to indicate that the new block should go
     at the beginning of the list of blocks at this binding level,
     rather than the end.  This hack is no longer used.  */
  gcc_assert (keep == 0 || keep == 1);

  if (current_binding_level->keep)
    keep = 1;

  /* Any uses of undefined labels, and any defined labels, now operate
     under constraints of next binding contour.  */
  if (cfun && !functionbody && named_labels)
    named_labels->traverse<cp_binding_level *, poplevel_named_label_1>
		   (current_binding_level);

  /* Get the decls in the order they were written.
     Usually current_binding_level->names is in reverse order.
     But parameter decls were previously put in forward order.  */

  decls = current_binding_level->names;
  if (reverse)
    {
      decls = nreverse (decls);
      current_binding_level->names = decls;
    }

  /* If there were any declarations or structure tags in that level,
     or if this level is a function body,
     create a BLOCK to record them for the life of this function.  */
  block = NULL_TREE;
  /* Avoid function body block if possible.  */
  if (functionbody && subblocks && BLOCK_CHAIN (subblocks) == NULL_TREE)
    keep = 0;
  else if (keep == 1 || functionbody)
    block = make_node (BLOCK);
  if (block != NULL_TREE)
    {
      BLOCK_VARS (block) = decls;
      BLOCK_SUBBLOCKS (block) = subblocks;
    }

  /* In each subblock, record that this is its superior.  */
  if (keep >= 0)
    for (link = subblocks; link; link = BLOCK_CHAIN (link))
      BLOCK_SUPERCONTEXT (link) = block;

  /* Before we remove the declarations first check for unused variables.  */
  if ((warn_unused_variable || warn_unused_but_set_variable)
      && current_binding_level->kind != sk_template_parms
      && !processing_template_decl)
    for (tree d = get_local_decls (); d; d = TREE_CHAIN (d))
      {
	/* There are cases where D itself is a TREE_LIST.  See in
	   push_local_binding where the list of decls returned by
	   getdecls is built.  */
	decl = TREE_CODE (d) == TREE_LIST ? TREE_VALUE (d) : d;

	tree type = TREE_TYPE (decl);
	if (VAR_P (decl)
	    && (! TREE_USED (decl) || !DECL_READ_P (decl))
	    && ! DECL_IN_SYSTEM_HEADER (decl)
	    /* For structured bindings, consider only real variables, not
	       subobjects.  */
	    && (DECL_DECOMPOSITION_P (decl) ? !DECL_DECOMP_BASE (decl)
		: (DECL_NAME (decl) && !DECL_ARTIFICIAL (decl)))
	    && type != error_mark_node
	    && (!CLASS_TYPE_P (type)
		|| !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
		|| lookup_attribute ("warn_unused",
				     TYPE_ATTRIBUTES (TREE_TYPE (decl)))))
	  {
	    if (! TREE_USED (decl))
	      {
		if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl))
		  warning_at (DECL_SOURCE_LOCATION (decl),
			      OPT_Wunused_variable,
			      "unused structured binding declaration");
		else
		  warning_at (DECL_SOURCE_LOCATION (decl),
			      OPT_Wunused_variable, "unused variable %qD", decl);
	      }
	    else if (DECL_CONTEXT (decl) == current_function_decl
		     // For -Wunused-but-set-variable leave references alone.
		     && !TYPE_REF_P (TREE_TYPE (decl))
		     && errorcount == unused_but_set_errorcount)
	      {
		if (!DECL_NAME (decl) && DECL_DECOMPOSITION_P (decl))
		  warning_at (DECL_SOURCE_LOCATION (decl),
			      OPT_Wunused_but_set_variable, "structured "
			      "binding declaration set but not used");
		else
		  warning_at (DECL_SOURCE_LOCATION (decl),
			      OPT_Wunused_but_set_variable,
			      "variable %qD set but not used", decl);
		unused_but_set_errorcount = errorcount;
	      }
	  }
      }

  /* Remove declarations for all the DECLs in this level.  */
  for (link = decls; link; link = TREE_CHAIN (link))
    {
      decl = TREE_CODE (link) == TREE_LIST ? TREE_VALUE (link) : link;
      tree name = OVL_NAME (decl);

      /* Remove the binding.  */
      if (TREE_CODE (decl) == LABEL_DECL)
	pop_local_label (name, decl);
      else
	pop_local_binding (name, decl);
    }

  /* Restore the IDENTIFIER_TYPE_VALUEs.  */
  for (link = current_binding_level->type_shadowed;
       link; link = TREE_CHAIN (link))
    SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link));

  /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs
     list if a `using' declaration put them there.  The debugging
     back ends won't understand OVERLOAD, so we remove them here.
     Because the BLOCK_VARS are (temporarily) shared with
     CURRENT_BINDING_LEVEL->NAMES we must do this fixup after we have
     popped all the bindings.  Also remove undeduced 'auto' decls,
     which LTO doesn't understand, and can't have been used by anything.  */
  if (block)
    {
      tree* d;

      for (d = &BLOCK_VARS (block); *d; )
	{
	  if (TREE_CODE (*d) == TREE_LIST
	      || (!processing_template_decl
		  && undeduced_auto_decl (*d)))
	    *d = TREE_CHAIN (*d);
	  else
	    d = &DECL_CHAIN (*d);
	}
    }

  /* If the level being exited is the top level of a function,
     check over all the labels.  */
  if (functionbody)
    {
      if (block)
	{
	  /* Since this is the top level block of a function, the vars are
	     the function's parameters.  Don't leave them in the BLOCK
	     because they are found in the FUNCTION_DECL instead.  */
	  BLOCK_VARS (block) = 0;
	  pop_labels (block);
	}
      else
	pop_labels (subblocks);
    }

  kind = current_binding_level->kind;
  if (kind == sk_cleanup)
    {
      tree stmt;

      /* If this is a temporary binding created for a cleanup, then we'll
	 have pushed a statement list level.  Pop that, create a new
	 BIND_EXPR for the block, and insert it into the stream.  */
      stmt = pop_stmt_list (current_binding_level->statement_list);
      stmt = c_build_bind_expr (input_location, block, stmt);
      add_stmt (stmt);
    }

  leave_scope ();
  if (functionbody)
    {
      /* The current function is being defined, so its DECL_INITIAL
	 should be error_mark_node.  */
      gcc_assert (DECL_INITIAL (current_function_decl) == error_mark_node);
      DECL_INITIAL (current_function_decl) = block ? block : subblocks;
      if (subblocks)
	{
	  if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
	    {
	      if (BLOCK_SUBBLOCKS (subblocks))
		BLOCK_OUTER_CURLY_BRACE_P (BLOCK_SUBBLOCKS (subblocks)) = 1;
	    }
	  else
	    BLOCK_OUTER_CURLY_BRACE_P (subblocks) = 1;
	}
    }
  else if (block)
    current_binding_level->blocks
      = block_chainon (current_binding_level->blocks, block);

  /* If we did not make a block for the level just exited,
     any blocks made for inner levels
     (since they cannot be recorded as subblocks in that level)
     must be carried forward so they will later become subblocks
     of something else.  */
  else if (subblocks)
    current_binding_level->blocks
      = block_chainon (current_binding_level->blocks, subblocks);

  /* Each and every BLOCK node created here in `poplevel' is important
     (e.g. for proper debugging information) so if we created one
     earlier, mark it as "used".  */
  if (block)
    TREE_USED (block) = 1;

  /* All temporary bindings created for cleanups are popped silently.  */
  if (kind == sk_cleanup)
    goto restart;

  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  return block;
}

/* Call wrapup_globals_declarations for the globals in NAMESPACE.  */
/* Diagnose odr-used extern inline variables without definitions
   in the current TU.  */

int
wrapup_namespace_globals ()
{
  if (vec<tree, va_gc> *statics = static_decls)
    {
      tree decl;
      unsigned int i;
      FOR_EACH_VEC_ELT (*statics, i, decl)
	{
	  if (warn_unused_function
	      && TREE_CODE (decl) == FUNCTION_DECL
	      && DECL_INITIAL (decl) == 0
	      && DECL_EXTERNAL (decl)
	      && !TREE_PUBLIC (decl)
	      && !DECL_ARTIFICIAL (decl)
	      && !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)
	      && !TREE_NO_WARNING (decl))
	    warning_at (DECL_SOURCE_LOCATION (decl),
			OPT_Wunused_function,
			"%qF declared %<static%> but never defined", decl);

	  if (VAR_P (decl)
	      && DECL_EXTERNAL (decl)
	      && DECL_INLINE_VAR_P (decl)
	      && DECL_ODR_USED (decl))
	    error_at (DECL_SOURCE_LOCATION (decl),
		      "odr-used inline variable %qD is not defined", decl);
	}

      /* Clear out the list, so we don't rescan next time.  */
      static_decls = NULL;

      /* Write out any globals that need to be output.  */
      return wrapup_global_declarations (statics->address (),
					 statics->length ());
    }
  return 0;
}

/* In C++, you don't have to write `struct S' to refer to `S'; you
   can just use `S'.  We accomplish this by creating a TYPE_DECL as
   if the user had written `typedef struct S S'.  Create and return
   the TYPE_DECL for TYPE.  */

tree
create_implicit_typedef (tree name, tree type)
{
  tree decl;

  decl = build_decl (input_location, TYPE_DECL, name, type);
  DECL_ARTIFICIAL (decl) = 1;
  /* There are other implicit type declarations, like the one *within*
     a class that allows you to write `S::S'.  We must distinguish
     amongst these.  */
  SET_DECL_IMPLICIT_TYPEDEF_P (decl);
  TYPE_NAME (type) = decl;
  TYPE_STUB_DECL (type) = decl;

  return decl;
}

/* Function-scope local entities that need discriminators.  Each entry
   is a {decl,name} pair.  VAR_DECLs for anon unions get their name
   smashed, so we cannot rely on DECL_NAME.  */

static GTY((deletable)) vec<tree, va_gc> *local_entities;

/* Determine the mangling discriminator of local DECL.  There are
   generally very few of these in any particular function.  */

void
determine_local_discriminator (tree decl)
{
  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
  retrofit_lang_decl (decl);
  tree ctx = DECL_CONTEXT (decl);
  tree name = (TREE_CODE (decl) == TYPE_DECL
	       && TYPE_UNNAMED_P (TREE_TYPE (decl))
	       ? NULL_TREE : DECL_NAME (decl));
  size_t nelts = vec_safe_length (local_entities);
  for (size_t i = 0; i < nelts; i += 2)
    {
      tree *pair = &(*local_entities)[i];
      tree d = pair[0];
      tree n = pair[1];
      gcc_checking_assert (d != decl);
      if (name == n
	  && TREE_CODE (decl) == TREE_CODE (d)
	  && ctx == DECL_CONTEXT (d))
	{
	  tree disc = integer_one_node;
	  if (DECL_DISCRIMINATOR (d))
	    disc = build_int_cst (TREE_TYPE (disc),
				  TREE_INT_CST_LOW (DECL_DISCRIMINATOR (d)) + 1);
	  DECL_DISCRIMINATOR (decl) = disc;
	  /* Replace the saved decl.  */
	  pair[0] = decl;
	  decl = NULL_TREE;
	  break;
	}
    }

  if (decl)
    {
      vec_safe_reserve (local_entities, 2);
      local_entities->quick_push (decl);
      local_entities->quick_push (name);
    }

  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
}


/* Subroutine of duplicate_decls: return truthvalue of whether
   or not types of these decls match.

   For C++, we must compare the parameter list so that `int' can match
   `int&' in a parameter position, but `int&' is not confused with
   `const int&'.  */

int
decls_match (tree newdecl, tree olddecl, bool record_versions /* = true */)
{
  int types_match;

  if (newdecl == olddecl)
    return 1;

  if (TREE_CODE (newdecl) != TREE_CODE (olddecl))
    /* If the two DECLs are not even the same kind of thing, we're not
       interested in their types.  */
    return 0;

  gcc_assert (DECL_P (newdecl));

  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      tree f1 = TREE_TYPE (newdecl);
      tree f2 = TREE_TYPE (olddecl);
      tree p1 = TYPE_ARG_TYPES (f1);
      tree p2 = TYPE_ARG_TYPES (f2);
      tree r2;

      /* Specializations of different templates are different functions
	 even if they have the same type.  */
      tree t1 = (DECL_USE_TEMPLATE (newdecl)
		 ? DECL_TI_TEMPLATE (newdecl)
		 : NULL_TREE);
      tree t2 = (DECL_USE_TEMPLATE (olddecl)
		 ? DECL_TI_TEMPLATE (olddecl)
		 : NULL_TREE);
      if (t1 != t2)
	return 0;

      if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
	  && ! (DECL_EXTERN_C_P (newdecl)
		&& DECL_EXTERN_C_P (olddecl)))
	return 0;

      /* A new declaration doesn't match a built-in one unless it
	 is also extern "C".  */
      if (DECL_IS_BUILTIN (olddecl)
	  && DECL_EXTERN_C_P (olddecl) && !DECL_EXTERN_C_P (newdecl))
	return 0;

      if (TREE_CODE (f1) != TREE_CODE (f2))
	return 0;

      /* A declaration with deduced return type should use its pre-deduction
	 type for declaration matching.  */
      r2 = fndecl_declared_return_type (olddecl);

      if (same_type_p (TREE_TYPE (f1), r2))
	{
	  if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
	      && fndecl_built_in_p (olddecl))
	    {
	      types_match = self_promoting_args_p (p1);
	      if (p1 == void_list_node)
		TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
	    }
	  else
	    types_match =
	      compparms (p1, p2)
	      && type_memfn_rqual (f1) == type_memfn_rqual (f2)
	      && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
	          || comp_type_attributes (TREE_TYPE (newdecl),
					   TREE_TYPE (olddecl)) != 0);
	}
      else
	types_match = 0;

      /* The decls dont match if they correspond to two different versions
	 of the same function.   Disallow extern "C" functions to be
	 versions for now.  */
      if (types_match
	  && !DECL_EXTERN_C_P (newdecl)
	  && !DECL_EXTERN_C_P (olddecl)
	  && record_versions
	  && maybe_version_functions (newdecl, olddecl,
				      (!DECL_FUNCTION_VERSIONED (newdecl)
				       || !DECL_FUNCTION_VERSIONED (olddecl))))
	return 0;
    }
  else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
    {
      tree oldres = DECL_TEMPLATE_RESULT (olddecl);
      tree newres = DECL_TEMPLATE_RESULT (newdecl);

      if (TREE_CODE (newres) != TREE_CODE (oldres))
	return 0;

      if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
				DECL_TEMPLATE_PARMS (olddecl)))
	return 0;

      if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
	types_match = (same_type_p (TREE_TYPE (oldres), TREE_TYPE (newres))
		       && equivalently_constrained (olddecl, newdecl));
      else
	// We don't need to check equivalently_constrained for variable and
	// function templates because we check it on the results.
	types_match = decls_match (oldres, newres);
    }
  else
    {
      /* Need to check scope for variable declaration (VAR_DECL).
	 For typedef (TYPE_DECL), scope is ignored.  */
      if (VAR_P (newdecl)
	  && CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
	  /* [dcl.link]
	     Two declarations for an object with C language linkage
	     with the same name (ignoring the namespace that qualify
	     it) that appear in different namespace scopes refer to
	     the same object.  */
	  && !(DECL_EXTERN_C_P (olddecl) && DECL_EXTERN_C_P (newdecl)))
	return 0;

      if (TREE_TYPE (newdecl) == error_mark_node)
	types_match = TREE_TYPE (olddecl) == error_mark_node;
      else if (TREE_TYPE (olddecl) == NULL_TREE)
	types_match = TREE_TYPE (newdecl) == NULL_TREE;
      else if (TREE_TYPE (newdecl) == NULL_TREE)
	types_match = 0;
      else
	types_match = comptypes (TREE_TYPE (newdecl),
				 TREE_TYPE (olddecl),
				 COMPARE_REDECLARATION);
    }

  // Normal functions can be constrained, as can variable partial
  // specializations.
  if (types_match && VAR_OR_FUNCTION_DECL_P (newdecl))
    types_match = equivalently_constrained (newdecl, olddecl);

  return types_match;
}

/* NEWDECL and OLDDECL have identical signatures.  If they are
   different versions adjust them and return true.
   If RECORD is set to true, record function versions.  */

bool
maybe_version_functions (tree newdecl, tree olddecl, bool record)
{
  if (!targetm.target_option.function_versions (newdecl, olddecl))
    return false;

  if (!DECL_FUNCTION_VERSIONED (olddecl))
    {
      DECL_FUNCTION_VERSIONED (olddecl) = 1;
      if (DECL_ASSEMBLER_NAME_SET_P (olddecl))
	mangle_decl (olddecl);
    }

  if (!DECL_FUNCTION_VERSIONED (newdecl))
    {
      DECL_FUNCTION_VERSIONED (newdecl) = 1;
      if (DECL_ASSEMBLER_NAME_SET_P (newdecl))
	mangle_decl (newdecl);
    }

  if (record)
    cgraph_node::record_function_versions (olddecl, newdecl);

  return true;
}

/* If NEWDECL is `static' and an `extern' was seen previously,
   warn about it.  OLDDECL is the previous declaration.

   Note that this does not apply to the C++ case of declaring
   a variable `extern const' and then later `const'.

   Don't complain about built-in functions, since they are beyond
   the user's control.  */

void
warn_extern_redeclared_static (tree newdecl, tree olddecl)
{
  if (TREE_CODE (newdecl) == TYPE_DECL
      || TREE_CODE (newdecl) == TEMPLATE_DECL
      || TREE_CODE (newdecl) == CONST_DECL
      || TREE_CODE (newdecl) == NAMESPACE_DECL)
    return;

  /* Don't get confused by static member functions; that's a different
     use of `static'.  */
  if (TREE_CODE (newdecl) == FUNCTION_DECL
      && DECL_STATIC_FUNCTION_P (newdecl))
    return;

  /* If the old declaration was `static', or the new one isn't, then
     everything is OK.  */
  if (DECL_THIS_STATIC (olddecl) || !DECL_THIS_STATIC (newdecl))
    return;

  /* It's OK to declare a builtin function as `static'.  */
  if (TREE_CODE (olddecl) == FUNCTION_DECL
      && DECL_ARTIFICIAL (olddecl))
    return;

  auto_diagnostic_group d;
  if (permerror (DECL_SOURCE_LOCATION (newdecl),
		 "%qD was declared %<extern%> and later %<static%>", newdecl))
    inform (DECL_SOURCE_LOCATION (olddecl),
	    "previous declaration of %qD", olddecl);
}

/* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
   function templates.  If their exception specifications do not
   match, issue a diagnostic.  */

static void
check_redeclaration_exception_specification (tree new_decl,
					     tree old_decl)
{
  tree new_exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (new_decl));
  tree old_exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (old_decl));

  /* Two default specs are equivalent, don't force evaluation.  */
  if (UNEVALUATED_NOEXCEPT_SPEC_P (new_exceptions)
      && UNEVALUATED_NOEXCEPT_SPEC_P (old_exceptions))
    return;

  if (!type_dependent_expression_p (old_decl))
    {
      maybe_instantiate_noexcept (new_decl);
      maybe_instantiate_noexcept (old_decl);
    }
  new_exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (new_decl));
  old_exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (old_decl));

  /* [except.spec]

     If any declaration of a function has an exception-specification,
     all declarations, including the definition and an explicit
     specialization, of that function shall have an
     exception-specification with the same set of type-ids.  */
  if (! DECL_IS_BUILTIN (old_decl)
      && !comp_except_specs (new_exceptions, old_exceptions, ce_normal))
    {
      const char *const msg
	= G_("declaration of %qF has a different exception specifier");
      bool complained = true;
      location_t new_loc = DECL_SOURCE_LOCATION (new_decl);
      auto_diagnostic_group d;
      if (DECL_IN_SYSTEM_HEADER (old_decl))
	complained = pedwarn (new_loc, OPT_Wsystem_headers, msg, new_decl);
      else if (!flag_exceptions)
	/* We used to silently permit mismatched eh specs with
	   -fno-exceptions, so make them a pedwarn now.  */
	complained = pedwarn (new_loc, OPT_Wpedantic, msg, new_decl);
      else
	error_at (new_loc, msg, new_decl);
      if (complained)
	inform (DECL_SOURCE_LOCATION (old_decl),
		"from previous declaration %qF", old_decl);
    }
}

/* Return true if OLD_DECL and NEW_DECL agree on constexprness.
   Otherwise issue diagnostics.  */

static bool
validate_constexpr_redeclaration (tree old_decl, tree new_decl)
{
  old_decl = STRIP_TEMPLATE (old_decl);
  new_decl = STRIP_TEMPLATE (new_decl);
  if (!VAR_OR_FUNCTION_DECL_P (old_decl)
      || !VAR_OR_FUNCTION_DECL_P (new_decl))
    return true;
  if (DECL_DECLARED_CONSTEXPR_P (old_decl)
      == DECL_DECLARED_CONSTEXPR_P (new_decl))
    return true;
  if (TREE_CODE (old_decl) == FUNCTION_DECL)
    {
      if (fndecl_built_in_p (old_decl))
	{
	  /* Hide a built-in declaration.  */
	  DECL_DECLARED_CONSTEXPR_P (old_decl)
	    = DECL_DECLARED_CONSTEXPR_P (new_decl);
	  return true;
	}
      /* 7.1.5 [dcl.constexpr]
	 Note: An explicit specialization can differ from the template
	 declaration with respect to the constexpr specifier.  */
      if (! DECL_TEMPLATE_SPECIALIZATION (old_decl)
	  && DECL_TEMPLATE_SPECIALIZATION (new_decl))
	return true;

      error_at (DECL_SOURCE_LOCATION (new_decl),
		"redeclaration %qD differs in %<constexpr%> "
		"from previous declaration", new_decl);
      inform (DECL_SOURCE_LOCATION (old_decl),
	      "previous declaration %qD", old_decl);
      return false;
    }
  return true;
}

// If OLDDECL and NEWDECL are concept declarations with the same type
// (i.e., and template parameters), but different requirements,
// emit diagnostics and return true. Otherwise, return false.
static inline bool
check_concept_refinement (tree olddecl, tree newdecl)
{
  if (!DECL_DECLARED_CONCEPT_P (olddecl) || !DECL_DECLARED_CONCEPT_P (newdecl))
    return false;

  tree d1 = DECL_TEMPLATE_RESULT (olddecl);
  tree d2 = DECL_TEMPLATE_RESULT (newdecl);
  if (TREE_CODE (d1) != TREE_CODE (d2))
    return false;

  tree t1 = TREE_TYPE (d1);
  tree t2 = TREE_TYPE (d2);
  if (TREE_CODE (d1) == FUNCTION_DECL)
    {
      if (compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))
          && comp_template_parms (DECL_TEMPLATE_PARMS (olddecl),
                                  DECL_TEMPLATE_PARMS (newdecl))
          && !equivalently_constrained (olddecl, newdecl))
        {
          error ("cannot specialize concept %q#D", olddecl);
          return true;
        }
    }
  return false;
}

/* DECL is a redeclaration of a function or function template.  If
   it does have default arguments issue a diagnostic.  Note: this
   function is used to enforce the requirements in C++11 8.3.6 about
   no default arguments in redeclarations.  */

static void
check_redeclaration_no_default_args (tree decl)
{
  gcc_assert (DECL_DECLARES_FUNCTION_P (decl));

  for (tree t = FUNCTION_FIRST_USER_PARMTYPE (decl);
       t && t != void_list_node; t = TREE_CHAIN (t))
    if (TREE_PURPOSE (t))
      {
	permerror (DECL_SOURCE_LOCATION (decl),
		   "redeclaration of %q#D may not have default "
		   "arguments", decl);
	return;
      }
}

/* NEWDECL is a redeclaration of a function or function template OLDDECL,
   in any case represented as FUNCTION_DECLs (the DECL_TEMPLATE_RESULTs of
   the TEMPLATE_DECLs in case of function templates).  This function is used
   to enforce the final part of C++17 11.3.6/4, about a single declaration:
   "If a friend declaration specifies a default argument expression, that
   declaration shall be a definition and shall be the only declaration of
   the function or function template in the translation unit."  */

static void
check_no_redeclaration_friend_default_args (tree olddecl, tree newdecl,
					    bool olddecl_hidden_friend_p)
{
  if (!olddecl_hidden_friend_p && !DECL_FRIEND_P (newdecl))
    return;

  tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
  tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);

  for (; t1 && t1 != void_list_node;
       t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
    if ((olddecl_hidden_friend_p && TREE_PURPOSE (t1))
	|| (DECL_FRIEND_P (newdecl) && TREE_PURPOSE (t2)))
      {
	auto_diagnostic_group d;
	if (permerror (DECL_SOURCE_LOCATION (newdecl),
		       "friend declaration of %q#D specifies default "
		       "arguments and isn't the only declaration", newdecl))
	  inform (DECL_SOURCE_LOCATION (olddecl),
		  "previous declaration of %q#D", olddecl);
	return;
      }
}

/* Merge tree bits that correspond to attributes noreturn, nothrow,
   const,  malloc, and pure from NEWDECL with those of OLDDECL.  */

static void
merge_attribute_bits (tree newdecl, tree olddecl)
{
  TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
  TREE_THIS_VOLATILE (olddecl) |= TREE_THIS_VOLATILE (newdecl);
  TREE_NOTHROW (newdecl) |= TREE_NOTHROW (olddecl);
  TREE_NOTHROW (olddecl) |= TREE_NOTHROW (newdecl);
  TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
  TREE_READONLY (olddecl) |= TREE_READONLY (newdecl);
  DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
  DECL_IS_MALLOC (olddecl) |= DECL_IS_MALLOC (newdecl);
  DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
  DECL_PURE_P (olddecl) |= DECL_PURE_P (newdecl);
  DECL_UNINLINABLE (newdecl) |= DECL_UNINLINABLE (olddecl);
  DECL_UNINLINABLE (olddecl) |= DECL_UNINLINABLE (newdecl);
}

#define GNU_INLINE_P(fn) (DECL_DECLARED_INLINE_P (fn)			\
			  && lookup_attribute ("gnu_inline",		\
					       DECL_ATTRIBUTES (fn)))

/* If NEWDECL is a redeclaration of OLDDECL, merge the declarations.
   If the redeclaration is invalid, a diagnostic is issued, and the
   error_mark_node is returned.  Otherwise, OLDDECL is returned.

   If NEWDECL is not a redeclaration of OLDDECL, NULL_TREE is
   returned.

   NEWDECL_IS_FRIEND is true if NEWDECL was declared as a friend.  */

tree
duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{
  unsigned olddecl_uid = DECL_UID (olddecl);
  int olddecl_friend = 0, types_match = 0, hidden_friend = 0;
  int olddecl_hidden_friend = 0;
  int new_defines_function = 0;
  tree new_template_info;
  location_t olddecl_loc = DECL_SOURCE_LOCATION (olddecl);
  location_t newdecl_loc = DECL_SOURCE_LOCATION (newdecl);

  if (newdecl == olddecl)
    return olddecl;

  types_match = decls_match (newdecl, olddecl);

  /* If either the type of the new decl or the type of the old decl is an
     error_mark_node, then that implies that we have already issued an
     error (earlier) for some bogus type specification, and in that case,
     it is rather pointless to harass the user with yet more error message
     about the same declaration, so just pretend the types match here.  */
  if (TREE_TYPE (newdecl) == error_mark_node
      || TREE_TYPE (olddecl) == error_mark_node)
    return error_mark_node;

  /* Check for redeclaration and other discrepancies.  */
  if (TREE_CODE (olddecl) == FUNCTION_DECL
      && DECL_ARTIFICIAL (olddecl))
    {
      gcc_assert (!DECL_HIDDEN_FRIEND_P (olddecl));
      if (TREE_CODE (newdecl) != FUNCTION_DECL)
	{
	  /* Avoid warnings redeclaring built-ins which have not been
	     explicitly declared.  */
	  if (DECL_ANTICIPATED (olddecl))
	    {
	      if (TREE_PUBLIC (newdecl)
		  && CP_DECL_CONTEXT (newdecl) == global_namespace)
		warning_at (newdecl_loc,
			    OPT_Wbuiltin_declaration_mismatch,
			    "built-in function %qD declared as non-function",
			    newdecl);
	      return NULL_TREE;
	    }

	  /* If you declare a built-in or predefined function name as static,
	     the old definition is overridden, but optionally warn this was a
	     bad choice of name.  */
	  if (! TREE_PUBLIC (newdecl))
	    {
	      warning_at (newdecl_loc,
			  OPT_Wshadow, 
			  fndecl_built_in_p (olddecl)
			  ? G_("shadowing built-in function %q#D")
			  : G_("shadowing library function %q#D"), olddecl);
	      /* Discard the old built-in function.  */
	      return NULL_TREE;
	    }
	  /* If the built-in is not ansi, then programs can override
	     it even globally without an error.  */
	  else if (! fndecl_built_in_p (olddecl))
	    warning_at (newdecl_loc, 0,
			"library function %q#D redeclared as non-function %q#D",
			olddecl, newdecl);
	  else
	    error_at (newdecl_loc,
		      "declaration of %q#D conflicts with built-in "
		      "declaration %q#D", newdecl, olddecl);
	  return NULL_TREE;
	}
      else if (DECL_OMP_DECLARE_REDUCTION_P (olddecl))
	{
	  gcc_assert (DECL_OMP_DECLARE_REDUCTION_P (newdecl));
	  error_at (newdecl_loc,
		    "redeclaration of %<pragma omp declare reduction%>");
	  inform (olddecl_loc,
		  "previous %<pragma omp declare reduction%> declaration");
	  return error_mark_node;
	}
      else if (!types_match)
	{
	  /* Avoid warnings redeclaring built-ins which have not been
	     explicitly declared.  */
	  if (DECL_ANTICIPATED (olddecl))
	    {
	      tree t1, t2;

	      /* A new declaration doesn't match a built-in one unless it
		 is also extern "C".  */
	      gcc_assert (DECL_IS_BUILTIN (olddecl));
	      gcc_assert (DECL_EXTERN_C_P (olddecl));
	      if (!DECL_EXTERN_C_P (newdecl))
		return NULL_TREE;

	      for (t1 = TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
		   t2 = TYPE_ARG_TYPES (TREE_TYPE (olddecl));
		   t1 || t2;
		   t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2))
		{
		  if (!t1 || !t2)
		    break;
		  /* FILE, tm types are not known at the time
		     we create the builtins.  */
		  for (unsigned i = 0;
		       i < sizeof (builtin_structptr_types)
			   / sizeof (builtin_structptr_type);
		       ++i)
		    if (TREE_VALUE (t2) == builtin_structptr_types[i].node)
		      {
			tree t = TREE_VALUE (t1);

			if (TYPE_PTR_P (t)
			    && TYPE_IDENTIFIER (TREE_TYPE (t))
			    == get_identifier (builtin_structptr_types[i].str)
			    && compparms (TREE_CHAIN (t1), TREE_CHAIN (t2)))
			  {
			    tree oldargs = TYPE_ARG_TYPES (TREE_TYPE (olddecl));

			    TYPE_ARG_TYPES (TREE_TYPE (olddecl))
			      = TYPE_ARG_TYPES (TREE_TYPE (newdecl));
			    types_match = decls_match (newdecl, olddecl);
			    if (types_match)
			      return duplicate_decls (newdecl, olddecl,
						      newdecl_is_friend);
			    TYPE_ARG_TYPES (TREE_TYPE (olddecl)) = oldargs;
			  }
			goto next_arg;
		      }

		  if (! same_type_p (TREE_VALUE (t1), TREE_VALUE (t2)))
		    break;
next_arg:;
		}

	      warning_at (newdecl_loc,
			  OPT_Wbuiltin_declaration_mismatch,
			  "declaration of %q#D conflicts with built-in "
			  "declaration %q#D", newdecl, olddecl);
	    }
	  else if ((DECL_EXTERN_C_P (newdecl)
		    && DECL_EXTERN_C_P (olddecl))
		   || compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
				 TYPE_ARG_TYPES (TREE_TYPE (olddecl))))
	    {
	      /* Don't really override olddecl for __* prefixed builtins
		 except for __[^b]*_chk, the compiler might be using those
		 explicitly.  */
	      if (fndecl_built_in_p (olddecl))
		{
		  tree id = DECL_NAME (olddecl);
		  const char *name = IDENTIFIER_POINTER (id);
		  size_t len;

		  if (name[0] == '_'
		      && name[1] == '_'
		      && (strncmp (name + 2, "builtin_",
				   strlen ("builtin_")) == 0
			  || (len = strlen (name)) <= strlen ("___chk")
			  || memcmp (name + len - strlen ("_chk"),
				     "_chk", strlen ("_chk") + 1) != 0))
		    {
		      if (DECL_INITIAL (newdecl))
			{
			  error_at (newdecl_loc,
				    "definition of %q#D ambiguates built-in "
				    "declaration %q#D", newdecl, olddecl);
			  return error_mark_node;
			}
		      auto_diagnostic_group d;
		      if (permerror (newdecl_loc,
				     "new declaration %q#D ambiguates built-in"
				     " declaration %q#D", newdecl, olddecl)
			  && flag_permissive)
			inform (newdecl_loc,
				"ignoring the %q#D declaration", newdecl);
		      return flag_permissive ? olddecl : error_mark_node;
		    }
		}

	      /* A near match; override the builtin.  */

	      if (TREE_PUBLIC (newdecl))
		warning_at (newdecl_loc,
			    OPT_Wbuiltin_declaration_mismatch,
			    "new declaration %q#D ambiguates built-in "
			    "declaration %q#D", newdecl, olddecl);
	      else
		warning (OPT_Wshadow, 
			 fndecl_built_in_p (olddecl)
			 ? G_("shadowing built-in function %q#D")
			 : G_("shadowing library function %q#D"), olddecl);
	    }
	  else
	    /* Discard the old built-in function.  */
	    return NULL_TREE;

	  /* Replace the old RTL to avoid problems with inlining.  */
	  COPY_DECL_RTL (newdecl, olddecl);
	}
      /* Even if the types match, prefer the new declarations type for
	 built-ins which have not been explicitly declared, for
	 exception lists, etc...  */
      else if (DECL_IS_BUILTIN (olddecl))
	{
	  tree type = TREE_TYPE (newdecl);
	  tree attribs = (*targetm.merge_type_attributes)
	    (TREE_TYPE (olddecl), type);

	  type = cp_build_type_attribute_variant (type, attribs);
	  TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = type;
	}

      /* If a function is explicitly declared "throw ()", propagate that to
	 the corresponding builtin.  */
      if (DECL_BUILT_IN_CLASS (olddecl) == BUILT_IN_NORMAL
	  && DECL_ANTICIPATED (olddecl)
	  && TREE_NOTHROW (newdecl)
	  && !TREE_NOTHROW (olddecl))
	{
	  enum built_in_function fncode = DECL_FUNCTION_CODE (olddecl);
	  tree tmpdecl = builtin_decl_explicit (fncode);
	  if (tmpdecl && tmpdecl != olddecl && types_match)
	    TREE_NOTHROW (tmpdecl)  = 1;
	}

      /* Whether or not the builtin can throw exceptions has no
	 bearing on this declarator.  */
      TREE_NOTHROW (olddecl) = 0;

      if (DECL_THIS_STATIC (newdecl) && !DECL_THIS_STATIC (olddecl))
	{
	  /* If a builtin function is redeclared as `static', merge
	     the declarations, but make the original one static.  */
	  DECL_THIS_STATIC (olddecl) = 1;
	  TREE_PUBLIC (olddecl) = 0;

	  /* Make the old declaration consistent with the new one so
	     that all remnants of the builtin-ness of this function
	     will be banished.  */
	  SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
	  COPY_DECL_RTL (newdecl, olddecl);
	}
    }
  else if (TREE_CODE (olddecl) != TREE_CODE (newdecl))
    {
      /* C++ Standard, 3.3, clause 4:
	 "[Note: a namespace name or a class template name must be unique
	 in its declarative region (7.3.2, clause 14). ]"  */
      if (TREE_CODE (olddecl) == NAMESPACE_DECL
	  || TREE_CODE (newdecl) == NAMESPACE_DECL)
	/* Namespace conflicts with not namespace.  */;
      else if (DECL_TYPE_TEMPLATE_P (olddecl)
	       || DECL_TYPE_TEMPLATE_P (newdecl))
	/* Class template conflicts.  */;
      else if ((TREE_CODE (newdecl) == FUNCTION_DECL
		&& DECL_FUNCTION_TEMPLATE_P (olddecl))
	       || (TREE_CODE (olddecl) == FUNCTION_DECL
		   && DECL_FUNCTION_TEMPLATE_P (newdecl)))
	{
	  /* One is a function and the other is a template
	     function.  */
	  if (!UDLIT_OPER_P (DECL_NAME (newdecl)))
	    return NULL_TREE;

	  /* There can only be one!  */
	  if (TREE_CODE (newdecl) == TEMPLATE_DECL
	      && check_raw_literal_operator (olddecl))
	    error_at (newdecl_loc,
		      "literal operator %q#D conflicts with"
		      " raw literal operator", newdecl);
	  else if (check_raw_literal_operator (newdecl))
	    error_at (newdecl_loc,
		      "raw literal operator %q#D conflicts with"
		      " literal operator template", newdecl);
	  else
	    return NULL_TREE;
	  
	  inform (olddecl_loc, "previous declaration %q#D", olddecl);
	  return error_mark_node;
	}
      else if (DECL_IMPLICIT_TYPEDEF_P (olddecl)
	       || DECL_IMPLICIT_TYPEDEF_P (newdecl))
	/* One is an implicit typedef, that's ok.  */
	return NULL_TREE;

      error ("%q#D redeclared as different kind of entity", newdecl);
      inform (olddecl_loc, "previous declaration %q#D", olddecl);

      return error_mark_node;
    }
  else if (!types_match)
    {
      if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl))
	/* These are certainly not duplicate declarations; they're
	   from different scopes.  */
	return NULL_TREE;

      if (TREE_CODE (newdecl) == TEMPLATE_DECL)
	{
	  /* The name of a class template may not be declared to refer to
	     any other template, class, function, object, namespace, value,
	     or type in the same scope.  */
	  if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == TYPE_DECL
	      || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
	    {
	      error_at (newdecl_loc,
			"conflicting declaration of template %q#D", newdecl);
	      inform (olddecl_loc,
		      "previous declaration %q#D", olddecl);
	      return error_mark_node;
	    }
	  else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL
		   && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL
		   && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))),
				 TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl))))
		   && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl),
					   DECL_TEMPLATE_PARMS (olddecl))
		   /* Template functions can be disambiguated by
		      return type.  */
		   && same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
				   TREE_TYPE (TREE_TYPE (olddecl)))
                   /* Template functions can also be disambiguated by
		      constraints.  */
                   && equivalently_constrained (olddecl, newdecl))
	    {
	      error_at (newdecl_loc, "ambiguating new declaration %q#D",
			newdecl);
	      inform (olddecl_loc,
		      "old declaration %q#D", olddecl);
	    }
          else if (check_concept_refinement (olddecl, newdecl))
	    return error_mark_node;
	  return NULL_TREE;
	}
      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	{
	  if (DECL_EXTERN_C_P (newdecl) && DECL_EXTERN_C_P (olddecl))
	    {
	      error_at (newdecl_loc,
			"conflicting declaration of C function %q#D",
			newdecl);
	      inform (olddecl_loc,
		      "previous declaration %q#D", olddecl);
	      return NULL_TREE;
	    }
	  /* For function versions, params and types match, but they
	     are not ambiguous.  */
	  else if ((!DECL_FUNCTION_VERSIONED (newdecl)
		    && !DECL_FUNCTION_VERSIONED (olddecl))
                   // The functions have the same parameter types.
		   && compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)),
				 TYPE_ARG_TYPES (TREE_TYPE (olddecl)))
                   // And the same constraints.
                   && equivalently_constrained (newdecl, olddecl))
	    {
	      error_at (newdecl_loc,
			"ambiguating new declaration of %q#D", newdecl);
	      inform (olddecl_loc,
		      "old declaration %q#D", olddecl);
              return error_mark_node;
	    }
	  else
	    return NULL_TREE;
	}
      else
	{
	  error_at (newdecl_loc, "conflicting declaration %q#D", newdecl);
	  inform (olddecl_loc,
		  "previous declaration as %q#D", olddecl);
	  return error_mark_node;
	}
    }
  else if (TREE_CODE (newdecl) == FUNCTION_DECL
	    && ((DECL_TEMPLATE_SPECIALIZATION (olddecl)
		 && (!DECL_TEMPLATE_INFO (newdecl)
		     || (DECL_TI_TEMPLATE (newdecl)
			 != DECL_TI_TEMPLATE (olddecl))))
		|| (DECL_TEMPLATE_SPECIALIZATION (newdecl)
		    && (!DECL_TEMPLATE_INFO (olddecl)
			|| (DECL_TI_TEMPLATE (olddecl)
			    != DECL_TI_TEMPLATE (newdecl))))))
    /* It's OK to have a template specialization and a non-template
       with the same type, or to have specializations of two
       different templates with the same type.  Note that if one is a
       specialization, and the other is an instantiation of the same
       template, that we do not exit at this point.  That situation
       can occur if we instantiate a template class, and then
       specialize one of its methods.  This situation is valid, but
       the declarations must be merged in the usual way.  */
    return NULL_TREE;
  else if (TREE_CODE (newdecl) == FUNCTION_DECL
	   && ((DECL_TEMPLATE_INSTANTIATION (olddecl)
		&& !DECL_USE_TEMPLATE (newdecl))
	       || (DECL_TEMPLATE_INSTANTIATION (newdecl)
		   && !DECL_USE_TEMPLATE (olddecl))))
    /* One of the declarations is a template instantiation, and the
       other is not a template at all.  That's OK.  */
    return NULL_TREE;
  else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
    {
      /* In [namespace.alias] we have:

	   In a declarative region, a namespace-alias-definition can be
	   used to redefine a namespace-alias declared in that declarative
	   region to refer only to the namespace to which it already
	   refers.

	 Therefore, if we encounter a second alias directive for the same
	 alias, we can just ignore the second directive.  */
      if (DECL_NAMESPACE_ALIAS (newdecl)
	  && (DECL_NAMESPACE_ALIAS (newdecl)
	      == DECL_NAMESPACE_ALIAS (olddecl)))
	return olddecl;

      /* Leave it to update_binding to merge or report error.  */
      return NULL_TREE;
    }
  else
    {
      const char *errmsg = redeclaration_error_message (newdecl, olddecl);
      if (errmsg)
	{
	  auto_diagnostic_group d;
	  error_at (newdecl_loc, errmsg, newdecl);
	  if (DECL_NAME (olddecl) != NULL_TREE)
	    inform (olddecl_loc,
		    (DECL_INITIAL (olddecl) && namespace_bindings_p ())
		    ? G_("%q#D previously defined here")
		    : G_("%q#D previously declared here"), olddecl);
	  return error_mark_node;
	}
      else if (TREE_CODE (olddecl) == FUNCTION_DECL
	       && DECL_INITIAL (olddecl) != NULL_TREE
	       && !prototype_p (TREE_TYPE (olddecl))
	       && prototype_p (TREE_TYPE (newdecl)))
	{
	  /* Prototype decl follows defn w/o prototype.  */
	  auto_diagnostic_group d;
	  if (warning_at (newdecl_loc, 0,
			  "prototype specified for %q#D", newdecl))
	    inform (olddecl_loc,
		    "previous non-prototype definition here");
	}
      else if (VAR_OR_FUNCTION_DECL_P (olddecl)
	       && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))
	{
	  /* [dcl.link]
	     If two declarations of the same function or object
	     specify different linkage-specifications ..., the program
	     is ill-formed.... Except for functions with C++ linkage,
	     a function declaration without a linkage specification
	     shall not precede the first linkage specification for
	     that function.  A function can be declared without a
	     linkage specification after an explicit linkage
	     specification has been seen; the linkage explicitly
	     specified in the earlier declaration is not affected by
	     such a function declaration.

	     DR 563 raises the question why the restrictions on
	     functions should not also apply to objects.  Older
	     versions of G++ silently ignore the linkage-specification
	     for this example:

	       namespace N { 
                 extern int i;
   	         extern "C" int i;
               }

             which is clearly wrong.  Therefore, we now treat objects
	     like functions.  */
	  if (current_lang_depth () == 0)
	    {
	      /* There is no explicit linkage-specification, so we use
		 the linkage from the previous declaration.  */
	      retrofit_lang_decl (newdecl);
	      SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
	    }
	  else
	    {
	      auto_diagnostic_group d;
	      error_at (newdecl_loc,
			"conflicting declaration of %q#D with %qL linkage",
			newdecl, DECL_LANGUAGE (newdecl));
	      inform (olddecl_loc,
		      "previous declaration with %qL linkage",
		      DECL_LANGUAGE (olddecl));
	    }
	}

      if (DECL_LANG_SPECIFIC (olddecl) && DECL_USE_TEMPLATE (olddecl))
	;
      else if (TREE_CODE (olddecl) == FUNCTION_DECL)
	{
	  /* Note: free functions, as TEMPLATE_DECLs, are handled below.  */
	  if (DECL_FUNCTION_MEMBER_P (olddecl)
	      && (/* grokfndecl passes member function templates too
		     as FUNCTION_DECLs.  */
		  DECL_TEMPLATE_INFO (olddecl)
		  /* C++11 8.3.6/6.
		     Default arguments for a member function of a class
		     template shall be specified on the initial declaration
		     of the member function within the class template.  */
		  || CLASSTYPE_TEMPLATE_INFO (CP_DECL_CONTEXT (olddecl))))
	    check_redeclaration_no_default_args (newdecl);
	  else
	    {
	      tree t1 = FUNCTION_FIRST_USER_PARMTYPE (olddecl);
	      tree t2 = FUNCTION_FIRST_USER_PARMTYPE (newdecl);
	      int i = 1;

	      for (; t1 && t1 != void_list_node;
		   t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++)
		if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2))
		  {
		    if (simple_cst_equal (TREE_PURPOSE (t1),
					  TREE_PURPOSE (t2)) == 1)
		      {
			auto_diagnostic_group d;
			if (permerror (newdecl_loc,
				       "default argument given for parameter "
				       "%d of %q#D", i, newdecl))
			  inform (olddecl_loc,
				  "previous specification in %q#D here",
				  olddecl);
		      }
		    else
		      {
			auto_diagnostic_group d;
			error_at (newdecl_loc,
				  "default argument given for parameter %d "
				  "of %q#D", i, newdecl);
			inform (olddecl_loc,
				"previous specification in %q#D here",
				olddecl);
		      }
		  }

	      /* C++17 11.3.6/4: "If a friend declaration specifies a default
		 argument expression, that declaration... shall be the only
		 declaration of the function or function template in the
		 translation unit."  */
	      check_no_redeclaration_friend_default_args
		(olddecl, newdecl, DECL_HIDDEN_FRIEND_P (olddecl));
	    }
	}
    }

  /* Do not merge an implicit typedef with an explicit one.  In:

       class A;
       ...
       typedef class A A __attribute__ ((foo));

     the attribute should apply only to the typedef.  */
  if (TREE_CODE (olddecl) == TYPE_DECL
      && (DECL_IMPLICIT_TYPEDEF_P (olddecl)
	  || DECL_IMPLICIT_TYPEDEF_P (newdecl)))
    return NULL_TREE;

  if (!validate_constexpr_redeclaration (olddecl, newdecl))
    return error_mark_node;

  /* We have committed to returning OLDDECL at this point.  */

  /* If new decl is `static' and an `extern' was seen previously,
     warn about it.  */
  warn_extern_redeclared_static (newdecl, olddecl);

  /* True to merge attributes between the declarations, false to
     set OLDDECL's attributes to those of NEWDECL (for template
     explicit specializations that specify their own attributes
     independent of those specified for the primary template).  */
  const bool merge_attr = (TREE_CODE (newdecl) != FUNCTION_DECL
			   || !DECL_TEMPLATE_SPECIALIZATION (newdecl)
			   || DECL_TEMPLATE_SPECIALIZATION (olddecl));

  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      if (merge_attr && diagnose_mismatched_attributes (olddecl, newdecl))
	inform (olddecl_loc, DECL_INITIAL (olddecl)
		? G_("previous definition of %qD here")
		: G_("previous declaration of %qD here"), olddecl);

      /* Now that functions must hold information normally held
	 by field decls, there is extra work to do so that
	 declaration information does not get destroyed during
	 definition.  */
      if (DECL_VINDEX (olddecl))
	DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl);
      if (DECL_CONTEXT (olddecl))
	DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl);
      DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl);
      DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl);
      DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (olddecl);
      DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl);
      DECL_INVALID_OVERRIDER_P (newdecl) |= DECL_INVALID_OVERRIDER_P (olddecl);
      DECL_FINAL_P (newdecl) |= DECL_FINAL_P (olddecl);
      DECL_OVERRIDE_P (newdecl) |= DECL_OVERRIDE_P (olddecl);
      DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl);
      if (DECL_OVERLOADED_OPERATOR_P (olddecl))
	DECL_OVERLOADED_OPERATOR_CODE_RAW (newdecl)
	  = DECL_OVERLOADED_OPERATOR_CODE_RAW (olddecl);
      new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE;

      /* Optionally warn about more than one declaration for the same
	 name, but don't warn about a function declaration followed by a
	 definition.  */
      if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl)
	  && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE)
	  /* Don't warn about extern decl followed by definition.  */
	  && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl))
	  /* Don't warn about friends, let add_friend take care of it.  */
	  && ! (newdecl_is_friend || DECL_FRIEND_P (olddecl))
	  /* Don't warn about declaration followed by specialization.  */
	  && (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
	      || DECL_TEMPLATE_SPECIALIZATION (olddecl)))
	{
	  auto_diagnostic_group d;
	  if (warning_at (newdecl_loc,
			  OPT_Wredundant_decls,
			  "redundant redeclaration of %qD in same scope",
			  newdecl))
	    inform (olddecl_loc,
		    "previous declaration of %qD", olddecl);
	}

      if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
	    && DECL_TEMPLATE_SPECIALIZATION (newdecl)))
	{
	  if (DECL_DELETED_FN (newdecl))
	    {
	      auto_diagnostic_group d;
	      error_at (newdecl_loc, "deleted definition of %qD", newdecl);
	      inform (olddecl_loc,
		      "previous declaration of %qD", olddecl);
	    }
	  DECL_DELETED_FN (newdecl) |= DECL_DELETED_FN (olddecl);
	}
    }

  /* Deal with C++: must preserve virtual function table size.  */
  if (TREE_CODE (olddecl) == TYPE_DECL)
    {
      tree newtype = TREE_TYPE (newdecl);
      tree oldtype = TREE_TYPE (olddecl);

      if (newtype != error_mark_node && oldtype != error_mark_node
	  && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype))
	CLASSTYPE_FRIEND_CLASSES (newtype)
	  = CLASSTYPE_FRIEND_CLASSES (oldtype);

      DECL_ORIGINAL_TYPE (newdecl) = DECL_ORIGINAL_TYPE (olddecl);
    }

  /* Copy all the DECL_... slots specified in the new decl except for
     any that we copy here from the old type.  */
  if (merge_attr)
    DECL_ATTRIBUTES (newdecl)
      = (*targetm.merge_decl_attributes) (olddecl, newdecl);
  else
    DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);

  if (DECL_DECLARES_FUNCTION_P (olddecl))
    {
      olddecl_friend = DECL_FRIEND_P (olddecl);
      olddecl_hidden_friend = DECL_HIDDEN_FRIEND_P (olddecl);
      hidden_friend = (DECL_ANTICIPATED (olddecl)
		       && DECL_HIDDEN_FRIEND_P (olddecl)
		       && newdecl_is_friend);
      if (!hidden_friend)
	{
	  DECL_ANTICIPATED (olddecl) = 0;
	  DECL_HIDDEN_FRIEND_P (olddecl) = 0;
	}
    }

  if (TREE_CODE (newdecl) == TEMPLATE_DECL)
    {
      tree old_result = DECL_TEMPLATE_RESULT (olddecl);
      tree new_result = DECL_TEMPLATE_RESULT (newdecl);
      TREE_TYPE (olddecl) = TREE_TYPE (old_result);
      DECL_TEMPLATE_SPECIALIZATIONS (olddecl)
	= chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl),
		   DECL_TEMPLATE_SPECIALIZATIONS (newdecl));

      DECL_ATTRIBUTES (old_result)
	= (*targetm.merge_decl_attributes) (old_result, new_result);

      if (DECL_FUNCTION_TEMPLATE_P (newdecl))
	{
	  if (DECL_SOURCE_LOCATION (newdecl)
	      != DECL_SOURCE_LOCATION (olddecl))
	    {
	      /* Per C++11 8.3.6/4, default arguments cannot be added in
		 later declarations of a function template.  */
	      check_redeclaration_no_default_args (newdecl);
	      /* C++17 11.3.6/4: "If a friend declaration specifies a default
		 argument expression, that declaration... shall be the only
		 declaration of the function or function template in the
		 translation unit."  */
	      check_no_redeclaration_friend_default_args
		(old_result, new_result, olddecl_hidden_friend);
	    }

	  check_default_args (newdecl);

	  if (GNU_INLINE_P (old_result) != GNU_INLINE_P (new_result)
	      && DECL_INITIAL (new_result))
	    {
	      if (DECL_INITIAL (old_result))
		DECL_UNINLINABLE (old_result) = 1;
	      else
		DECL_UNINLINABLE (old_result) = DECL_UNINLINABLE (new_result);
	      DECL_EXTERNAL (old_result) = DECL_EXTERNAL (new_result);
	      DECL_NOT_REALLY_EXTERN (old_result)
		= DECL_NOT_REALLY_EXTERN (new_result);
	      DECL_INTERFACE_KNOWN (old_result)
		= DECL_INTERFACE_KNOWN (new_result);
	      DECL_DECLARED_INLINE_P (old_result)
		= DECL_DECLARED_INLINE_P (new_result);
	      DECL_DISREGARD_INLINE_LIMITS (old_result)
	        |= DECL_DISREGARD_INLINE_LIMITS (new_result);

	    }
	  else
	    {
	      DECL_DECLARED_INLINE_P (old_result)
		|= DECL_DECLARED_INLINE_P (new_result);
	      DECL_DISREGARD_INLINE_LIMITS (old_result)
	        |= DECL_DISREGARD_INLINE_LIMITS (new_result);
	      check_redeclaration_exception_specification (newdecl, olddecl);

	      merge_attribute_bits (new_result, old_result);
	    }
	}

      /* If the new declaration is a definition, update the file and
	 line information on the declaration, and also make
	 the old declaration the same definition.  */
      if (DECL_INITIAL (new_result) != NULL_TREE)
	{
	  DECL_SOURCE_LOCATION (olddecl)
	    = DECL_SOURCE_LOCATION (old_result)
	    = DECL_SOURCE_LOCATION (newdecl);
	  DECL_INITIAL (old_result) = DECL_INITIAL (new_result);
	  if (DECL_FUNCTION_TEMPLATE_P (newdecl))
	    {
	      tree parm;
	      DECL_ARGUMENTS (old_result)
		= DECL_ARGUMENTS (new_result);
	      for (parm = DECL_ARGUMENTS (old_result); parm;
		   parm = DECL_CHAIN (parm))
		DECL_CONTEXT (parm) = old_result;
	    }
	}

      return olddecl;
    }

  if (types_match)
    {
      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	check_redeclaration_exception_specification (newdecl, olddecl);

      /* Automatically handles default parameters.  */
      tree oldtype = TREE_TYPE (olddecl);
      tree newtype;

      /* For typedefs use the old type, as the new type's DECL_NAME points
	 at newdecl, which will be ggc_freed.  */
      if (TREE_CODE (newdecl) == TYPE_DECL)
	{
	  /* But NEWTYPE might have an attribute, honor that.  */
	  tree tem = TREE_TYPE (newdecl);
	  newtype = oldtype;

	  if (TYPE_USER_ALIGN (tem))
	    {
	      if (TYPE_ALIGN (tem) > TYPE_ALIGN (newtype))
		SET_TYPE_ALIGN (newtype, TYPE_ALIGN (tem));
	      TYPE_USER_ALIGN (newtype) = true;
	    }

	  /* And remove the new type from the variants list.  */
	  if (TYPE_NAME (TREE_TYPE (newdecl)) == newdecl)
	    {
	      tree remove = TREE_TYPE (newdecl);
	      for (tree t = TYPE_MAIN_VARIANT (remove); ;
		   t = TYPE_NEXT_VARIANT (t))
		if (TYPE_NEXT_VARIANT (t) == remove)
		  {
		    TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (remove);
		    break;
		  }
	    }
	}
      else if (merge_attr)
	newtype = merge_types (TREE_TYPE (newdecl), TREE_TYPE (olddecl));
      else
	newtype = TREE_TYPE (newdecl);

      if (VAR_P (newdecl))
	{
	  DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
	  /* For already initialized vars, TREE_READONLY could have been
	     cleared in cp_finish_decl, because the var needs runtime
	     initialization or destruction.  Make sure not to set
	     TREE_READONLY on it again.  */
	  if (DECL_INITIALIZED_P (olddecl)
	      && !DECL_EXTERNAL (olddecl)
	      && !TREE_READONLY (olddecl))
	    TREE_READONLY (newdecl) = 0;
	  DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
	  DECL_NONTRIVIALLY_INITIALIZED_P (newdecl)
	    |= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl);
	  if (DECL_DEPENDENT_INIT_P (olddecl))
	    SET_DECL_DEPENDENT_INIT_P (newdecl, true);
	  DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (newdecl)
	    |= DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (olddecl);
          if (DECL_CLASS_SCOPE_P (olddecl))
            DECL_DECLARED_CONSTEXPR_P (newdecl)
	      |= DECL_DECLARED_CONSTEXPR_P (olddecl);

	  /* Merge the threadprivate attribute from OLDDECL into NEWDECL.  */
	  if (DECL_LANG_SPECIFIC (olddecl)
	      && CP_DECL_THREADPRIVATE_P (olddecl))
	    {
	      /* Allocate a LANG_SPECIFIC structure for NEWDECL, if needed.  */
	      retrofit_lang_decl (newdecl);
	      CP_DECL_THREADPRIVATE_P (newdecl) = 1;
	    }
	}

      /* An explicit specialization of a function template or of a member
	 function of a class template can be declared transaction_safe
	 independently of whether the corresponding template entity is declared
	 transaction_safe. */
      if (flag_tm && TREE_CODE (newdecl) == FUNCTION_DECL
	  && DECL_TEMPLATE_INSTANTIATION (olddecl)
	  && DECL_TEMPLATE_SPECIALIZATION (newdecl)
	  && tx_safe_fn_type_p (newtype)
	  && !tx_safe_fn_type_p (TREE_TYPE (newdecl)))
	newtype = tx_unsafe_fn_variant (newtype);

      TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype;

      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	check_default_args (newdecl);

      /* Lay the type out, unless already done.  */
      if (! same_type_p (newtype, oldtype)
	  && TREE_TYPE (newdecl) != error_mark_node
	  && !(processing_template_decl && uses_template_parms (newdecl)))
	layout_type (TREE_TYPE (newdecl));

      if ((VAR_P (newdecl)
	   || TREE_CODE (newdecl) == PARM_DECL
	   || TREE_CODE (newdecl) == RESULT_DECL
	   || TREE_CODE (newdecl) == FIELD_DECL
	   || TREE_CODE (newdecl) == TYPE_DECL)
	  && !(processing_template_decl && uses_template_parms (newdecl)))
	layout_decl (newdecl, 0);

      /* Merge deprecatedness.  */
      if (TREE_DEPRECATED (newdecl))
	TREE_DEPRECATED (olddecl) = 1;

      /* Preserve function specific target and optimization options */
      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	{
	  if (DECL_FUNCTION_SPECIFIC_TARGET (olddecl)
	      && !DECL_FUNCTION_SPECIFIC_TARGET (newdecl))
	    DECL_FUNCTION_SPECIFIC_TARGET (newdecl)
	      = DECL_FUNCTION_SPECIFIC_TARGET (olddecl);

	  if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl)
	      && !DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl))
	    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (newdecl)
	      = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (olddecl);
	}
      else
	{
	  /* Merge the const type qualifier.  */
	  if (TREE_READONLY (newdecl))
	    TREE_READONLY (olddecl) = 1;
	  /* Merge the volatile type qualifier.  */
	  if (TREE_THIS_VOLATILE (newdecl))
	    TREE_THIS_VOLATILE (olddecl) = 1;
	}

      /* Merge the initialization information.  */
      if (DECL_INITIAL (newdecl) == NULL_TREE
	  && DECL_INITIAL (olddecl) != NULL_TREE)
	{
	  DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl);
	  DECL_SOURCE_LOCATION (newdecl) = DECL_SOURCE_LOCATION (olddecl);
	  if (TREE_CODE (newdecl) == FUNCTION_DECL)
	    {
	      DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl);
	      DECL_STRUCT_FUNCTION (newdecl) = DECL_STRUCT_FUNCTION (olddecl);
	    }
	}

      if (TREE_CODE (newdecl) == FUNCTION_DECL)
	{
	  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
	    |= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
	  DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
	  DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
	  DECL_LOOPING_CONST_OR_PURE_P (newdecl)
	    |= DECL_LOOPING_CONST_OR_PURE_P (olddecl);

	  if (merge_attr)
	    merge_attribute_bits (newdecl, olddecl);
	  else
	    {
	      /* Merge the noreturn bit.  */
	      TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
	      TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
	      TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl);
	      DECL_IS_MALLOC (olddecl) = DECL_IS_MALLOC (newdecl);
	      DECL_PURE_P (olddecl) = DECL_PURE_P (newdecl);
	    }
	  /* Keep the old RTL.  */
	  COPY_DECL_RTL (olddecl, newdecl);
	}
      else if (VAR_P (newdecl)
	       && (DECL_SIZE (olddecl) || !DECL_SIZE (newdecl)))
	{
	  /* Keep the old RTL.  We cannot keep the old RTL if the old
	     declaration was for an incomplete object and the new
	     declaration is not since many attributes of the RTL will
	     change.  */
	  COPY_DECL_RTL (olddecl, newdecl);
	}
    }
  /* If cannot merge, then use the new type and qualifiers,
     and don't preserve the old rtl.  */
  else
    {
      /* Clean out any memory we had of the old declaration.  */
      tree oldstatic = value_member (olddecl, static_aggregates);
      if (oldstatic)
	TREE_VALUE (oldstatic) = error_mark_node;

      TREE_TYPE (olddecl) = TREE_TYPE (newdecl);
      TREE_READONLY (olddecl) = TREE_READONLY (newdecl);
      TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl);
      TREE_NOTHROW (olddecl) = TREE_NOTHROW (newdecl);
      TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl);
    }

  /* Merge the storage class information.  */
  merge_weak (newdecl, olddecl);

  DECL_DEFER_OUTPUT (newdecl) |= DECL_DEFER_OUTPUT (olddecl);
  TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl);
  TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl);
  if (! DECL_EXTERNAL (olddecl))
    DECL_EXTERNAL (newdecl) = 0;
  if (! DECL_COMDAT (olddecl))
    DECL_COMDAT (newdecl) = 0;

  new_template_info = NULL_TREE;
  if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl))
    {
      bool new_redefines_gnu_inline = false;

      if (new_defines_function
	  && ((DECL_INTERFACE_KNOWN (olddecl)
	       && TREE_CODE (olddecl) == FUNCTION_DECL)
	      || (TREE_CODE (olddecl) == TEMPLATE_DECL
		  && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl))
		      == FUNCTION_DECL))))
	{
	  tree fn = olddecl;

	  if (TREE_CODE (fn) == TEMPLATE_DECL)
	    fn = DECL_TEMPLATE_RESULT (olddecl);

	  new_redefines_gnu_inline = GNU_INLINE_P (fn) && DECL_INITIAL (fn);
	}

      if (!new_redefines_gnu_inline)
	{
	  DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl);
	  DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl);
	  DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl);
	}
      DECL_TEMPLATE_INSTANTIATED (newdecl)
	|= DECL_TEMPLATE_INSTANTIATED (olddecl);
      DECL_ODR_USED (newdecl) |= DECL_ODR_USED (olddecl);

      /* If the OLDDECL is an instantiation and/or specialization,
	 then the NEWDECL must be too.  But, it may not yet be marked
	 as such if the caller has created NEWDECL, but has not yet
	 figured out that it is a redeclaration.  */
      if (!DECL_USE_TEMPLATE (newdecl))
	DECL_USE_TEMPLATE (newdecl) = DECL_USE_TEMPLATE (olddecl);

      /* Don't really know how much of the language-specific
	 values we should copy from old to new.  */
      DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl);
      DECL_REPO_AVAILABLE_P (newdecl) = DECL_REPO_AVAILABLE_P (olddecl);
      DECL_INITIALIZED_IN_CLASS_P (newdecl)
	|= DECL_INITIALIZED_IN_CLASS_P (olddecl);

      if (LANG_DECL_HAS_MIN (newdecl))
	{
	  DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl);
	  if (DECL_TEMPLATE_INFO (newdecl))
	    {
	      new_template_info = DECL_TEMPLATE_INFO (newdecl);
	      if (DECL_TEMPLATE_INSTANTIATION (olddecl)
		  && DECL_TEMPLATE_SPECIALIZATION (newdecl))
		/* Remember the presence of explicit specialization args.  */
		TINFO_USED_TEMPLATE_ID (DECL_TEMPLATE_INFO (olddecl))
		  = TINFO_USED_TEMPLATE_ID (new_template_info);
	    }
	  DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl);
	}
      /* Only functions have these fields.  */
      if (DECL_DECLARES_FUNCTION_P (newdecl))
	{
	  DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl);
	  DECL_BEFRIENDING_CLASSES (newdecl)
	    = chainon (DECL_BEFRIENDING_CLASSES (newdecl),
		       DECL_BEFRIENDING_CLASSES (olddecl));
	  /* DECL_THUNKS is only valid for virtual functions,
	     otherwise it is a DECL_FRIEND_CONTEXT.  */
	  if (DECL_VIRTUAL_P (newdecl))
	    SET_DECL_THUNKS (newdecl, DECL_THUNKS (olddecl));
	}
      /* Only variables have this field.  */
      else if (VAR_P (newdecl)
	       && VAR_HAD_UNKNOWN_BOUND (olddecl))
	SET_VAR_HAD_UNKNOWN_BOUND (newdecl);
    }

  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      tree parm;

      /* Merge parameter attributes. */
      tree oldarg, newarg;
      for (oldarg = DECL_ARGUMENTS(olddecl),  newarg = DECL_ARGUMENTS(newdecl);
           oldarg && newarg;
           oldarg = DECL_CHAIN(oldarg), newarg = DECL_CHAIN(newarg))
	{
          DECL_ATTRIBUTES (newarg)
	    = (*targetm.merge_decl_attributes) (oldarg, newarg);
          DECL_ATTRIBUTES (oldarg) = DECL_ATTRIBUTES (newarg);
	}

      if (DECL_TEMPLATE_INSTANTIATION (olddecl)
	  && !DECL_TEMPLATE_INSTANTIATION (newdecl))
	{
	  /* If newdecl is not a specialization, then it is not a
	     template-related function at all.  And that means that we
	     should have exited above, returning 0.  */
	  gcc_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl));

	  if (DECL_ODR_USED (olddecl))
	    /* From [temp.expl.spec]:

	       If a template, a member template or the member of a class
	       template is explicitly specialized then that
	       specialization shall be declared before the first use of
	       that specialization that would cause an implicit
	       instantiation to take place, in every translation unit in
	       which such a use occurs.  */
	    error ("explicit specialization of %qD after first use",
		      olddecl);

	  SET_DECL_TEMPLATE_SPECIALIZATION (olddecl);
	  DECL_COMDAT (newdecl) = (TREE_PUBLIC (newdecl)
				   && DECL_DECLARED_INLINE_P (newdecl));

	  /* Don't propagate visibility from the template to the
	     specialization here.  We'll do that in determine_visibility if
	     appropriate.  */
	  DECL_VISIBILITY_SPECIFIED (olddecl) = 0;

	  /* [temp.expl.spec/14] We don't inline explicit specialization
	     just because the primary template says so.  */
	  gcc_assert (!merge_attr);

	  DECL_DECLARED_INLINE_P (olddecl)
	    = DECL_DECLARED_INLINE_P (newdecl);

	  DECL_DISREGARD_INLINE_LIMITS (olddecl)
	    = DECL_DISREGARD_INLINE_LIMITS (newdecl);

	  DECL_UNINLINABLE (olddecl) = DECL_UNINLINABLE (newdecl);
	}
      else if (new_defines_function && DECL_INITIAL (olddecl))
	{
	  /* Never inline re-defined extern inline functions.
	     FIXME: this could be better handled by keeping both
	     function as separate declarations.  */
	  DECL_UNINLINABLE (newdecl) = 1;
	}
      else
	{
	  if (DECL_PENDING_INLINE_P (olddecl))
	    {
	      DECL_PENDING_INLINE_P (newdecl) = 1;
	      DECL_PENDING_INLINE_INFO (newdecl)
		= DECL_PENDING_INLINE_INFO (olddecl);
	    }
	  else if (DECL_PENDING_INLINE_P (newdecl))
	    ;
	  else if (DECL_SAVED_FUNCTION_DATA (newdecl) == NULL)
	    DECL_SAVED_FUNCTION_DATA (newdecl)
	      = DECL_SAVED_FUNCTION_DATA (olddecl);

	  DECL_DECLARED_INLINE_P (newdecl) |= DECL_DECLARED_INLINE_P (olddecl);

	  DECL_UNINLINABLE (newdecl) = DECL_UNINLINABLE (olddecl)
	    = (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl));

	  DECL_DISREGARD_INLINE_LIMITS (newdecl)
	    = DECL_DISREGARD_INLINE_LIMITS (olddecl)
	    = (DECL_DISREGARD_INLINE_LIMITS (newdecl)
	       || DECL_DISREGARD_INLINE_LIMITS (olddecl));
	}

      /* Preserve abstractness on cloned [cd]tors.  */
      DECL_ABSTRACT_P (newdecl) = DECL_ABSTRACT_P (olddecl);

      /* Update newdecl's parms to point at olddecl.  */
      for (parm = DECL_ARGUMENTS (newdecl); parm;
	   parm = DECL_CHAIN (parm))
	DECL_CONTEXT (parm) = olddecl;

      if (! types_match)
	{
	  SET_DECL_LANGUAGE (olddecl, DECL_LANGUAGE (newdecl));
	  COPY_DECL_ASSEMBLER_NAME (newdecl, olddecl);
	  COPY_DECL_RTL (newdecl, olddecl);
	}
      if (! types_match || new_defines_function)
	{
	  /* These need to be copied so that the names are available.
	     Note that if the types do match, we'll preserve inline
	     info and other bits, but if not, we won't.  */
	  DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
	  DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
	}
      /* If redeclaring a builtin function, it stays built in
	 if newdecl is a gnu_inline definition, or if newdecl is just
	 a declaration.  */
      if (fndecl_built_in_p (olddecl)
	  && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
	{
	  DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
	  DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
	  /* If we're keeping the built-in definition, keep the rtl,
	     regardless of declaration matches.  */
	  COPY_DECL_RTL (olddecl, newdecl);
	  if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
	    {
	      enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
	      switch (fncode)
		{
		  /* If a compatible prototype of these builtin functions
		     is seen, assume the runtime implements it with the
		     expected semantics.  */
		case BUILT_IN_STPCPY:
		  if (builtin_decl_explicit_p (fncode))
		    set_builtin_decl_implicit_p (fncode, true);
		  break;
		default:
		  if (builtin_decl_explicit_p (fncode))
		    set_builtin_decl_declared_p (fncode, true);
		  break;
		}
	    }

	  copy_attributes_to_builtin (newdecl);
	}
      if (new_defines_function)
	/* If defining a function declared with other language
	   linkage, use the previously declared language linkage.  */
	SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
      else if (types_match)
	{
	  DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
	  /* Don't clear out the arguments if we're just redeclaring a
	     function.  */
	  if (DECL_ARGUMENTS (olddecl))
	    DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl);
	}
    }
  else if (TREE_CODE (newdecl) == NAMESPACE_DECL)
    NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl);

  /* Now preserve various other info from the definition.  */
  TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl);
  TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl);
  DECL_COMMON (newdecl) = DECL_COMMON (olddecl);
  COPY_DECL_ASSEMBLER_NAME (olddecl, newdecl);

  /* Warn about conflicting visibility specifications.  */
  if (DECL_VISIBILITY_SPECIFIED (olddecl)
      && DECL_VISIBILITY_SPECIFIED (newdecl)
      && DECL_VISIBILITY (newdecl) != DECL_VISIBILITY (olddecl))
    {
      auto_diagnostic_group d;
      if (warning_at (newdecl_loc, OPT_Wattributes,
		      "%qD: visibility attribute ignored because it "
		      "conflicts with previous declaration", newdecl))
	inform (olddecl_loc,
		"previous declaration of %qD", olddecl);
    }
  /* Choose the declaration which specified visibility.  */
  if (DECL_VISIBILITY_SPECIFIED (olddecl))
    {
      DECL_VISIBILITY (newdecl) = DECL_VISIBILITY (olddecl);
      DECL_VISIBILITY_SPECIFIED (newdecl) = 1;
    }
  /* Init priority used to be merged from newdecl to olddecl by the memcpy,
     so keep this behavior.  */
  if (VAR_P (newdecl) && DECL_HAS_INIT_PRIORITY_P (newdecl))
    {
      SET_DECL_INIT_PRIORITY (olddecl, DECL_INIT_PRIORITY (newdecl));
      DECL_HAS_INIT_PRIORITY_P (olddecl) = 1;
    }
  /* Likewise for DECL_ALIGN, DECL_USER_ALIGN and DECL_PACKED.  */
  if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl))
    {
      SET_DECL_ALIGN (newdecl, DECL_ALIGN (olddecl));
      DECL_USER_ALIGN (newdecl) |= DECL_USER_ALIGN (olddecl);
    }
  DECL_USER_ALIGN (olddecl) = DECL_USER_ALIGN (newdecl);
  if (DECL_WARN_IF_NOT_ALIGN (olddecl)
      > DECL_WARN_IF_NOT_ALIGN (newdecl))
    SET_DECL_WARN_IF_NOT_ALIGN (newdecl,
				DECL_WARN_IF_NOT_ALIGN (olddecl));
  if (TREE_CODE (newdecl) == FIELD_DECL)
    DECL_PACKED (olddecl) = DECL_PACKED (newdecl);

  /* The DECL_LANG_SPECIFIC information in OLDDECL will be replaced
     with that from NEWDECL below.  */
  if (DECL_LANG_SPECIFIC (olddecl))
    {
      gcc_assert (DECL_LANG_SPECIFIC (olddecl)
		  != DECL_LANG_SPECIFIC (newdecl));
      ggc_free (DECL_LANG_SPECIFIC (olddecl));
    }

  /* Merge the USED information.  */
  if (TREE_USED (olddecl))
    TREE_USED (newdecl) = 1;
  else if (TREE_USED (newdecl))
    TREE_USED (olddecl) = 1;
  if (VAR_P (newdecl))
    {
      if (DECL_READ_P (olddecl))
	DECL_READ_P (newdecl) = 1;
      else if (DECL_READ_P (newdecl))
	DECL_READ_P (olddecl) = 1;
    }
  if (DECL_PRESERVE_P (olddecl))
    DECL_PRESERVE_P (newdecl) = 1;
  else if (DECL_PRESERVE_P (newdecl))
    DECL_PRESERVE_P (olddecl) = 1;

  /* Merge the DECL_FUNCTION_VERSIONED information.  newdecl will be copied
     to olddecl and deleted.  */
  if (TREE_CODE (newdecl) == FUNCTION_DECL
      && DECL_FUNCTION_VERSIONED (olddecl))
    {
      /* Set the flag for newdecl so that it gets copied to olddecl.  */
      DECL_FUNCTION_VERSIONED (newdecl) = 1;
      /* newdecl will be purged after copying to olddecl and is no longer
         a version.  */
      cgraph_node::delete_function_version_by_decl (newdecl);
    }

  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      int function_size;
      struct symtab_node *snode = symtab_node::get (olddecl);

      function_size = sizeof (struct tree_decl_common);

      memcpy ((char *) olddecl + sizeof (struct tree_common),
	      (char *) newdecl + sizeof (struct tree_common),
	      function_size - sizeof (struct tree_common));

      memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
	      (char *) newdecl + sizeof (struct tree_decl_common),
	      sizeof (struct tree_function_decl) - sizeof (struct tree_decl_common));

      /* Preserve symtab node mapping.  */
      olddecl->decl_with_vis.symtab_node = snode;

      if (new_template_info)
	/* If newdecl is a template instantiation, it is possible that
	   the following sequence of events has occurred:

	   o A friend function was declared in a class template.  The
	   class template was instantiated.

	   o The instantiation of the friend declaration was
	   recorded on the instantiation list, and is newdecl.

	   o Later, however, instantiate_class_template called pushdecl
	   on the newdecl to perform name injection.  But, pushdecl in
	   turn called duplicate_decls when it discovered that another
	   declaration of a global function with the same name already
	   existed.

	   o Here, in duplicate_decls, we decided to clobber newdecl.

	   If we're going to do that, we'd better make sure that
	   olddecl, and not newdecl, is on the list of
	   instantiations so that if we try to do the instantiation
	   again we won't get the clobbered declaration.  */
	reregister_specialization (newdecl,
				   new_template_info,
				   olddecl);
    }
  else
    {
      size_t size = tree_code_size (TREE_CODE (newdecl));

      memcpy ((char *) olddecl + sizeof (struct tree_common),
	      (char *) newdecl + sizeof (struct tree_common),
	      sizeof (struct tree_decl_common) - sizeof (struct tree_common));
      switch (TREE_CODE (newdecl))
	{
	case LABEL_DECL:
	case VAR_DECL:
	case RESULT_DECL:
	case PARM_DECL:
	case FIELD_DECL:
	case TYPE_DECL:
	case CONST_DECL:
	  {
            struct symtab_node *snode = NULL;

	    if (VAR_P (newdecl)
		&& (TREE_STATIC (olddecl) || TREE_PUBLIC (olddecl)
		    || DECL_EXTERNAL (olddecl)))
	      snode = symtab_node::get (olddecl);
	    memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
		    (char *) newdecl + sizeof (struct tree_decl_common),
		    size - sizeof (struct tree_decl_common)
		    + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
	    if (VAR_P (newdecl))
	      olddecl->decl_with_vis.symtab_node = snode;
	  }
	  break;
	default:
	  memcpy ((char *) olddecl + sizeof (struct tree_decl_common),
		  (char *) newdecl + sizeof (struct tree_decl_common),
		  sizeof (struct tree_decl_non_common) - sizeof (struct tree_decl_common)
		  + TREE_CODE_LENGTH (TREE_CODE (newdecl)) * sizeof (char *));
	  break;
	}
    }

  if (VAR_OR_FUNCTION_DECL_P (newdecl))
    {
      if (DECL_EXTERNAL (olddecl)
	  || TREE_PUBLIC (olddecl)
	  || TREE_STATIC (olddecl))
	{
	  /* Merge the section attribute.
	     We want to issue an error if the sections conflict but that must be
	     done later in decl_attributes since we are called before attributes
	     are assigned.  */
	  if (DECL_SECTION_NAME (newdecl) != NULL)
	    set_decl_section_name (olddecl, DECL_SECTION_NAME (newdecl));

	  if (DECL_ONE_ONLY (newdecl))
	    {
	      struct symtab_node *oldsym, *newsym;
	      if (TREE_CODE (olddecl) == FUNCTION_DECL)
		oldsym = cgraph_node::get_create (olddecl);
	      else
		oldsym = varpool_node::get_create (olddecl);
	      newsym = symtab_node::get (newdecl);
	      oldsym->set_comdat_group (newsym->get_comdat_group ());
	    }
	}

      if (VAR_P (newdecl)
	  && CP_DECL_THREAD_LOCAL_P (newdecl))
	{
	  CP_DECL_THREAD_LOCAL_P (olddecl) = true;
	  if (!processing_template_decl)
	    set_decl_tls_model (olddecl, DECL_TLS_MODEL (newdecl));
	}
    }

  DECL_UID (olddecl) = olddecl_uid;
  if (olddecl_friend)
    DECL_FRIEND_P (olddecl) = 1;
  if (hidden_friend)
    {
      DECL_ANTICIPATED (olddecl) = 1;
      DECL_HIDDEN_FRIEND_P (olddecl) = 1;
    }

  /* NEWDECL contains the merged attribute lists.
     Update OLDDECL to be the same.  */
  DECL_ATTRIBUTES (olddecl) = DECL_ATTRIBUTES (newdecl);

  /* If OLDDECL had its DECL_RTL instantiated, re-invoke make_decl_rtl
    so that encode_section_info has a chance to look at the new decl
    flags and attributes.  */
  if (DECL_RTL_SET_P (olddecl)
      && (TREE_CODE (olddecl) == FUNCTION_DECL
	  || (VAR_P (olddecl)
	      && TREE_STATIC (olddecl))))
    make_decl_rtl (olddecl);

  /* The NEWDECL will no longer be needed.  Because every out-of-class
     declaration of a member results in a call to duplicate_decls,
     freeing these nodes represents in a significant savings.

     Before releasing the node, be sore to remove function from symbol
     table that might have been inserted there to record comdat group.
     Be sure to however do not free DECL_STRUCT_FUNCTION because this
     structure is shared in between newdecl and oldecl.  */
  if (TREE_CODE (newdecl) == FUNCTION_DECL)
    DECL_STRUCT_FUNCTION (newdecl) = NULL;
  if (VAR_OR_FUNCTION_DECL_P (newdecl))
    {
      struct symtab_node *snode = symtab_node::get (newdecl);
      if (snode)
	snode->remove ();
    }

  /* Remove the associated constraints for newdecl, if any, before
     reclaiming memory. */
  if (flag_concepts)
    remove_constraints (newdecl);

  ggc_free (newdecl);

  return olddecl;
}

/* Return zero if the declaration NEWDECL is valid
   when the declaration OLDDECL (assumed to be for the same name)
   has already been seen.
   Otherwise return an error message format string with a %s
   where the identifier should go.  */

static const char *
redeclaration_error_message (tree newdecl, tree olddecl)
{
  if (TREE_CODE (newdecl) == TYPE_DECL)
    {
      /* Because C++ can put things into name space for free,
	 constructs like "typedef struct foo { ... } foo"
	 would look like an erroneous redeclaration.  */
      if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl)))
	return NULL;
      else
	return G_("redefinition of %q#D");
    }
  else if (TREE_CODE (newdecl) == FUNCTION_DECL)
    {
      /* If this is a pure function, its olddecl will actually be
	 the original initialization to `0' (which we force to call
	 abort()).  Don't complain about redefinition in this case.  */
      if (DECL_LANG_SPECIFIC (olddecl) && DECL_PURE_VIRTUAL_P (olddecl)
	  && DECL_INITIAL (olddecl) == NULL_TREE)
	return NULL;

      /* If both functions come from different namespaces, this is not
	 a redeclaration - this is a conflict with a used function.  */
      if (DECL_NAMESPACE_SCOPE_P (olddecl)
	  && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)
	  && ! decls_match (olddecl, newdecl))
	return G_("%qD conflicts with used function");

      /* We'll complain about linkage mismatches in
	 warn_extern_redeclared_static.  */

      /* Defining the same name twice is no good.  */
      if (decl_defined_p (olddecl)
	  && decl_defined_p (newdecl))
	{
	  if (DECL_NAME (olddecl) == NULL_TREE)
	    return G_("%q#D not declared in class");
	  else if (!GNU_INLINE_P (olddecl)
		   || GNU_INLINE_P (newdecl))
	    return G_("redefinition of %q#D");
	}

      if (DECL_DECLARED_INLINE_P (olddecl) && DECL_DECLARED_INLINE_P (newdecl))
	{
	  bool olda = GNU_INLINE_P (olddecl);
	  bool newa = GNU_INLINE_P (newdecl);

	  if (olda != newa)
	    {
	      if (newa)
		return G_("%q+D redeclared inline with "
			  "%<gnu_inline%> attribute");
	      else
		return G_("%q+D redeclared inline without "
			  "%<gnu_inline%> attribute");
	    }
	}

      check_abi_tag_redeclaration
	(olddecl, lookup_attribute ("abi_tag", DECL_ATTRIBUTES (olddecl)),
	 lookup_attribute ("abi_tag", DECL_ATTRIBUTES (newdecl)));

      return NULL;
    }
  else if (TREE_CODE (newdecl) == TEMPLATE_DECL)
    {
      tree nt, ot;

      if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)
	{
	  if (COMPLETE_TYPE_P (TREE_TYPE (newdecl))
	      && COMPLETE_TYPE_P (TREE_TYPE (olddecl)))
	    return G_("redefinition of %q#D");
	  return NULL;
	}

      if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) != FUNCTION_DECL
	  || (DECL_TEMPLATE_RESULT (newdecl)
	      == DECL_TEMPLATE_RESULT (olddecl)))
	return NULL;

      nt = DECL_TEMPLATE_RESULT (newdecl);
      if (DECL_TEMPLATE_INFO (nt))
	nt = DECL_TEMPLATE_RESULT (template_for_substitution (nt));
      ot = DECL_TEMPLATE_RESULT (olddecl);
      if (DECL_TEMPLATE_INFO (ot))
	ot = DECL_TEMPLATE_RESULT (template_for_substitution (ot));
      if (DECL_INITIAL (nt) && DECL_INITIAL (ot)
	  && (!GNU_INLINE_P (ot) || GNU_INLINE_P (nt)))
	return G_("redefinition of %q#D");

      if (DECL_DECLARED_INLINE_P (ot) && DECL_DECLARED_INLINE_P (nt))
	{
	  bool olda = GNU_INLINE_P (ot);
	  bool newa = GNU_INLINE_P (nt);

	  if (olda != newa)
	    {
	      if (newa)
		return G_("%q+D redeclared inline with "
			  "%<gnu_inline%> attribute");
	      else
		return G_("%q+D redeclared inline without "
		     	  "%<gnu_inline%> attribute");
	    }
	}

      /* Core issue #226 (C++0x): 
           
           If a friend function template declaration specifies a
           default template-argument, that declaration shall be a
           definition and shall be the only declaration of the
           function template in the translation unit.  */
      if ((cxx_dialect != cxx98) 
          && TREE_CODE (ot) == FUNCTION_DECL && DECL_FRIEND_P (ot)
          && !check_default_tmpl_args (nt, DECL_TEMPLATE_PARMS (newdecl), 
                                       /*is_primary=*/true,
				       /*is_partial=*/false,
                                       /*is_friend_decl=*/2))
        return G_("redeclaration of friend %q#D "
	 	  "may not have default template arguments");

      return NULL;
    }
  else if (VAR_P (newdecl)
	   && CP_DECL_THREAD_LOCAL_P (newdecl) != CP_DECL_THREAD_LOCAL_P (olddecl)
	   && (! DECL_LANG_SPECIFIC (olddecl)
	       || ! CP_DECL_THREADPRIVATE_P (olddecl)
	       || CP_DECL_THREAD_LOCAL_P (newdecl)))
    {
      /* Only variables can be thread-local, and all declarations must
	 agree on this property.  */
      if (CP_DECL_THREAD_LOCAL_P (newdecl))
	return G_("thread-local declaration of %q#D follows "
	          "non-thread-local declaration");
      else
	return G_("non-thread-local declaration of %q#D follows "
	          "thread-local declaration");
    }
  else if (toplevel_bindings_p () || DECL_NAMESPACE_SCOPE_P (newdecl))
    {
      /* The objects have been declared at namespace scope.  If either
	 is a member of an anonymous union, then this is an invalid
	 redeclaration.  For example:

	   int i;
	   union { int i; };

	   is invalid.  */
      if ((VAR_P (newdecl) && DECL_ANON_UNION_VAR_P (newdecl))
	  || (VAR_P (olddecl) && DECL_ANON_UNION_VAR_P (olddecl)))
	return G_("redeclaration of %q#D");
      /* If at least one declaration is a reference, there is no
	 conflict.  For example:

	   int i = 3;
	   extern int i;

	 is valid.  */
      if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl))
	return NULL;

      /* Static data member declared outside a class definition
	 if the variable is defined within the class with constexpr
	 specifier is declaration rather than definition (and
	 deprecated).  */
      if (cxx_dialect >= cxx17
	  && VAR_P (olddecl)
	  && DECL_CLASS_SCOPE_P (olddecl)
	  && DECL_DECLARED_CONSTEXPR_P (olddecl)
	  && !DECL_INITIAL (newdecl))
	{
	  DECL_EXTERNAL (newdecl) = 1;
	  /* For now, only warn with explicit -Wdeprecated.  */
	  if (global_options_set.x_warn_deprecated)
	    {
	      auto_diagnostic_group d;
	      if (warning_at (DECL_SOURCE_LOCATION (newdecl), OPT_Wdeprecated,
				"redundant redeclaration of %<constexpr%> "
				"static data member %qD", newdecl))
		inform (DECL_SOURCE_LOCATION (olddecl),
			  "previous declaration of %qD", olddecl);
	    }
	  return NULL;
	}

      /* Reject two definitions.  */
      return G_("redefinition of %q#D");
    }
  else
    {
      /* Objects declared with block scope:  */
      /* Reject two definitions, and reject a definition
	 together with an external reference.  */
      if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl)))
	return G_("redeclaration of %q#D");
      return NULL;
    }
}


/* Hash and equality functions for the named_label table.  */

hashval_t
named_label_hash::hash (const value_type entry)
{
  return IDENTIFIER_HASH_VALUE (entry->name);
}

bool
named_label_hash::equal (const value_type entry, compare_type name)
{
  return name == entry->name;
}

/* Look for a label named ID in the current function.  If one cannot
   be found, create one.  Return the named_label_entry, or NULL on
   failure.  */

static named_label_entry *
lookup_label_1 (tree id, bool making_local_p)
{
  /* You can't use labels at global scope.  */
  if (current_function_decl == NULL_TREE)
    {
      error ("label %qE referenced outside of any function", id);
      return NULL;
    }

  if (!named_labels)
    named_labels = hash_table<named_label_hash>::create_ggc (13);

  hashval_t hash = IDENTIFIER_HASH_VALUE (id);
  named_label_entry **slot
    = named_labels->find_slot_with_hash (id, hash, INSERT);
  named_label_entry *old = *slot;
  
  if (old && old->label_decl)
    {
      if (!making_local_p)
	return old;

      if (old->binding_level == current_binding_level)
	{
	  error ("local label %qE conflicts with existing label", id);
	  inform (DECL_SOURCE_LOCATION (old->label_decl), "previous label");
	  return NULL;
	}
    }

  /* We are making a new decl, create or reuse the named_label_entry  */
  named_label_entry *ent = NULL;
  if (old && !old->label_decl)
    ent = old;
  else
    {
      ent = ggc_cleared_alloc<named_label_entry> ();
      ent->name = id;
      ent->outer = old;
      *slot = ent;
    }

  /* Now create the LABEL_DECL.  */
  tree decl = build_decl (input_location, LABEL_DECL, id, void_type_node);

  DECL_CONTEXT (decl) = current_function_decl;
  SET_DECL_MODE (decl, VOIDmode);
  if (making_local_p)
    {
      C_DECLARED_LABEL_FLAG (decl) = true;
      DECL_CHAIN (decl) = current_binding_level->names;
      current_binding_level->names = decl;
    }

  ent->label_decl = decl;

  return ent;
}

/* Wrapper for lookup_label_1.  */

tree
lookup_label (tree id)
{
  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
  named_label_entry *ent = lookup_label_1 (id, false);
  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  return ent ? ent->label_decl : NULL_TREE;
}

tree
declare_local_label (tree id)
{
  bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
  named_label_entry *ent = lookup_label_1 (id, true);
  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  return ent ? ent->label_decl : NULL_TREE;
}

/* Returns nonzero if it is ill-formed to jump past the declaration of
   DECL.  Returns 2 if it's also a real problem.  */

static int
decl_jump_unsafe (tree decl)
{
  /* [stmt.dcl]/3: A program that jumps from a point where a local variable
     with automatic storage duration is not in scope to a point where it is
     in scope is ill-formed unless the variable has scalar type, class type
     with a trivial default constructor and a trivial destructor, a
     cv-qualified version of one of these types, or an array of one of the
     preceding types and is declared without an initializer (8.5).  */
  tree type = TREE_TYPE (decl);

  if (!VAR_P (decl) || TREE_STATIC (decl)
      || type == error_mark_node)
    return 0;

  if (DECL_NONTRIVIALLY_INITIALIZED_P (decl)
      || variably_modified_type_p (type, NULL_TREE))
    return 2;

  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
    return 1;

  return 0;
}

/* A subroutine of check_previous_goto_1 and check_goto to identify a branch
   to the user.  */

static bool
identify_goto (tree decl, location_t loc, const location_t *locus,
	       diagnostic_t diag_kind)
{
  bool complained
    = emit_diagnostic (diag_kind, loc, 0,
		       decl ? N_("jump to label %qD")
		       : N_("jump to case label"), decl);
  if (complained && locus)
    inform (*locus, "  from here");
  return complained;
}

/* Check that a single previously seen jump to a newly defined label
   is OK.  DECL is the LABEL_DECL or 0; LEVEL is the binding_level for
   the jump context; NAMES are the names in scope in LEVEL at the jump
   context; LOCUS is the source position of the jump or 0.  Returns
   true if all is well.  */

static bool
check_previous_goto_1 (tree decl, cp_binding_level* level, tree names,
		       bool exited_omp, const location_t *locus)
{
  cp_binding_level *b;
  bool complained = false;
  int identified = 0;
  bool saw_eh = false, saw_omp = false, saw_tm = false, saw_cxif = false;

  if (exited_omp)
    {
      complained = identify_goto (decl, input_location, locus, DK_ERROR);
      if (complained)
	inform (input_location, "  exits OpenMP structured block");
      saw_omp = true;
      identified = 2;
    }

  for (b = current_binding_level; b ; b = b->level_chain)
    {
      tree new_decls, old_decls = (b == level ? names : NULL_TREE);

      for (new_decls = b->names; new_decls != old_decls;
	   new_decls = (DECL_P (new_decls) ? DECL_CHAIN (new_decls)
			: TREE_CHAIN (new_decls)))
	{
	  int problem = decl_jump_unsafe (new_decls);
	  if (! problem)
	    continue;

	  if (!identified)
	    {
	      complained = identify_goto (decl, input_location, locus,
					  problem > 1
					  ? DK_ERROR : DK_PERMERROR);
	      identified = 1;
	    }
	  if (complained)
	    {
	      if (problem > 1)
		inform (DECL_SOURCE_LOCATION (new_decls),
			"  crosses initialization of %q#D", new_decls);
	      else
		inform (DECL_SOURCE_LOCATION (new_decls),
			"  enters scope of %q#D, which has "
			"non-trivial destructor", new_decls);
	    }
	}

      if (b == level)
	break;

      const char *inf = NULL;
      location_t loc = input_location;
      switch (b->kind)
	{
	case sk_try:
	  if (!saw_eh)
	    inf = N_("enters try block");
	  saw_eh = true;
	  break;

	case sk_catch:
	  if (!saw_eh)
	    inf = N_("enters catch block");
	  saw_eh = true;
	  break;

	case sk_omp:
	  if (!saw_omp)
	    inf = N_("enters OpenMP structured block");
	  saw_omp = true;
	  break;

	case sk_transaction:
	  if (!saw_tm)
	    inf = N_("enters synchronized or atomic statement");
	  saw_tm = true;
	  break;

	case sk_block:
	  if (!saw_cxif && level_for_constexpr_if (b->level_chain))
	    {
	      inf = N_("enters constexpr if statement");
	      loc = EXPR_LOCATION (b->level_chain->this_entity);
	      saw_cxif = true;
	    }
	  break;

	default:
	  break;
	}

      if (inf)
	{
	  if (identified < 2)
	    complained = identify_goto (decl, input_location, locus, DK_ERROR);
	  identified = 2;
	  if (complained)
	    inform (loc, "  %s", inf);
	}
    }

  return !identified;
}

static void
check_previous_goto (tree decl, struct named_label_use_entry *use)
{
  check_previous_goto_1 (decl, use->binding_level,
			 use->names_in_scope, use->in_omp_scope,
			 &use->o_goto_locus);
}

static bool
check_switch_goto (cp_binding_level* level)
{
  return check_previous_goto_1 (NULL_TREE, level, level->names, false, NULL);
}

/* Check that a new jump to a label DECL is OK.  Called by
   finish_goto_stmt.  */

void
check_goto (tree decl)
{
  /* We can't know where a computed goto is jumping.
     So we assume that it's OK.  */
  if (TREE_CODE (decl) != LABEL_DECL)
    return;

  /* We didn't record any information about this label when we created it,
     and there's not much point since it's trivial to analyze as a return.  */
  if (decl == cdtor_label)
    return;

  hashval_t hash = IDENTIFIER_HASH_VALUE (DECL_NAME (decl));
  named_label_entry **slot
    = named_labels->find_slot_with_hash (DECL_NAME (decl), hash, NO_INSERT);
  named_label_entry *ent = *slot;

  /* If the label hasn't been defined yet, defer checking.  */
  if (! DECL_INITIAL (decl))
    {
      /* Don't bother creating another use if the last goto had the
	 same data, and will therefore create the same set of errors.  */
      if (ent->uses
	  && ent->uses->names_in_scope == current_binding_level->names)
	return;

      named_label_use_entry *new_use
	= ggc_alloc<named_label_use_entry> ();
      new_use->binding_level = current_binding_level;
      new_use->names_in_scope = current_binding_level->names;
      new_use->o_goto_locus = input_location;
      new_use->in_omp_scope = false;

      new_use->next = ent->uses;
      ent->uses = new_use;
      return;
    }

  bool saw_catch = false, complained = false;
  int identified = 0;
  tree bad;
  unsigned ix;

  if (ent->in_try_scope || ent->in_catch_scope || ent->in_transaction_scope
      || ent->in_constexpr_if
      || ent->in_omp_scope || !vec_safe_is_empty (ent->bad_decls))
    {
      diagnostic_t diag_kind = DK_PERMERROR;
      if (ent->in_try_scope || ent->in_catch_scope || ent->in_constexpr_if
	  || ent->in_transaction_scope || ent->in_omp_scope)
	diag_kind = DK_ERROR;
      complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
				  &input_location, diag_kind);
      identified = 1 + (diag_kind == DK_ERROR);
    }

  FOR_EACH_VEC_SAFE_ELT (ent->bad_decls, ix, bad)
    {
      int u = decl_jump_unsafe (bad);

      if (u > 1 && DECL_ARTIFICIAL (bad))
	{
	  /* Can't skip init of __exception_info.  */
	  if (identified == 1)
	    {
	      complained = identify_goto (decl, DECL_SOURCE_LOCATION (decl),
					  &input_location, DK_ERROR);
	      identified = 2;
	    }
	  if (complained)
	    inform (DECL_SOURCE_LOCATION (bad), "  enters catch block");
	  saw_catch = true;
	}
      else if (complained)
	{
	  if (u > 1)
	    inform (DECL_SOURCE_LOCATION (bad),
		    "  skips initialization of %q#D", bad);
	  else
	    inform (DECL_SOURCE_LOCATION (bad),
		    "  enters scope of %q#D which has "
		    "non-trivial destructor", bad);
	}
    }

  if (complained)
    {
      if (ent->in_try_scope)
	inform (input_location, "  enters try block");
      else if (ent->in_catch_scope && !saw_catch)
	inform (input_location, "  enters catch block");
      else if (ent->in_transaction_scope)
	inform (input_location, "  enters synchronized or atomic statement");
      else if (ent->in_constexpr_if)
	inform (input_location, "  enters %<constexpr%> if statement");
    }

  if (ent->in_omp_scope)
    {
      if (complained)
	inform (input_location, "  enters OpenMP structured block");
    }
  else if (flag_openmp)
    for (cp_binding_level *b = current_binding_level; b ; b = b->level_chain)
      {
	if (b == ent->binding_level)
	  break;
	if (b->kind == sk_omp)
	  {
	    if (identified < 2)
	      {
		complained = identify_goto (decl,
					    DECL_SOURCE_LOCATION (decl),
					    &input_location, DK_ERROR);
		identified = 2;
	      }
	    if (complained)
	      inform (input_location, "  exits OpenMP structured block");
	    break;
	  }
      }
}

/* Check that a return is ok wrt OpenMP structured blocks.
   Called by finish_return_stmt.  Returns true if all is well.  */

bool
check_omp_return (void)
{
  for (cp_binding_level *b = current_binding_level; b ; b = b->level_chain)
    if (b->kind == sk_omp)
      {
	error ("invalid exit from OpenMP structured block");
	return false;
      }
    else if (b->kind == sk_function_parms)
      break;
  return true;
}

/* Define a label, specifying the location in the source file.
   Return the LABEL_DECL node for the label.  */

static tree
define_label_1 (location_t location, tree name)
{
  /* After labels, make any new cleanups in the function go into their
     own new (temporary) binding contour.  */
  for (cp_binding_level *p = current_binding_level;
       p->kind != sk_function_parms;
       p = p->level_chain)
    p->more_cleanups_ok = 0;

  named_label_entry *ent = lookup_label_1 (name, false);
  tree decl = ent->label_decl;

  if (DECL_INITIAL (decl) != NULL_TREE)
    {
      error ("duplicate label %qD", decl);
      return error_mark_node;
    }
  else
    {
      /* Mark label as having been defined.  */
      DECL_INITIAL (decl) = error_mark_node;
      /* Say where in the source.  */
      DECL_SOURCE_LOCATION (decl) = location;

      ent->binding_level = current_binding_level;
      ent->names_in_scope = current_binding_level->names;

      for (named_label_use_entry *use = ent->uses; use; use = use->next)
	check_previous_goto (decl, use);
      ent->uses = NULL;
    }

  return decl;
}

/* Wrapper for define_label_1.  */

tree
define_label (location_t location, tree name)
{
  bool running = timevar_cond_start (TV_NAME_LOOKUP);
  tree ret = define_label_1 (location, name);
  timevar_cond_stop (TV_NAME_LOOKUP, running);
  return ret;
}


struct cp_switch
{
  cp_binding_level *level;
  struct cp_switch *next;
  /* The SWITCH_STMT being built.  */
  tree switch_stmt;
  /* A splay-tree mapping the low element of a case range to the high
     element, or NULL_TREE if there is no high element.  Used to
     determine whether or not a new case label duplicates an old case
     label.  We need a tree, rather than simply a hash table, because
     of the GNU case range extension.  */
  splay_tree cases;
  /* Remember whether there was a case value that is outside the
     range of the original type of the controlling expression.  */
  bool outside_range_p;
  /* Remember whether a default: case label has been seen.  */
  bool has_default_p;
  /* Remember whether a BREAK_STMT has been seen in this SWITCH_STMT.  */
  bool break_stmt_seen_p;
  /* Set if inside of {FOR,DO,WHILE}_BODY nested inside of a switch,
     where BREAK_STMT doesn't belong to the SWITCH_STMT.  */
  bool in_loop_body_p;
};

/* A stack of the currently active switch statements.  The innermost
   switch statement is on the top of the stack.  There is no need to
   mark the stack for garbage collection because it is only active
   during the processing of the body of a function, and we never
   collect at that point.  */

static struct cp_switch *switch_stack;

/* Called right after a switch-statement condition is parsed.
   SWITCH_STMT is the switch statement being parsed.  */

void
push_switch (tree switch_stmt)
{
  struct cp_switch *p = XNEW (struct cp_switch);
  p->level = current_binding_level;
  p->next = switch_stack;
  p->switch_stmt = switch_stmt;
  p->cases = splay_tree_new (case_compare, NULL, NULL);
  p->outside_range_p = false;
  p->has_default_p = false;
  p->break_stmt_seen_p = false;
  p->in_loop_body_p = false;
  switch_stack = p;
}

void
pop_switch (void)
{
  struct cp_switch *cs = switch_stack;
  location_t switch_location;

  /* Emit warnings as needed.  */
  switch_location = cp_expr_loc_or_loc (cs->switch_stmt, input_location);
  const bool bool_cond_p
    = (SWITCH_STMT_TYPE (cs->switch_stmt)
       && TREE_CODE (SWITCH_STMT_TYPE (cs->switch_stmt)) == BOOLEAN_TYPE);
  if (!processing_template_decl)
    c_do_switch_warnings (cs->cases, switch_location,
			  SWITCH_STMT_TYPE (cs->switch_stmt),
			  SWITCH_STMT_COND (cs->switch_stmt),
			  bool_cond_p, cs->outside_range_p);

  /* For the benefit of block_may_fallthru remember if the switch body
     case labels cover all possible values and if there are break; stmts.  */
  if (cs->has_default_p
      || (!processing_template_decl
	  && c_switch_covers_all_cases_p (cs->cases,
					  SWITCH_STMT_TYPE (cs->switch_stmt))))
    SWITCH_STMT_ALL_CASES_P (cs->switch_stmt) = 1;
  if (!cs->break_stmt_seen_p)
    SWITCH_STMT_NO_BREAK_P (cs->switch_stmt) = 1;
  gcc_assert (!cs->in_loop_body_p);
  splay_tree_delete (cs->cases);
  switch_stack = switch_stack->next;
  free (cs);
}

/* Note that a BREAK_STMT is about to be added.  If it is inside of
   a SWITCH_STMT and not inside of a loop body inside of it, note
   in switch_stack we've seen a BREAK_STMT.  */

void
note_break_stmt (void)
{
  if (switch_stack && !switch_stack->in_loop_body_p)
    switch_stack->break_stmt_seen_p = true;
}

/* Note the start of processing of an iteration statement's body.
   The note_break_stmt function will do nothing while processing it.
   Return a flag that should be passed to note_iteration_stmt_body_end.  */

bool
note_iteration_stmt_body_start (void)
{
  if (!switch_stack)
    return false;
  bool ret = switch_stack->in_loop_body_p;
  switch_stack->in_loop_body_p = true;
  return ret;
}

/* Note the end of processing of an iteration statement's body.  */

void
note_iteration_stmt_body_end (bool prev)
{
  if (switch_stack)
    switch_stack->in_loop_body_p = prev;
}

/* Convert a case constant VALUE in a switch to the type TYPE of the switch
   condition.  Note that if TYPE and VALUE are already integral we don't
   really do the conversion because the language-independent
   warning/optimization code will work better that way.  */

static tree
case_conversion (tree type, tree value)
{
  if (value == NULL_TREE)
    return value;

  value = mark_rvalue_use (value);

  if (cxx_dialect >= cxx11
      && (SCOPED_ENUM_P (type)
	  || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
    {
      if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
	type = type_promotes_to (type);
      value = (perform_implicit_conversion_flags
	       (type, value, tf_warning_or_error,
		LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
    }
  return cxx_constant_value (value);
}

/* Note that we've seen a definition of a case label, and complain if this
   is a bad place for one.  */

tree
finish_case_label (location_t loc, tree low_value, tree high_value)
{
  tree cond, r;
  cp_binding_level *p;
  tree type;

  if (low_value == NULL_TREE && high_value == NULL_TREE)
    switch_stack->has_default_p = true;

  if (processing_template_decl)
    {
      tree label;

      /* For templates, just add the case label; we'll do semantic
	 analysis at instantiation-time.  */
      label = build_decl (loc, LABEL_DECL, NULL_TREE, void_type_node);
      return add_stmt (build_case_label (low_value, high_value, label));
    }

  /* Find the condition on which this switch statement depends.  */
  cond = SWITCH_STMT_COND (switch_stack->switch_stmt);
  if (cond && TREE_CODE (cond) == TREE_LIST)
    cond = TREE_VALUE (cond);

  if (!check_switch_goto (switch_stack->level))
    return error_mark_node;

  type = SWITCH_STMT_TYPE (switch_stack->switch_stmt);
  if (type == error_mark_node)
    return error_mark_node;

  low_value = case_conversion (type, low_value);
  high_value = case_conversion (type, high_value);

  r = c_add_case_label (loc, switch_stack->cases, cond, type,
			low_value, high_value,
			&switch_stack->outside_range_p);

  /* After labels, make any new cleanups in the function go into their
     own new (temporary) binding contour.  */
  for (p = current_binding_level;
       p->kind != sk_function_parms;
       p = p->level_chain)
    p->more_cleanups_ok = 0;

  return r;
}

struct typename_info {
  tree scope;
  tree name;
  tree template_id;
  bool enum_p;
  bool class_p;
};

struct typename_hasher : ggc_ptr_hash<tree_node>
{
  typedef typename_info *compare_type;

  /* Hash a TYPENAME_TYPE.  */

  static hashval_t
  hash (tree t)
  {
    hashval_t hash;

    hash = (htab_hash_pointer (TYPE_CONTEXT (t))
	    ^ htab_hash_pointer (TYPE_IDENTIFIER (t)));

    return hash;
  }

  /* Compare two TYPENAME_TYPEs.  */

  static bool
  equal (tree t1, const typename_info *t2)
  {
    return (TYPE_IDENTIFIER (t1) == t2->name
	    && TYPE_CONTEXT (t1) == t2->scope
	    && TYPENAME_TYPE_FULLNAME (t1) == t2->template_id
	    && TYPENAME_IS_ENUM_P (t1) == t2->enum_p
	    && TYPENAME_IS_CLASS_P (t1) == t2->class_p);
  }
};

/* Build a TYPENAME_TYPE.  If the type is `typename T::t', CONTEXT is
   the type of `T', NAME is the IDENTIFIER_NODE for `t'.

   Returns the new TYPENAME_TYPE.  */

static GTY (()) hash_table<typename_hasher> *typename_htab;

tree
build_typename_type (tree context, tree name, tree fullname,
		     enum tag_types tag_type)
{
  tree t;
  tree d;
  typename_info ti;
  tree *e;
  hashval_t hash;

  if (typename_htab == NULL)
    typename_htab = hash_table<typename_hasher>::create_ggc (61);

  ti.scope = FROB_CONTEXT (context);
  ti.name = name;
  ti.template_id = fullname;
  ti.enum_p = tag_type == enum_type;
  ti.class_p = (tag_type == class_type
		|| tag_type == record_type
		|| tag_type == union_type);
  hash =  (htab_hash_pointer (ti.scope)
	   ^ htab_hash_pointer (ti.name));

  /* See if we already have this type.  */
  e = typename_htab->find_slot_with_hash (&ti, hash, INSERT);
  if (*e)
    t = *e;
  else
    {
      /* Build the TYPENAME_TYPE.  */
      t = cxx_make_type (TYPENAME_TYPE);
      TYPE_CONTEXT (t) = ti.scope;
      TYPENAME_TYPE_FULLNAME (t) = ti.template_id;
      TYPENAME_IS_ENUM_P (t) = ti.enum_p;
      TYPENAME_IS_CLASS_P (t) = ti.class_p;

      /* Build the corresponding TYPE_DECL.  */
      d = build_decl (input_location, TYPE_DECL, name, t);
      TYPE_NAME (TREE_TYPE (d)) = d;
      TYPE_STUB_DECL (TREE_TYPE (d)) = d;
      DECL_CONTEXT (d) = FROB_CONTEXT (context);
      DECL_ARTIFICIAL (d) = 1;

      /* Store it in the hash table.  */
      *e = t;

      /* TYPENAME_TYPEs must always be compared structurally, because
	 they may or may not resolve down to another type depending on
	 the currently open classes. */
      SET_TYPE_STRUCTURAL_EQUALITY (t);
    }

  return t;
}

/* Resolve `typename CONTEXT::NAME'.  TAG_TYPE indicates the tag
   provided to name the type.  Returns an appropriate type, unless an
   error occurs, in which case error_mark_node is returned.  If we
   locate a non-artificial TYPE_DECL and TF_KEEP_TYPE_DECL is set, we
   return that, rather than the _TYPE it corresponds to, in other
   cases we look through the type decl.  If TF_ERROR is set, complain
   about errors, otherwise be quiet.  */

tree
make_typename_type (tree context, tree name, enum tag_types tag_type,
		    tsubst_flags_t complain)
{
  tree fullname;
  tree t;
  bool want_template;

  if (name == error_mark_node
      || context == NULL_TREE
      || context == error_mark_node)
    return error_mark_node;

  if (TYPE_P (name))
    {
      if (!(TYPE_LANG_SPECIFIC (name)
	    && (CLASSTYPE_IS_TEMPLATE (name)
		|| CLASSTYPE_USE_TEMPLATE (name))))
	name = TYPE_IDENTIFIER (name);
      else
	/* Create a TEMPLATE_ID_EXPR for the type.  */
	name = build_nt (TEMPLATE_ID_EXPR,
			 CLASSTYPE_TI_TEMPLATE (name),
			 CLASSTYPE_TI_ARGS (name));
    }
  else if (TREE_CODE (name) == TYPE_DECL)
    name = DECL_NAME (name);

  fullname = name;

  if (TREE_CODE (name) == TEMPLATE_ID_EXPR)
    {
      name = TREE_OPERAND (name, 0);
      if (DECL_TYPE_TEMPLATE_P (name))
	name = TREE_OPERAND (fullname, 0) = DECL_NAME (name);
      if (TREE_CODE (name) != IDENTIFIER_NODE)
	{
	  if (complain & tf_error)
	    error ("%qD is not a type", name);
	  return error_mark_node;
	}
    }
  if (TREE_CODE (name) == TEMPLATE_DECL)
    {
      if (complain & tf_error)
	error ("%qD used without template arguments", name);
      return error_mark_node;
    }
  gcc_assert (identifier_p (name));
  gcc_assert (TYPE_P (context));

  if (!MAYBE_CLASS_TYPE_P (context))
    {
      if (complain & tf_error)
	error ("%q#T is not a class", context);
      return error_mark_node;
    }
  
  /* When the CONTEXT is a dependent type,  NAME could refer to a
     dependent base class of CONTEXT.  But look inside it anyway
     if CONTEXT is a currently open scope, in case it refers to a
     member of the current instantiation or a non-dependent base;
     lookup will stop when we hit a dependent base.  */
  if (!dependent_scope_p (context))
    /* We should only set WANT_TYPE when we're a nested typename type.
       Then we can give better diagnostics if we find a non-type.  */
    t = lookup_field (context, name, 2, /*want_type=*/true);
  else
    t = NULL_TREE;

  if ((!t || TREE_CODE (t) == TREE_LIST) && dependent_type_p (context))
    return build_typename_type (context, name, fullname, tag_type);

  want_template = TREE_CODE (fullname) == TEMPLATE_ID_EXPR;
  
  if (!t)
    {
      if (complain & tf_error)
	{
	  if (!COMPLETE_TYPE_P (context))
	    cxx_incomplete_type_error (NULL_TREE, context);
	  else
	    error (want_template ? G_("no class template named %q#T in %q#T")
		   : G_("no type named %q#T in %q#T"), name, context);
	}
      return error_mark_node;
    }
  
  /* Pull out the template from an injected-class-name (or multiple).  */
  if (want_template)
    t = maybe_get_template_decl_from_type_decl (t);

  if (TREE_CODE (t) == TREE_LIST)
    {
      if (complain & tf_error)
	{
	  error ("lookup of %qT in %qT is ambiguous", name, context);
	  print_candidates (t);
	}
      return error_mark_node;
    }

  if (want_template && !DECL_TYPE_TEMPLATE_P (t))
    {
      if (complain & tf_error)
	error ("%<typename %T::%D%> names %q#T, which is not a class template",
	       context, name, t);
      return error_mark_node;
    }
  if (!want_template && TREE_CODE (t) != TYPE_DECL)
    {
      if (complain & tf_error)
	error ("%<typename %T::%D%> names %q#T, which is not a type",
	       context, name, t);
      return error_mark_node;
    }

  if (!perform_or_defer_access_check (TYPE_BINFO (context), t, t, complain))
    return error_mark_node;

  /* If we are currently parsing a template and if T is a typedef accessed
     through CONTEXT then we need to remember and check access of T at
     template instantiation time.  */
  add_typedef_to_current_template_for_access_check (t, context, input_location);

  if (want_template)
    return lookup_template_class (t, TREE_OPERAND (fullname, 1),
				  NULL_TREE, context,
				  /*entering_scope=*/0,
				  complain | tf_user);
  
  if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
    t = TREE_TYPE (t);

  maybe_record_typedef_use (t);

  return t;
}

/* Resolve `CONTEXT::template NAME'.  Returns a TEMPLATE_DECL if the name
   can be resolved or an UNBOUND_CLASS_TEMPLATE, unless an error occurs,
   in which case error_mark_node is returned.

   If PARM_LIST is non-NULL, also make sure that the template parameter
   list of TEMPLATE_DECL matches.

   If COMPLAIN zero, don't complain about any errors that occur.  */

tree
make_unbound_class_template (tree context, tree name, tree parm_list,
			     tsubst_flags_t complain)
{
  tree t;
  tree d;

  if (TYPE_P (name))
    name = TYPE_IDENTIFIER (name);
  else if (DECL_P (name))
    name = DECL_NAME (name);
  gcc_assert (identifier_p (name));

  if (!dependent_type_p (context)
      || currently_open_class (context))
    {
      tree tmpl = NULL_TREE;

      if (MAYBE_CLASS_TYPE_P (context))
	tmpl = lookup_field (context, name, 0, false);

      if (tmpl && TREE_CODE (tmpl) == TYPE_DECL)
	tmpl = maybe_get_template_decl_from_type_decl (tmpl);

      if (!tmpl || !DECL_TYPE_TEMPLATE_P (tmpl))
	{
	  if (complain & tf_error)
	    error ("no class template named %q#T in %q#T", name, context);
	  return error_mark_node;
	}

      if (parm_list
	  && !comp_template_parms (DECL_TEMPLATE_PARMS (tmpl), parm_list))
	{
	  if (complain & tf_error)
	    {
	      error ("template parameters do not match template %qD", tmpl);
	      inform (DECL_SOURCE_LOCATION (tmpl),
		      "%qD declared here", tmpl);
	    }
	  return error_mark_node;
	}

      if (!perform_or_defer_access_check (TYPE_BINFO (context), tmpl, tmpl,
					  complain))
	return error_mark_node;

      return tmpl;
    }

  /* Build the UNBOUND_CLASS_TEMPLATE.  */
  t = cxx_make_type (UNBOUND_CLASS_TEMPLATE);
  TYPE_CONTEXT (t) = FROB_CONTEXT (context);
  TREE_TYPE (t) = NULL_TREE;
  SET_TYPE_STRUCTURAL_EQUALITY (t);

  /* Build the corresponding TEMPLATE_DECL.  */
  d = build_decl (input_location, TEMPLATE_DECL, name, t);
  TYPE_NAME (TREE_TYPE (d)) = d;
  TYPE_STUB_DECL (TREE_TYPE (d)) = d;
  DECL_CONTEXT (d) = FROB_CONTEXT (context);
  DECL_ARTIFICIAL (d) = 1;
  DECL_TEMPLATE_PARMS (d) = parm_list;

  return t;
}



/* Push the declarations of builtin types into the global namespace.
   RID_INDEX is the index of the builtin type in the array
   RID_POINTERS.  NAME is the name used when looking up the builtin
   type.  TYPE is the _TYPE node for the builtin type.

   The calls to set_global_binding below should be
   eliminated.  Built-in types should not be looked up name; their
   names are keywords that the parser can recognize.  However, there
   is code in c-common.c that uses identifier_global_value to look up
   built-in types by name.  */

void
record_builtin_type (enum rid rid_index,
		     const char* name,
		     tree type)
{
  tree decl = NULL_TREE;

  if (name)
    {
      tree tname = get_identifier (name);
      tree tdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, tname, type);
      DECL_ARTIFICIAL (tdecl) = 1;
      set_global_binding (tdecl);
      decl = tdecl;
    }

  if ((int) rid_index < (int) RID_MAX)
    if (tree rname = ridpointers[(int) rid_index])
      if (!decl || DECL_NAME (decl) != rname)
	{
	  tree rdecl = build_decl (BUILTINS_LOCATION, TYPE_DECL, rname, type);
	  DECL_ARTIFICIAL (rdecl) = 1;
	  set_global_binding (rdecl);
	  if (!decl)
	    decl = rdecl;
	}

  if (decl)
    {
      if (!TYPE_NAME (type))
	TYPE_NAME (type) = decl;
      debug_hooks->type_decl (decl, 0);
    }
}

/* Push a type into the namespace so that the back ends ignore it.  */

static void
record_unknown_type (tree type, const char* name)
{
  tree decl = pushdecl (build_decl (UNKNOWN_LOCATION,
				    TYPE_DECL, get_identifier (name), type));
  /* Make sure the "unknown type" typedecl gets ignored for debug info.  */
  DECL_IGNORED_P (decl) = 1;
  TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;
  TYPE_SIZE (type) = TYPE_SIZE (void_type_node);
  SET_TYPE_ALIGN (type, 1);
  TYPE_USER_ALIGN (type) = 0;
  SET_TYPE_MODE (type, TYPE_MODE (void_type_node));
}

/* Create all the predefined identifiers.  */

static void
initialize_predefined_identifiers (void)
{
  struct predefined_identifier
  {
    const char *name; /* Name.  */
    tree *node;  /* Node to store it in.  */
    cp_identifier_kind kind;  /* Kind of identifier.  */
  };

  /* A table of identifiers to create at startup.  */
  static const predefined_identifier predefined_identifiers[] = {
    {"C++", &lang_name_cplusplus, cik_normal},
    {"C", &lang_name_c, cik_normal},
    /* Some of these names have a trailing space so that it is
       impossible for them to conflict with names written by users.  */
    {"__ct ", &ctor_identifier, cik_ctor},
    {"__ct_base ", &base_ctor_identifier, cik_ctor},
    {"__ct_comp ", &complete_ctor_identifier, cik_ctor},
    {"__dt ", &dtor_identifier, cik_dtor},
    {"__dt_base ", &base_dtor_identifier, cik_dtor},
    {"__dt_comp ", &complete_dtor_identifier, cik_dtor},
    {"__dt_del ", &deleting_dtor_identifier, cik_dtor},
    {"__conv_op ", &conv_op_identifier, cik_conv_op},
    {"__in_chrg", &in_charge_identifier, cik_normal},
    {"this", &this_identifier, cik_normal},
    {"__delta", &delta_identifier, cik_normal},
    {"__pfn", &pfn_identifier, cik_normal},
    {"_vptr", &vptr_identifier, cik_normal},
    {"__vtt_parm", &vtt_parm_identifier, cik_normal},
    {"::", &global_identifier, cik_normal},
    {"std", &std_identifier, cik_normal},
      /* The demangler expects anonymous namespaces to be called
	 something starting with '_GLOBAL__N_'.  It no longer needs
	 to be unique to the TU.  */
    {"_GLOBAL__N_1", &anon_identifier, cik_normal},
    {"auto", &auto_identifier, cik_normal},
    {"decltype(auto)", &decltype_auto_identifier, cik_normal},
    {"initializer_list", &init_list_identifier, cik_normal},
    {"__for_range ", &for_range__identifier, cik_normal},
    {"__for_begin ", &for_begin__identifier, cik_normal},
    {"__for_end ", &for_end__identifier, cik_normal},
    {"__for_range", &for_range_identifier, cik_normal},
    {"__for_begin", &for_begin_identifier, cik_normal},
    {"__for_end", &for_end_identifier, cik_normal},
    {"abi_tag", &abi_tag_identifier, cik_normal},
    {"aligned", &aligned_identifier, cik_normal},
    {"begin", &begin_identifier, cik_normal},
    {"end", &end_identifier, cik_normal},
    {"get", &get__identifier, cik_normal},
    {"gnu", &gnu_identifier, cik_normal},
    {"tuple_element", &tuple_element_identifier, cik_normal},
    {"tuple_size", &tuple_size_identifier, cik_normal},
    {"type", &type_identifier, cik_normal},
    {"value", &value_identifier, cik_normal},
    {"_FUN", &fun_identifier, cik_normal},
    {"__closure", &closure_identifier, cik_normal},
    {NULL, NULL, cik_normal}
  };

  for (const predefined_identifier *pid = predefined_identifiers;
       pid->name; ++pid)
    {
      *pid->node = get_identifier (pid->name);
      /* Some of these identifiers already have a special kind.  */
      if (pid->kind != cik_normal)
	set_identifier_kind (*pid->node, pid->kind);
    }
}

/* Create the predefined scalar types of C,
   and some nodes representing standard constants (0, 1, (void *)0).
   Initialize the global binding level.
   Make definitions for built-in primitive functions.  */

void
cxx_init_decl_processing (void)
{
  tree void_ftype;
  tree void_ftype_ptr;

  /* Create all the identifiers we need.  */
  initialize_predefined_identifiers ();

  /* Create the global variables.  */
  push_to_top_level ();

  current_function_decl = NULL_TREE;
  current_binding_level = NULL;
  /* Enter the global namespace.  */
  gcc_assert (global_namespace == NULL_TREE);
  global_namespace = build_lang_decl (NAMESPACE_DECL, global_identifier,
				      void_type_node);
  TREE_PUBLIC (global_namespace) = 1;
  DECL_CONTEXT (global_namespace)
    = build_translation_unit_decl (get_identifier (main_input_filename));
  /* Remember whether we want the empty class passing ABI change warning
     in this TU.  */
  TRANSLATION_UNIT_WARN_EMPTY_P (DECL_CONTEXT (global_namespace))
    = warn_abi && abi_version_crosses (12);
  debug_hooks->register_main_translation_unit
    (DECL_CONTEXT (global_namespace));
  begin_scope (sk_namespace, global_namespace);
  current_namespace = global_namespace;

  if (flag_visibility_ms_compat)
    default_visibility = VISIBILITY_HIDDEN;

  /* Initially, C.  */
  current_lang_name = lang_name_c;

  /* Create the `std' namespace.  */
  push_namespace (std_identifier);
  std_node = current_namespace;
  pop_namespace ();

  flag_noexcept_type = (cxx_dialect >= cxx17);

  c_common_nodes_and_builtins ();

  tree bool_ftype = build_function_type_list (boolean_type_node, NULL_TREE);
  tree decl
    = add_builtin_function ("__builtin_is_constant_evaluated",
			    bool_ftype, CP_BUILT_IN_IS_CONSTANT_EVALUATED,
			    BUILT_IN_FRONTEND, NULL, NULL_TREE);
  set_call_expr_flags (decl, ECF_CONST | ECF_NOTHROW | ECF_LEAF);

  integer_two_node = build_int_cst (NULL_TREE, 2);

  /* Guess at the initial static decls size.  */
  vec_alloc (static_decls, 500);

  /* ... and keyed classes.  */
  vec_alloc (keyed_classes, 100);

  record_builtin_type (RID_BOOL, "bool", boolean_type_node);
  truthvalue_type_node = boolean_type_node;
  truthvalue_false_node = boolean_false_node;
  truthvalue_true_node = boolean_true_node;

  empty_except_spec = build_tree_list (NULL_TREE, NULL_TREE);
  noexcept_true_spec = build_tree_list (boolean_true_node, NULL_TREE);
  noexcept_false_spec = build_tree_list (boolean_false_node, NULL_TREE);
  noexcept_deferred_spec = build_tree_list (make_node (DEFERRED_NOEXCEPT),
					    NULL_TREE);

#if 0
  record_builtin_type (RID_MAX, NULL, string_type_node);
#endif

  delta_type_node = ptrdiff_type_node;
  vtable_index_type = ptrdiff_type_node;

  vtt_parm_type = build_pointer_type (const_ptr_type_node);
  void_ftype = build_function_type_list (void_type_node, NULL_TREE);
  void_ftype_ptr = build_function_type_list (void_type_node,
					     ptr_type_node, NULL_TREE);
  void_ftype_ptr
    = build_exception_variant (void_ftype_ptr, empty_except_spec);

  /* Create the conversion operator marker.  This operator's DECL_NAME
     is in the identifier table, so we can use identifier equality to
     find it.  */
  conv_op_marker = build_lang_decl (FUNCTION_DECL, conv_op_identifier,
				    void_ftype);

  /* C++ extensions */

  unknown_type_node = make_node (LANG_TYPE);
  record_unknown_type (unknown_type_node, "unknown type");

  /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node.  */
  TREE_TYPE (unknown_type_node) = unknown_type_node;

  /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same
     result.  */
  TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
  TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;

  init_list_type_node = make_node (LANG_TYPE);
  record_unknown_type (init_list_type_node, "init list");

  {
    /* Make sure we get a unique function type, so we can give
       its pointer type a name.  (This wins for gdb.) */
    tree vfunc_type = make_node (FUNCTION_TYPE);
    TREE_TYPE (vfunc_type) = integer_type_node;
    TYPE_ARG_TYPES (vfunc_type) = NULL_TREE;
    layout_type (vfunc_type);

    vtable_entry_type = build_pointer_type (vfunc_type);
  }
  record_builtin_type (RID_MAX, "__vtbl_ptr_type", vtable_entry_type);

  vtbl_type_node
    = build_cplus_array_type (vtable_entry_type, NULL_TREE);
  layout_type (vtbl_type_node);
  vtbl_type_node = cp_build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST);
  record_builtin_type (RID_MAX, NULL, vtbl_type_node);
  vtbl_ptr_type_node = build_pointer_type (vtable_entry_type);
  layout_type (vtbl_ptr_type_node);
  record_builtin_type (RID_MAX, NULL, vtbl_ptr_type_node);

  push_namespace (get_identifier ("__cxxabiv1"));
  abi_node = current_namespace;
  pop_namespace ();

  global_type_node = make_node (LANG_TYPE);
  record_unknown_type (global_type_node, "global type");

  any_targ_node = make_node (LANG_TYPE);
  record_unknown_type (any_targ_node, "any type");

  /* Now, C++.  */
  current_lang_name = lang_name_cplusplus;

  if (aligned_new_threshold > 1
      && !pow2p_hwi (aligned_new_threshold))
    {
      error ("-faligned-new=%d is not a power of two", aligned_new_threshold);
      aligned_new_threshold = 1;
    }
  if (aligned_new_threshold == -1)
    aligned_new_threshold = (cxx_dialect >= cxx17) ? 1 : 0;
  if (aligned_new_threshold == 1)
    aligned_new_threshold = malloc_alignment () / BITS_PER_UNIT;

  {
    tree newattrs, extvisattr;
    tree newtype, deltype;
    tree ptr_ftype_sizetype;
    tree new_eh_spec;

    ptr_ftype_sizetype
      = build_function_type_list (ptr_type_node, size_type_node, NULL_TREE);
    if (cxx_dialect == cxx98)
      {
	tree bad_alloc_id;
	tree bad_alloc_type_node;
	tree bad_alloc_decl;

	push_namespace (std_identifier);
	bad_alloc_id = get_identifier ("bad_alloc");
	bad_alloc_type_node = make_class_type (RECORD_TYPE);
	TYPE_CONTEXT (bad_alloc_type_node) = current_namespace;
	bad_alloc_decl
	  = create_implicit_typedef (bad_alloc_id, bad_alloc_type_node);
	DECL_CONTEXT (bad_alloc_decl) = current_namespace;
	pop_namespace ();

	new_eh_spec
	  = add_exception_specifier (NULL_TREE, bad_alloc_type_node, -1);
      }
    else
      new_eh_spec = noexcept_false_spec;

    /* Ensure attribs.c is initialized.  */
    init_attributes ();

    /* Ensure constraint.cc is initialized. */
    init_constraint_processing ();

    extvisattr = build_tree_list (get_identifier ("externally_visible"),
				  NULL_TREE);
    newattrs = tree_cons (get_identifier ("alloc_size"),
			  build_tree_list (NULL_TREE, integer_one_node),
			  extvisattr);
    newtype = cp_build_type_attribute_variant (ptr_ftype_sizetype, newattrs);
    newtype = build_exception_variant (newtype, new_eh_spec);
    deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
    deltype = build_exception_variant (deltype, empty_except_spec);
    tree opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
    DECL_IS_MALLOC (opnew) = 1;
    DECL_IS_OPERATOR_NEW (opnew) = 1;
    opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
    DECL_IS_MALLOC (opnew) = 1;
    DECL_IS_OPERATOR_NEW (opnew) = 1;
    push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
    push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
    if (flag_sized_deallocation)
      {
	/* Also push the sized deallocation variants:
	     void operator delete(void*, std::size_t) throw();
	     void operator delete[](void*, std::size_t) throw();  */
	tree void_ftype_ptr_size
	  = build_function_type_list (void_type_node, ptr_type_node,
				      size_type_node, NULL_TREE);
	deltype = cp_build_type_attribute_variant (void_ftype_ptr_size,
						   extvisattr);
	deltype = build_exception_variant (deltype, empty_except_spec);
	push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
	push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
      }

    if (aligned_new_threshold)
      {
	push_namespace (std_identifier);
	tree align_id = get_identifier ("align_val_t");
	align_type_node = start_enum (align_id, NULL_TREE, size_type_node,
				      NULL_TREE, /*scoped*/true, NULL);
	pop_namespace ();

	/* operator new (size_t, align_val_t); */
	newtype = build_function_type_list (ptr_type_node, size_type_node,
					    align_type_node, NULL_TREE);
	newtype = cp_build_type_attribute_variant (newtype, newattrs);
	newtype = build_exception_variant (newtype, new_eh_spec);
	opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
	DECL_IS_MALLOC (opnew) = 1;
	DECL_IS_OPERATOR_NEW (opnew) = 1;
	opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
	DECL_IS_MALLOC (opnew) = 1;
	DECL_IS_OPERATOR_NEW (opnew) = 1;

	/* operator delete (void *, align_val_t); */
	deltype = build_function_type_list (void_type_node, ptr_type_node,
					    align_type_node, NULL_TREE);
	deltype = cp_build_type_attribute_variant (deltype, extvisattr);
	deltype = build_exception_variant (deltype, empty_except_spec);
	push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
	push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);

	if (flag_sized_deallocation)
	  {
	    /* operator delete (void *, size_t, align_val_t); */
	    deltype = build_function_type_list (void_type_node, ptr_type_node,
						size_type_node, align_type_node,
						NULL_TREE);
	    deltype = cp_build_type_attribute_variant (deltype, extvisattr);
	    deltype = build_exception_variant (deltype, empty_except_spec);
	    push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
	    push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
	  }
      }

    nullptr_type_node = make_node (NULLPTR_TYPE);
    TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
    TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode));
    TYPE_UNSIGNED (nullptr_type_node) = 1;
    TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode);
    if (abi_version_at_least (9))
      SET_TYPE_ALIGN (nullptr_type_node, GET_MODE_ALIGNMENT (ptr_mode));
    SET_TYPE_MODE (nullptr_type_node, ptr_mode);
    record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node);
    nullptr_node = build_int_cst (nullptr_type_node, 0);
  }

  abort_fndecl
    = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
			    ECF_NORETURN | ECF_NOTHROW | ECF_COLD);

  /* Perform other language dependent initializations.  */
  init_class_processing ();
  init_rtti_processing ();
  init_template_processing ();

  if (flag_exceptions)
    init_exception_processing ();

  if (! supports_one_only ())
    flag_weak = 0;

  make_fname_decl = cp_make_fname_decl;
  start_fname_decls ();

  /* Show we use EH for cleanups.  */
  if (flag_exceptions)
    using_eh_for_cleanups ();
}

/* Generate an initializer for a function naming variable from
   NAME. NAME may be NULL, to indicate a dependent name.  TYPE_P is
   filled in with the type of the init.  */

tree
cp_fname_init (const char* name, tree *type_p)
{
  tree domain = NULL_TREE;
  tree type;
  tree init = NULL_TREE;
  size_t length = 0;

  if (name)
    {
      length = strlen (name);
      domain = build_index_type (size_int (length));
      init = build_string (length + 1, name);
    }

  type = cp_build_qualified_type (char_type_node, TYPE_QUAL_CONST);
  type = build_cplus_array_type (type, domain);

  *type_p = type;

  if (init)
    TREE_TYPE (init) = type;
  else
    init = error_mark_node;

  return init;
}

/* Create the VAR_DECL for __FUNCTION__ etc. ID is the name to give
   the decl, LOC is the location to give the decl, NAME is the
   initialization string and TYPE_DEP indicates whether NAME depended
   on the type of the function. We make use of that to detect
   __PRETTY_FUNCTION__ inside a template fn. This is being done lazily
   at the point of first use, so we mustn't push the decl now.  */

static tree
cp_make_fname_decl (location_t loc, tree id, int type_dep)
{
  const char *const name = (type_dep && in_template_function ()
			    ? NULL : fname_as_string (type_dep));
  tree type;
  tree init = cp_fname_init (name, &type);
  tree decl = build_decl (loc, VAR_DECL, id, type);

  if (name)
    free (CONST_CAST (char *, name));

  /* As we're using pushdecl_with_scope, we must set the context.  */
  DECL_CONTEXT (decl) = current_function_decl;

  TREE_READONLY (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_DECLARED_CONSTEXPR_P (decl) = 1;
  TREE_STATIC (decl) = 1;

  TREE_USED (decl) = 1;

  if (init)
    {
      SET_DECL_VALUE_EXPR (decl, init);
      DECL_HAS_VALUE_EXPR_P (decl) = 1;
      /* For decl_constant_var_p.  */
      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
    }

  if (current_function_decl)
    {
      DECL_CONTEXT (decl) = current_function_decl;
      decl = pushdecl_outermost_localscope (decl);
      if (decl != error_mark_node)
	add_decl_expr (decl);
    }
  else
    {
      DECL_THIS_STATIC (decl) = true;
      pushdecl_top_level_and_finish (decl, NULL_TREE);
    }

  return decl;
}

static tree
builtin_function_1 (tree decl, tree context, bool is_global)
{
  tree          id = DECL_NAME (decl);
  const char *name = IDENTIFIER_POINTER (id);

  retrofit_lang_decl (decl);

  DECL_ARTIFICIAL (decl) = 1;
  SET_DECL_LANGUAGE (decl, lang_c);
  /* Runtime library routines are, by definition, available in an
     external shared object.  */
  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
  DECL_VISIBILITY_SPECIFIED (decl) = 1;

  DECL_CONTEXT (decl) = context;

  /* A function in the user's namespace should have an explicit
     declaration before it is used.  Mark the built-in function as
     anticipated but not actually declared.  */
  if (name[0] != '_' || name[1] != '_')
    DECL_ANTICIPATED (decl) = 1;
  else if (strncmp (name + 2, "builtin_", strlen ("builtin_")) != 0)
    {
      size_t len = strlen (name);

      /* Treat __*_chk fortification functions as anticipated as well,
	 unless they are __builtin_*.  */
      if (len > strlen ("___chk")
	  && memcmp (name + len - strlen ("_chk"),
		     "_chk", strlen ("_chk") + 1) == 0)
	DECL_ANTICIPATED (decl) = 1;
    }

  if (is_global)
    pushdecl_top_level (decl);
  else
    pushdecl (decl);

  return decl;
}

tree
cxx_builtin_function (tree decl)
{
  tree          id = DECL_NAME (decl);
  const char *name = IDENTIFIER_POINTER (id);
  /* All builtins that don't begin with an '_' should additionally
     go in the 'std' namespace.  */
  if (name[0] != '_')
    {
      tree decl2 = copy_node(decl);
      push_namespace (std_identifier);
      builtin_function_1 (decl2, std_node, false);
      pop_namespace ();
    }

  return builtin_function_1 (decl, NULL_TREE, false);
}

/* Like cxx_builtin_function, but guarantee the function is added to the global
   scope.  This is to allow function specific options to add new machine
   dependent builtins when the target ISA changes via attribute((target(...)))
   which saves space on program startup if the program does not use non-generic
   ISAs.  */

tree
cxx_builtin_function_ext_scope (tree decl)
{

  tree          id = DECL_NAME (decl);
  const char *name = IDENTIFIER_POINTER (id);
  /* All builtins that don't begin with an '_' should additionally
     go in the 'std' namespace.  */
  if (name[0] != '_')
    {
      tree decl2 = copy_node(decl);
      push_namespace (std_identifier);
      builtin_function_1 (decl2, std_node, true);
      pop_namespace ();
    }

  return builtin_function_1 (decl, NULL_TREE, true);
}

/* Generate a FUNCTION_DECL with the typical flags for a runtime library
   function.  Not called directly.  */

static tree
build_library_fn (tree name, enum tree_code operator_code, tree type,
		  int ecf_flags)
{
  tree fn = build_lang_decl (FUNCTION_DECL, name, type);
  DECL_EXTERNAL (fn) = 1;
  TREE_PUBLIC (fn) = 1;
  DECL_ARTIFICIAL (fn) = 1;
  DECL_OVERLOADED_OPERATOR_CODE_RAW (fn)
    = OVL_OP_INFO (false, operator_code)->ovl_op_code;
  SET_DECL_LANGUAGE (fn, lang_c);
  /* Runtime library routines are, by definition, available in an
     external shared object.  */
  DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
  DECL_VISIBILITY_SPECIFIED (fn) = 1;
  set_call_expr_flags (fn, ecf_flags);
  return fn;
}

/* Returns the _DECL for a library function with C++ linkage.  */

static tree
build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
		     int ecf_flags)
{
  tree fn = build_library_fn (name, operator_code, type, ecf_flags);
  DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
  SET_DECL_LANGUAGE (fn, lang_cplusplus);
  return fn;
}

/* Like build_library_fn, but takes a C string instead of an
   IDENTIFIER_NODE.  */

tree
build_library_fn_ptr (const char* name, tree type, int ecf_flags)
{
  return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
}

/* Like build_cp_library_fn, but takes a C string instead of an
   IDENTIFIER_NODE.  */

tree
build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
{
  return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
			      ecf_flags);
}

/* Like build_library_fn, but also pushes the function so that we will
   be able to find it via get_global_binding.  Also, the function
   may throw exceptions listed in RAISES.  */

tree
push_library_fn (tree name, tree type, tree raises, int ecf_flags)
{
  tree fn;

  if (raises)
    type = build_exception_variant (type, raises);

  fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
  pushdecl_top_level (fn);
  return fn;
}

/* Like build_cp_library_fn, but also pushes the function so that it
   will be found by normal lookup.  */

static tree
push_cp_library_fn (enum tree_code operator_code, tree type,
		    int ecf_flags)
{
  tree fn = build_cp_library_fn (ovl_op_identifier (false, operator_code),
				 operator_code, type, ecf_flags);
  pushdecl (fn);
  if (flag_tm)
    apply_tm_attr (fn, get_identifier ("transaction_safe"));
  return fn;
}

/* Like push_library_fn, but takes a TREE_LIST of parm types rather than
   a FUNCTION_TYPE.  */

tree
push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
{
  tree type = build_function_type (void_type_node, parmtypes);
  return push_library_fn (name, type, NULL_TREE, ecf_flags);
}

/* Like push_library_fn, but also note that this function throws
   and does not return.  Used for __throw_foo and the like.  */

tree
push_throw_library_fn (tree name, tree type)
{
  tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN | ECF_COLD);
  return fn;
}

/* When we call finish_struct for an anonymous union, we create
   default copy constructors and such.  But, an anonymous union
   shouldn't have such things; this function undoes the damage to the
   anonymous union type T.

   (The reason that we create the synthesized methods is that we don't
   distinguish `union { int i; }' from `typedef union { int i; } U'.
   The first is an anonymous union; the second is just an ordinary
   union type.)  */

void
fixup_anonymous_aggr (tree t)
{
  /* Wipe out memory of synthesized methods.  */
  TYPE_HAS_USER_CONSTRUCTOR (t) = 0;
  TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0;
  TYPE_HAS_COPY_CTOR (t) = 0;
  TYPE_HAS_CONST_COPY_CTOR (t) = 0;
  TYPE_HAS_COPY_ASSIGN (t) = 0;
  TYPE_HAS_CONST_COPY_ASSIGN (t) = 0;

  /* Splice the implicitly generated functions out of TYPE_FIELDS.  */
  for (tree probe, *prev_p = &TYPE_FIELDS (t); (probe = *prev_p);)
    if (TREE_CODE (probe) == FUNCTION_DECL && DECL_ARTIFICIAL (probe))
      *prev_p = DECL_CHAIN (probe);
    else
      prev_p = &DECL_CHAIN (probe);

  /* Anonymous aggregates cannot have fields with ctors, dtors or complex
     assignment operators (because they cannot have these methods themselves).
     For anonymous unions this is already checked because they are not allowed
     in any union, otherwise we have to check it.  */
  if (TREE_CODE (t) != UNION_TYPE)
    {
      tree field, type;

      for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL)
	  {
	    type = TREE_TYPE (field);
	    if (CLASS_TYPE_P (type))
	      {
		if (TYPE_NEEDS_CONSTRUCTING (type))
		  error ("member %q+#D with constructor not allowed "
			 "in anonymous aggregate", field);
		if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
		  error ("member %q+#D with destructor not allowed "
			 "in anonymous aggregate", field);
		if (TYPE_HAS_COMPLEX_COPY_ASSIGN (type))
		  error ("member %q+#D with copy assignment operator "
			 "not allowed in anonymous aggregate", field);
	      }
	  }
    }
}

/* Warn for an attribute located at LOCATION that appertains to the
   class type CLASS_TYPE that has not been properly placed after its
   class-key, in it class-specifier.  */

void
warn_misplaced_attr_for_class_type (location_t location,
				    tree class_type)
{
  gcc_assert (OVERLOAD_TYPE_P (class_type));

  auto_diagnostic_group d;
  if (warning_at (location, OPT_Wattributes,
		  "attribute ignored in declaration "
		  "of %q#T", class_type))
    inform (location,
	    "attribute for %q#T must follow the %qs keyword",
	    class_type, class_key_or_enum_as_string (class_type));
}

/* Make sure that a declaration with no declarator is well-formed, i.e.
   just declares a tagged type or anonymous union.

   Returns the type declared; or NULL_TREE if none.  */

tree
check_tag_decl (cp_decl_specifier_seq *declspecs,
		bool explicit_type_instantiation_p)
{
  int saw_friend = decl_spec_seq_has_spec_p (declspecs, ds_friend);
  int saw_typedef = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
  /* If a class, struct, or enum type is declared by the DECLSPECS
     (i.e, if a class-specifier, enum-specifier, or non-typename
     elaborated-type-specifier appears in the DECLSPECS),
     DECLARED_TYPE is set to the corresponding type.  */
  tree declared_type = NULL_TREE;
  bool error_p = false;

  if (declspecs->multiple_types_p)
    error ("multiple types in one declaration");
  else if (declspecs->redefined_builtin_type)
    {
      if (!in_system_header_at (input_location))
	permerror (declspecs->locations[ds_redefined_builtin_type_spec],
		   "redeclaration of C++ built-in type %qT",
		   declspecs->redefined_builtin_type);
      return NULL_TREE;
    }

  if (declspecs->type
      && TYPE_P (declspecs->type)
      && ((TREE_CODE (declspecs->type) != TYPENAME_TYPE
	   && MAYBE_CLASS_TYPE_P (declspecs->type))
	  || TREE_CODE (declspecs->type) == ENUMERAL_TYPE))
    declared_type = declspecs->type;
  else if (declspecs->type == error_mark_node)
    error_p = true;
  if (declared_type == NULL_TREE && ! saw_friend && !error_p)
    permerror (input_location, "declaration does not declare anything");
  else if (declared_type != NULL_TREE && type_uses_auto (declared_type))
    {
      error_at (declspecs->locations[ds_type_spec],
		"%<auto%> can only be specified for variables "
		"or function declarations");
      return error_mark_node;
    }
  /* Check for an anonymous union.  */
  else if (declared_type && RECORD_OR_UNION_CODE_P (TREE_CODE (declared_type))
	   && TYPE_UNNAMED_P (declared_type))
    {
      /* 7/3 In a simple-declaration, the optional init-declarator-list
	 can be omitted only when declaring a class (clause 9) or
	 enumeration (7.2), that is, when the decl-specifier-seq contains
	 either a class-specifier, an elaborated-type-specifier with
	 a class-key (9.1), or an enum-specifier.  In these cases and
	 whenever a class-specifier or enum-specifier is present in the
	 decl-specifier-seq, the identifiers in these specifiers are among
	 the names being declared by the declaration (as class-name,
	 enum-names, or enumerators, depending on the syntax).  In such
	 cases, and except for the declaration of an unnamed bit-field (9.6),
	 the decl-specifier-seq shall introduce one or more names into the
	 program, or shall redeclare a name introduced by a previous
	 declaration.  [Example:
	     enum { };			// ill-formed
	     typedef class { };		// ill-formed
	 --end example]  */
      if (saw_typedef)
	{
	  error ("missing type-name in typedef-declaration");
	  return NULL_TREE;
	}
      /* Anonymous unions are objects, so they can have specifiers.  */;
      SET_ANON_AGGR_TYPE_P (declared_type);

      if (TREE_CODE (declared_type) != UNION_TYPE
	  && !in_system_header_at (input_location))
	pedwarn (input_location, OPT_Wpedantic, "ISO C++ prohibits anonymous structs");
    }

  else
    {
      if (decl_spec_seq_has_spec_p (declspecs, ds_inline))
	error_at (declspecs->locations[ds_inline],
		  "%<inline%> can only be specified for functions");
      else if (decl_spec_seq_has_spec_p (declspecs, ds_virtual))
	error_at (declspecs->locations[ds_virtual],
		  "%<virtual%> can only be specified for functions");
      else if (saw_friend
	       && (!current_class_type
		   || current_scope () != current_class_type))
	error_at (declspecs->locations[ds_friend],
		  "%<friend%> can only be specified inside a class");
      else if (decl_spec_seq_has_spec_p (declspecs, ds_explicit))
	error_at (declspecs->locations[ds_explicit],
		  "%<explicit%> can only be specified for constructors");
      else if (declspecs->storage_class)
	error_at (declspecs->locations[ds_storage_class],
		  "a storage class can only be specified for objects "
		  "and functions");
      else if (decl_spec_seq_has_spec_p (declspecs, ds_const))
	error_at (declspecs->locations[ds_const],
		  "%<const%> can only be specified for objects and "
		  "functions");
      else if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
	error_at (declspecs->locations[ds_volatile],
		  "%<volatile%> can only be specified for objects and "
		  "functions");
      else if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
	error_at (declspecs->locations[ds_restrict],
		  "%<__restrict%> can only be specified for objects and "
		  "functions");
      else if (decl_spec_seq_has_spec_p (declspecs, ds_thread))
	error_at (declspecs->locations[ds_thread],
		  "%<__thread%> can only be specified for objects "
		  "and functions");
      else if (saw_typedef)
	warning_at (declspecs->locations[ds_typedef], 0,
		    "%<typedef%> was ignored in this declaration");
      else if (decl_spec_seq_has_spec_p (declspecs,  ds_constexpr))
        error_at (declspecs->locations[ds_constexpr],
		  "%<constexpr%> cannot be used for type declarations");
    }

  if (declspecs->attributes && warn_attributes && declared_type)
    {
      location_t loc;
      if (!CLASS_TYPE_P (declared_type)
	  || !CLASSTYPE_TEMPLATE_INSTANTIATION (declared_type))
	/* For a non-template class, use the name location.  */
	loc = location_of (declared_type);
      else
	/* For a template class (an explicit instantiation), use the
	   current location.  */
	loc = input_location;

      if (explicit_type_instantiation_p)
	/* [dcl.attr.grammar]/4:

	       No attribute-specifier-seq shall appertain to an explicit
	       instantiation.  */
	{
	  if (warning_at (loc, OPT_Wattributes,
			  "attribute ignored in explicit instantiation %q#T",
			  declared_type))
	    inform (loc,
		    "no attribute can be applied to "
		    "an explicit instantiation");
	}
      else
	warn_misplaced_attr_for_class_type (loc, declared_type);
    }

  return declared_type;
}

/* Called when a declaration is seen that contains no names to declare.
   If its type is a reference to a structure, union or enum inherited
   from a containing scope, shadow that tag name for the current scope
   with a forward reference.
   If its type defines a new named structure or union
   or defines an enum, it is valid but we need not do anything here.
   Otherwise, it is an error.

   C++: may have to grok the declspecs to learn about static,
   complain for anonymous unions.

   Returns the TYPE declared -- or NULL_TREE if none.  */

tree
shadow_tag (cp_decl_specifier_seq *declspecs)
{
  tree t = check_tag_decl (declspecs,
			   /*explicit_type_instantiation_p=*/false);

  if (!t)
    return NULL_TREE;

  if (maybe_process_partial_specialization (t) == error_mark_node)
    return NULL_TREE;

  /* This is where the variables in an anonymous union are
     declared.  An anonymous union declaration looks like:
     union { ... } ;
     because there is no declarator after the union, the parser
     sends that declaration here.  */
  if (ANON_AGGR_TYPE_P (t))
    {
      fixup_anonymous_aggr (t);

      if (TYPE_FIELDS (t))
	{
	  tree decl = grokdeclarator (/*declarator=*/NULL,
				      declspecs, NORMAL, 0, NULL);
	  finish_anon_union (decl);
	}
    }

  return t;
}

/* Decode a "typename", such as "int **", returning a ..._TYPE node.  */

tree
groktypename (cp_decl_specifier_seq *type_specifiers,
	      const cp_declarator *declarator,
	      bool is_template_arg)
{
  tree attrs;
  tree type;
  enum decl_context context
    = is_template_arg ? TEMPLATE_TYPE_ARG : TYPENAME;
  attrs = type_specifiers->attributes;
  type_specifiers->attributes = NULL_TREE;
  type = grokdeclarator (declarator, type_specifiers, context, 0, &attrs);
  if (attrs && type != error_mark_node)
    {
      if (CLASS_TYPE_P (type))
	warning (OPT_Wattributes, "ignoring attributes applied to class type %qT "
		 "outside of definition", type);
      else if (MAYBE_CLASS_TYPE_P (type))
	/* A template type parameter or other dependent type.  */
	warning (OPT_Wattributes, "ignoring attributes applied to dependent "
		 "type %qT without an associated declaration", type);
      else
	cplus_decl_attributes (&type, attrs, 0);
    }
  return type;
}

/* Process a DECLARATOR for a function-scope variable declaration,
   namespace-scope variable declaration, or function declaration.
   (Function definitions go through start_function; class member
   declarations appearing in the body of the class go through
   grokfield.)  The DECL corresponding to the DECLARATOR is returned.
   If an error occurs, the error_mark_node is returned instead.
   
   DECLSPECS are the decl-specifiers for the declaration.  INITIALIZED is
   SD_INITIALIZED if an explicit initializer is present, or SD_DEFAULTED
   for an explicitly defaulted function, or SD_DELETED for an explicitly
   deleted function, but 0 (SD_UNINITIALIZED) if this is a variable
   implicitly initialized via a default constructor.  ATTRIBUTES and
   PREFIX_ATTRIBUTES are GNU attributes associated with this declaration.

   The scope represented by the context of the returned DECL is pushed
   (if it is not the global namespace) and is assigned to
   *PUSHED_SCOPE_P.  The caller is then responsible for calling
   pop_scope on *PUSHED_SCOPE_P if it is set.  */

tree
start_decl (const cp_declarator *declarator,
	    cp_decl_specifier_seq *declspecs,
	    int initialized,
	    tree attributes,
	    tree prefix_attributes,
	    tree *pushed_scope_p)
{
  tree decl;
  tree context;
  bool was_public;
  int flags;
  bool alias;

  *pushed_scope_p = NULL_TREE;

  /* An object declared as __attribute__((deprecated)) suppresses
     warnings of uses of other deprecated items.  */
  if (lookup_attribute ("deprecated", attributes))
    deprecated_state = DEPRECATED_SUPPRESS;

  attributes = chainon (attributes, prefix_attributes);

  decl = grokdeclarator (declarator, declspecs, NORMAL, initialized,
			 &attributes);

  deprecated_state = DEPRECATED_NORMAL;

  if (decl == NULL_TREE || VOID_TYPE_P (decl)
      || decl == error_mark_node)
    return error_mark_node;

  context = CP_DECL_CONTEXT (decl);
  if (context != global_namespace)
    *pushed_scope_p = push_scope (context);

  /* Is it valid for this decl to have an initializer at all?
     If not, set INITIALIZED to zero, which will indirectly
     tell `cp_finish_decl' to ignore the initializer once it is parsed.  */
  if (initialized
      && TREE_CODE (decl) == TYPE_DECL)
    {
      error ("typedef %qD is initialized (use decltype instead)", decl);
      return error_mark_node;
    }

  if (initialized)
    {
      if (! toplevel_bindings_p ()
	  && DECL_EXTERNAL (decl))
	warning (0, "declaration of %q#D has %<extern%> and is initialized",
		 decl);
      DECL_EXTERNAL (decl) = 0;
      if (toplevel_bindings_p ())
	TREE_STATIC (decl) = 1;
    }
  alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) != 0;
  
  if (alias && TREE_CODE (decl) == FUNCTION_DECL)
    record_key_method_defined (decl);

  /* If this is a typedef that names the class for linkage purposes
     (7.1.3p8), apply any attributes directly to the type.  */
  if (TREE_CODE (decl) == TYPE_DECL
      && OVERLOAD_TYPE_P (TREE_TYPE (decl))
      && decl == TYPE_NAME (TYPE_MAIN_VARIANT (TREE_TYPE (decl))))
    flags = ATTR_FLAG_TYPE_IN_PLACE;
  else
    flags = 0;

  /* Set attributes here so if duplicate decl, will have proper attributes.  */
  cplus_decl_attributes (&decl, attributes, flags);

  /* Dllimported symbols cannot be defined.  Static data members (which
     can be initialized in-class and dllimported) go through grokfield,
     not here, so we don't need to exclude those decls when checking for
     a definition.  */
  if (initialized && DECL_DLLIMPORT_P (decl))
    {
      error ("definition of %q#D is marked %<dllimport%>", decl);
      DECL_DLLIMPORT_P (decl) = 0;
    }

  /* If #pragma weak was used, mark the decl weak now.  */
  if (!processing_template_decl && !DECL_DECOMPOSITION_P (decl))
    maybe_apply_pragma_weak (decl);

  if (TREE_CODE (decl) == FUNCTION_DECL
      && DECL_DECLARED_INLINE_P (decl)
      && DECL_UNINLINABLE (decl)
      && lookup_attribute ("noinline", DECL_ATTRIBUTES (decl)))
    warning_at (DECL_SOURCE_LOCATION (decl), 0,
		"inline function %qD given attribute noinline", decl);

  if (TYPE_P (context) && COMPLETE_TYPE_P (complete_type (context)))
    {
      bool this_tmpl = (processing_template_decl
			> template_class_depth (context));
      if (VAR_P (decl))
	{
	  tree field = lookup_field (context, DECL_NAME (decl), 0, false);
	  if (field == NULL_TREE
	      || !(VAR_P (field) || variable_template_p (field)))
	    error ("%q+#D is not a static data member of %q#T", decl, context);
	  else if (variable_template_p (field)
		   && (DECL_LANG_SPECIFIC (decl)
		       && DECL_TEMPLATE_SPECIALIZATION (decl)))
	    /* OK, specialization was already checked.  */;
	  else if (variable_template_p (field) && !this_tmpl)
	    {
	      error_at (DECL_SOURCE_LOCATION (decl),
			"non-member-template declaration of %qD", decl);
	      inform (DECL_SOURCE_LOCATION (field), "does not match "
		      "member template declaration here");
	      return error_mark_node;
	    }
	  else
	    {
	      if (variable_template_p (field))
		field = DECL_TEMPLATE_RESULT (field);

	      if (DECL_CONTEXT (field) != context)
		{
		  if (!same_type_p (DECL_CONTEXT (field), context))
		    permerror (input_location, "ISO C++ does not permit %<%T::%D%> "
			       "to be defined as %<%T::%D%>",
			       DECL_CONTEXT (field), DECL_NAME (decl),
			       context, DECL_NAME (decl));
		  DECL_CONTEXT (decl) = DECL_CONTEXT (field);
		}
	      /* Static data member are tricky; an in-class initialization
		 still doesn't provide a definition, so the in-class
		 declaration will have DECL_EXTERNAL set, but will have an
		 initialization.  Thus, duplicate_decls won't warn
		 about this situation, and so we check here.  */
	      if (initialized && DECL_INITIALIZED_IN_CLASS_P (field))
		error ("duplicate initialization of %qD", decl);
	      field = duplicate_decls (decl, field,
				       /*newdecl_is_friend=*/false);
	      if (field == error_mark_node)
		return error_mark_node;
	      else if (field)
		decl = field;
	    }
	}
      else
	{
	  tree field = check_classfn (context, decl,
				      this_tmpl
				      ? current_template_parms
				      : NULL_TREE);
	  if (field && field != error_mark_node
	      && duplicate_decls (decl, field,
				 /*newdecl_is_friend=*/false))
	    decl = field;
	}

      /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set.  */
      DECL_IN_AGGR_P (decl) = 0;
      /* Do not mark DECL as an explicit specialization if it was not
	 already marked as an instantiation; a declaration should
	 never be marked as a specialization unless we know what
	 template is being specialized.  */
      if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
	{
	  SET_DECL_TEMPLATE_SPECIALIZATION (decl);
	  if (TREE_CODE (decl) == FUNCTION_DECL)
	    DECL_COMDAT (decl) = (TREE_PUBLIC (decl)
				  && DECL_DECLARED_INLINE_P (decl));
	  else
	    DECL_COMDAT (decl) = false;

	  /* [temp.expl.spec] An explicit specialization of a static data
	     member of a template is a definition if the declaration
	     includes an initializer; otherwise, it is a declaration.

	     We check for processing_specialization so this only applies
	     to the new specialization syntax.  */
	  if (!initialized && processing_specialization)
	    DECL_EXTERNAL (decl) = 1;
	}

      if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)
	  /* Aliases are definitions. */
	  && !alias)
	permerror (input_location, "declaration of %q#D outside of class is not definition",
		   decl);
    }

  was_public = TREE_PUBLIC (decl);

  /* Enter this declaration into the symbol table.  Don't push the plain
     VAR_DECL for a variable template.  */
  if (!template_parm_scope_p ()
      || !VAR_P (decl))
    decl = maybe_push_decl (decl);

  if (processing_template_decl)
    decl = push_template_decl (decl);
  if (decl == error_mark_node)
    return error_mark_node;

  if (VAR_P (decl)
      && DECL_NAMESPACE_SCOPE_P (decl) && !TREE_PUBLIC (decl) && !was_public
      && !DECL_THIS_STATIC (decl) && !DECL_ARTIFICIAL (decl))
    {
      /* This is a const variable with implicit 'static'.  Set
	 DECL_THIS_STATIC so we can tell it from variables that are
	 !TREE_PUBLIC because of the anonymous namespace.  */
      gcc_assert (CP_TYPE_CONST_P (TREE_TYPE (decl)) || errorcount);
      DECL_THIS_STATIC (decl) = 1;
    }

  if (current_function_decl && VAR_P (decl)
      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
    {
      bool ok = false;
      if (CP_DECL_THREAD_LOCAL_P (decl))
	error ("%qD declared %<thread_local%> in %<constexpr%> function",
	       decl);
      else if (TREE_STATIC (decl))
	error ("%qD declared %<static%> in %<constexpr%> function", decl);
      else
	ok = true;
      if (!ok)
	cp_function_chain->invalid_constexpr = true;
    }

  if (!processing_template_decl && VAR_P (decl))
    start_decl_1 (decl, initialized);

  return decl;
}

/* Process the declaration of a variable DECL.  INITIALIZED is true
   iff DECL is explicitly initialized.  (INITIALIZED is false if the
   variable is initialized via an implicitly-called constructor.)
   This function must be called for ordinary variables (including, for
   example, implicit instantiations of templates), but must not be
   called for template declarations.  */

void
start_decl_1 (tree decl, bool initialized)
{
  tree type;
  bool complete_p;
  bool aggregate_definition_p;

  gcc_assert (!processing_template_decl);

  if (error_operand_p (decl))
    return;

  gcc_assert (VAR_P (decl));

  type = TREE_TYPE (decl);
  complete_p = COMPLETE_TYPE_P (type);
  aggregate_definition_p = MAYBE_CLASS_TYPE_P (type) && !DECL_EXTERNAL (decl);

  /* If an explicit initializer is present, or if this is a definition
     of an aggregate, then we need a complete type at this point.
     (Scalars are always complete types, so there is nothing to
     check.)  This code just sets COMPLETE_P; errors (if necessary)
     are issued below.  */
  if ((initialized || aggregate_definition_p) 
      && !complete_p
      && COMPLETE_TYPE_P (complete_type (type)))
    {
      complete_p = true;
      /* We will not yet have set TREE_READONLY on DECL if the type
	 was "const", but incomplete, before this point.  But, now, we
	 have a complete type, so we can try again.  */
      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
    }

  if (initialized)
    /* Is it valid for this decl to have an initializer at all?  */
    {
      /* Don't allow initializations for incomplete types except for
	 arrays which might be completed by the initialization.  */
      if (complete_p)
	;			/* A complete type is ok.  */
      else if (type_uses_auto (type))
	; 			/* An auto type is ok.  */
      else if (TREE_CODE (type) != ARRAY_TYPE)
	{
	  error ("variable %q#D has initializer but incomplete type", decl);
	  type = TREE_TYPE (decl) = error_mark_node;
	}
      else if (!COMPLETE_TYPE_P (complete_type (TREE_TYPE (type))))
	{
	  if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl))
	    error ("elements of array %q#D have incomplete type", decl);
	  /* else we already gave an error in start_decl.  */
	}
    }
  else if (aggregate_definition_p && !complete_p)
    {
      if (type_uses_auto (type))
	gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (type));
      else
	{
	  error ("aggregate %q#D has incomplete type and cannot be defined",
		 decl);
	  /* Change the type so that assemble_variable will give
	     DECL an rtl we can live with: (mem (const_int 0)).  */
	  type = TREE_TYPE (decl) = error_mark_node;
	}
    }

  /* Create a new scope to hold this declaration if necessary.
     Whether or not a new scope is necessary cannot be determined
     until after the type has been completed; if the type is a
     specialization of a class template it is not until after
     instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
     will be set correctly.  */
  maybe_push_cleanup_level (type);
}

/* Handle initialization of references.  DECL, TYPE, and INIT have the
   same meaning as in cp_finish_decl.  *CLEANUP must be NULL on entry,
   but will be set to a new CLEANUP_STMT if a temporary is created
   that must be destroyed subsequently.

   Returns an initializer expression to use to initialize DECL, or
   NULL if the initialization can be performed statically.

   Quotes on semantics can be found in ARM 8.4.3.  */

static tree
grok_reference_init (tree decl, tree type, tree init, int flags)
{
  if (init == NULL_TREE)
    {
      if ((DECL_LANG_SPECIFIC (decl) == 0
	   || DECL_IN_AGGR_P (decl) == 0)
	  && ! DECL_THIS_EXTERN (decl))
	error ("%qD declared as reference but not initialized", decl);
      return NULL_TREE;
    }

  if (TREE_CODE (init) == TREE_LIST)
    init = build_x_compound_expr_from_list (init, ELK_INIT,
					    tf_warning_or_error);

  tree ttype = TREE_TYPE (type);
  if (TREE_CODE (ttype) != ARRAY_TYPE
      && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE)
    /* Note: default conversion is only called in very special cases.  */
    init = decay_conversion (init, tf_warning_or_error);

  /* check_initializer handles this for non-reference variables, but for
     references we need to do it here or the initializer will get the
     incomplete array type and confuse later calls to
     cp_complete_array_type.  */
  if (TREE_CODE (ttype) == ARRAY_TYPE
      && TYPE_DOMAIN (ttype) == NULL_TREE
      && (BRACE_ENCLOSED_INITIALIZER_P (init)
	  || TREE_CODE (init) == STRING_CST))
    {
      cp_complete_array_type (&ttype, init, false);
      if (ttype != TREE_TYPE (type))
	type = cp_build_reference_type (ttype, TYPE_REF_IS_RVALUE (type));
    }

  /* Convert INIT to the reference type TYPE.  This may involve the
     creation of a temporary, whose lifetime must be the same as that
     of the reference.  If so, a DECL_EXPR for the temporary will be
     added just after the DECL_EXPR for DECL.  That's why we don't set
     DECL_INITIAL for local references (instead assigning to them
     explicitly); we need to allow the temporary to be initialized
     first.  */
  return initialize_reference (type, init, flags,
			       tf_warning_or_error);
}

/* Designated initializers in arrays are not supported in GNU C++.
   The parser cannot detect this error since it does not know whether
   a given brace-enclosed initializer is for a class type or for an
   array.  This function checks that CE does not use a designated
   initializer.  If it does, an error is issued.  Returns true if CE
   is valid, i.e., does not have a designated initializer.  */

bool
check_array_designated_initializer (constructor_elt *ce,
				    unsigned HOST_WIDE_INT index)
{
  /* Designated initializers for array elements are not supported.  */
  if (ce->index)
    {
      /* The parser only allows identifiers as designated
	 initializers.  */
      if (ce->index == error_mark_node)
	{
	  error ("name used in a GNU-style designated "
		 "initializer for an array");
	  return false;
	}
      else if (identifier_p (ce->index))
	{
	  error ("name %qD used in a GNU-style designated "
		 "initializer for an array", ce->index);
	  return false;
	}

      tree ce_index = build_expr_type_conversion (WANT_INT | WANT_ENUM,
						  ce->index, true);
      if (ce_index
	  && INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (ce_index))
	  && (TREE_CODE (ce_index = fold_non_dependent_expr (ce_index))
	      == INTEGER_CST))
	{
	  /* A C99 designator is OK if it matches the current index.  */
	  if (wi::to_wide (ce_index) == index)
	    {
	      ce->index = ce_index;
	      return true;
	    }
	  else
	    sorry ("non-trivial designated initializers not supported");
	}
      else
	error ("C99 designator %qE is not an integral constant-expression",
	       ce->index);

      return false;
    }

  return true;
}

/* When parsing `int a[] = {1, 2};' we don't know the size of the
   array until we finish parsing the initializer.  If that's the
   situation we're in, update DECL accordingly.  */

static void
maybe_deduce_size_from_array_init (tree decl, tree init)
{
  tree type = TREE_TYPE (decl);

  if (TREE_CODE (type) == ARRAY_TYPE
      && TYPE_DOMAIN (type) == NULL_TREE
      && TREE_CODE (decl) != TYPE_DECL)
    {
      /* do_default is really a C-ism to deal with tentative definitions.
	 But let's leave it here to ease the eventual merge.  */
      int do_default = !DECL_EXTERNAL (decl);
      tree initializer = init ? init : DECL_INITIAL (decl);
      int failure = 0;

      /* Check that there are no designated initializers in INIT, as
	 those are not supported in GNU C++, and as the middle-end
	 will crash if presented with a non-numeric designated
	 initializer.  */
      if (initializer && BRACE_ENCLOSED_INITIALIZER_P (initializer))
	{
	  vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initializer);
	  constructor_elt *ce;
	  HOST_WIDE_INT i;
	  FOR_EACH_VEC_SAFE_ELT (v, i, ce)
	    {
	      if (instantiation_dependent_expression_p (ce->index))
		return;
	      if (!check_array_designated_initializer (ce, i))
		failure = 1;
	    }
	}

      if (failure)
	TREE_TYPE (decl) = error_mark_node;
      else
	{
	  failure = cp_complete_array_type (&TREE_TYPE (decl), initializer,
					    do_default);
	  if (failure == 1)
	    {
	      error_at (cp_expr_loc_or_loc (initializer,
					 DECL_SOURCE_LOCATION (decl)),
			"initializer fails to determine size of %qD", decl);
	    }
	  else if (failure == 2)
	    {
	      if (do_default)
		{
		  error_at (DECL_SOURCE_LOCATION (decl),
			    "array size missing in %qD", decl);
		}
	      /* If a `static' var's size isn't known, make it extern as
		 well as static, so it does not get allocated.  If it's not
		 `static', then don't mark it extern; finish_incomplete_decl
		 will give it a default size and it will get allocated.  */
	      else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl))
		DECL_EXTERNAL (decl) = 1;
	    }
	  else if (failure == 3)
	    {
	      error_at (DECL_SOURCE_LOCATION (decl),
			"zero-size array %qD", decl);
	    }
	}

      cp_apply_type_quals_to_decl (cp_type_quals (TREE_TYPE (decl)), decl);

      relayout_decl (decl);
    }
}

/* Set DECL_SIZE, DECL_ALIGN, etc. for DECL (a VAR_DECL), and issue
   any appropriate error messages regarding the layout.  */

static void
layout_var_decl (tree decl)
{
  tree type;

  type = TREE_TYPE (decl);
  if (type == error_mark_node)
    return;

  /* If we haven't already laid out this declaration, do so now.
     Note that we must not call complete type for an external object
     because it's type might involve templates that we are not
     supposed to instantiate yet.  (And it's perfectly valid to say
     `extern X x' for some incomplete type `X'.)  */
  if (!DECL_EXTERNAL (decl))
    complete_type (type);
  if (!DECL_SIZE (decl)
      && TREE_TYPE (decl) != error_mark_node
      && complete_or_array_type_p (type))
    layout_decl (decl, 0);

  if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE)
    {
      /* An automatic variable with an incomplete type: that is an error.
	 Don't talk about array types here, since we took care of that
	 message in grokdeclarator.  */
      error_at (DECL_SOURCE_LOCATION (decl),
		"storage size of %qD isn%'t known", decl);
      TREE_TYPE (decl) = error_mark_node;
    }
#if 0
  /* Keep this code around in case we later want to control debug info
     based on whether a type is "used".  (jason 1999-11-11) */

  else if (!DECL_EXTERNAL (decl) && MAYBE_CLASS_TYPE_P (ttype))
    /* Let debugger know it should output info for this type.  */
    note_debug_info_needed (ttype);

  if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl))
    note_debug_info_needed (DECL_CONTEXT (decl));
#endif

  if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl))
      && DECL_SIZE (decl) != NULL_TREE
      && ! TREE_CONSTANT (DECL_SIZE (decl)))
    {
      if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST)
	constant_expression_warning (DECL_SIZE (decl));
      else
	{
	  error_at (DECL_SOURCE_LOCATION (decl),
		    "storage size of %qD isn%'t constant", decl);
	  TREE_TYPE (decl) = error_mark_node;
	}
    }
}

/* If a local static variable is declared in an inline function, or if
   we have a weak definition, we must endeavor to create only one
   instance of the variable at link-time.  */

void
maybe_commonize_var (tree decl)
{
  /* Don't mess with __FUNCTION__ and similar.  */
  if (DECL_ARTIFICIAL (decl))
    return;

  /* Static data in a function with comdat linkage also has comdat
     linkage.  */
  if ((TREE_STATIC (decl)
       && DECL_FUNCTION_SCOPE_P (decl)
       && vague_linkage_p (DECL_CONTEXT (decl)))
      || (TREE_PUBLIC (decl) && DECL_INLINE_VAR_P (decl)))
    {
      if (flag_weak)
	{
	  /* With weak symbols, we simply make the variable COMDAT;
	     that will cause copies in multiple translations units to
	     be merged.  */
	  comdat_linkage (decl);
	}
      else
	{
	  if (DECL_INITIAL (decl) == NULL_TREE
	      || DECL_INITIAL (decl) == error_mark_node)
	    {
	      /* Without weak symbols, we can use COMMON to merge
		 uninitialized variables.  */
	      TREE_PUBLIC (decl) = 1;
	      DECL_COMMON (decl) = 1;
	    }
	  else
	    {
	      /* While for initialized variables, we must use internal
		 linkage -- which means that multiple copies will not
		 be merged.  */
	      TREE_PUBLIC (decl) = 0;
	      DECL_COMMON (decl) = 0;
	      const char *msg;
	      if (DECL_INLINE_VAR_P (decl))
		msg = G_("sorry: semantics of inline variable "
			 "%q#D are wrong (you%'ll wind up with "
			 "multiple copies)");
	      else
		msg = G_("sorry: semantics of inline function "
			 "static data %q#D are wrong (you%'ll wind "
			 "up with multiple copies)");
	      if (warning_at (DECL_SOURCE_LOCATION (decl), 0,
			      msg, decl))
		inform (DECL_SOURCE_LOCATION (decl),
			"you can work around this by removing the initializer");
	    }
	}
    }
}

/* Issue an error message if DECL is an uninitialized const variable.
   CONSTEXPR_CONTEXT_P is true when the function is called in a constexpr
   context from potential_constant_expression.  Returns true if all is well,
   false otherwise.  */

bool
check_for_uninitialized_const_var (tree decl, bool constexpr_context_p,
				   tsubst_flags_t complain)
{
  tree type = strip_array_types (TREE_TYPE (decl));

  /* ``Unless explicitly declared extern, a const object does not have
     external linkage and must be initialized. ($8.4; $12.1)'' ARM
     7.1.6 */
  if (VAR_P (decl)
      && !TYPE_REF_P (type)
      && (constexpr_context_p
	  || CP_TYPE_CONST_P (type) || var_in_constexpr_fn (decl))
      && !DECL_NONTRIVIALLY_INITIALIZED_P (decl))
    {
      tree field = default_init_uninitialized_part (type);
      if (!field)
	return true;

      if (!constexpr_context_p)
	{
	  if (CP_TYPE_CONST_P (type))
	    {
	      if (complain & tf_error)
		permerror (DECL_SOURCE_LOCATION (decl),
			   "uninitialized const %qD", decl);
	    }
	  else
	    {
	      if (!is_instantiation_of_constexpr (current_function_decl)
		  && (complain & tf_error))
		error_at (DECL_SOURCE_LOCATION (decl),
			  "uninitialized variable %qD in %<constexpr%> "
			  "function", decl);
	      cp_function_chain->invalid_constexpr = true;
	    }
	}
      else if (complain & tf_error)
	error_at (DECL_SOURCE_LOCATION (decl),
		  "uninitialized variable %qD in %<constexpr%> context",
		  decl);

      if (CLASS_TYPE_P (type) && (complain & tf_error))
	{
	  tree defaulted_ctor;

	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
		  "%q#T has no user-provided default constructor", type);
	  defaulted_ctor = in_class_defaulted_default_constructor (type);
	  if (defaulted_ctor)
	    inform (DECL_SOURCE_LOCATION (defaulted_ctor),
		    "constructor is not user-provided because it is "
		    "explicitly defaulted in the class body");
	  inform (DECL_SOURCE_LOCATION (field),
		  "and the implicitly-defined constructor does not "
		  "initialize %q#D", field);
	}

      return false;
    }

  return true;
}

/* Structure holding the current initializer being processed by reshape_init.
   CUR is a pointer to the current element being processed, END is a pointer
   after the last element present in the initializer.  */
struct reshape_iter
{
  constructor_elt *cur;
  constructor_elt *end;
};

static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t);

/* FIELD is a FIELD_DECL or NULL.  In the former case, the value
   returned is the next FIELD_DECL (possibly FIELD itself) that can be
   initialized.  If there are no more such fields, the return value
   will be NULL.  */

tree
next_initializable_field (tree field)
{
  while (field
	 && (TREE_CODE (field) != FIELD_DECL
	     || DECL_UNNAMED_BIT_FIELD (field)
	     || (DECL_ARTIFICIAL (field)
		 && !(cxx_dialect >= cxx17 && DECL_FIELD_IS_BASE (field)))))
    field = DECL_CHAIN (field);

  return field;
}

/* Return true for [dcl.init.list] direct-list-initialization from
   single element of enumeration with a fixed underlying type.  */

bool
is_direct_enum_init (tree type, tree init)
{
  if (cxx_dialect >= cxx17
      && TREE_CODE (type) == ENUMERAL_TYPE
      && ENUM_FIXED_UNDERLYING_TYPE_P (type)
      && TREE_CODE (init) == CONSTRUCTOR
      && CONSTRUCTOR_IS_DIRECT_INIT (init)
      && CONSTRUCTOR_NELTS (init) == 1)
    return true;
  return false;
}

/* Subroutine of reshape_init_array and reshape_init_vector, which does
   the actual work. ELT_TYPE is the element type of the array. MAX_INDEX is an
   INTEGER_CST representing the size of the array minus one (the maximum index),
   or NULL_TREE if the array was declared without specifying the size. D is
   the iterator within the constructor.  */

static tree
reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
		      tsubst_flags_t complain)
{
  tree new_init;
  bool sized_array_p = (max_index && TREE_CONSTANT (max_index));
  unsigned HOST_WIDE_INT max_index_cst = 0;
  unsigned HOST_WIDE_INT index;

  /* The initializer for an array is always a CONSTRUCTOR.  */
  new_init = build_constructor (init_list_type_node, NULL);

  if (sized_array_p)
    {
      /* Minus 1 is used for zero sized arrays.  */
      if (integer_all_onesp (max_index))
	return new_init;

      if (tree_fits_uhwi_p (max_index))
	max_index_cst = tree_to_uhwi (max_index);
      /* sizetype is sign extended, not zero extended.  */
      else
	max_index_cst = tree_to_uhwi (fold_convert (size_type_node, max_index));
    }

  /* Loop until there are no more initializers.  */
  for (index = 0;
       d->cur != d->end && (!sized_array_p || index <= max_index_cst);
       ++index)
    {
      tree elt_init;
      constructor_elt *old_cur = d->cur;

      check_array_designated_initializer (d->cur, index);
      elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
				 complain);
      if (elt_init == error_mark_node)
	return error_mark_node;
      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
			      size_int (index), elt_init);
      if (!TREE_CONSTANT (elt_init))
	TREE_CONSTANT (new_init) = false;

      /* This can happen with an invalid initializer (c++/54501).  */
      if (d->cur == old_cur && !sized_array_p)
	break;
    }

  return new_init;
}

/* Subroutine of reshape_init_r, processes the initializers for arrays.
   Parameters are the same of reshape_init_r.  */

static tree
reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain)
{
  tree max_index = NULL_TREE;

  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);

  if (TYPE_DOMAIN (type))
    max_index = array_type_nelts (type);

  return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
}

/* Subroutine of reshape_init_r, processes the initializers for vectors.
   Parameters are the same of reshape_init_r.  */

static tree
reshape_init_vector (tree type, reshape_iter *d, tsubst_flags_t complain)
{
  tree max_index = NULL_TREE;

  gcc_assert (VECTOR_TYPE_P (type));

  if (COMPOUND_LITERAL_P (d->cur->value))
    {
      tree value = d->cur->value;
      if (!same_type_p (TREE_TYPE (value), type))
	{
	  if (complain & tf_error)
	    error ("invalid type %qT as initializer for a vector of type %qT",
		   TREE_TYPE (d->cur->value), type);
	  value = error_mark_node;
	}
      ++d->cur;
      return value;
    }

  /* For a vector, we initialize it as an array of the appropriate size.  */
  if (VECTOR_TYPE_P (type))
    max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1);

  return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
}

/* Subroutine of reshape_init_r, processes the initializers for classes
   or union. Parameters are the same of reshape_init_r.  */

static tree
reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
		    tsubst_flags_t complain)
{
  tree field;
  tree new_init;

  gcc_assert (CLASS_TYPE_P (type));

  /* The initializer for a class is always a CONSTRUCTOR.  */
  new_init = build_constructor (init_list_type_node, NULL);
  field = next_initializable_field (TYPE_FIELDS (type));

  if (!field)
    {
      /* [dcl.init.aggr]

	An initializer for an aggregate member that is an
	empty class shall have the form of an empty
	initializer-list {}.  */
      if (!first_initializer_p)
	{
	  if (complain & tf_error)
	    error ("initializer for %qT must be brace-enclosed", type);
	  return error_mark_node;
	}
      return new_init;
    }

  /* Loop through the initializable fields, gathering initializers.  */
  while (d->cur != d->end)
    {
      tree field_init;
      constructor_elt *old_cur = d->cur;

      /* Handle designated initializers, as an extension.  */
      if (d->cur->index)
	{
	  if (d->cur->index == error_mark_node)
	    return error_mark_node;

	  if (TREE_CODE (d->cur->index) == FIELD_DECL)
	    {
	      /* We already reshaped this.  */
	      if (field != d->cur->index)
		{
		  tree id = DECL_NAME (d->cur->index);
		  gcc_assert (id);
		  gcc_checking_assert (d->cur->index
				       == get_class_binding (type, id, false));
		  field = d->cur->index;
		}
	    }
	  else if (TREE_CODE (d->cur->index) == IDENTIFIER_NODE)
	    field = get_class_binding (type, d->cur->index, false);
	  else
	    {
	      if (complain & tf_error)
		error ("%<[%E] =%> used in a GNU-style designated initializer"
		       " for class %qT", d->cur->index, type);
	      return error_mark_node;
	    }

	  if (!field || TREE_CODE (field) != FIELD_DECL)
	    {
	      if (complain & tf_error)
		error ("%qT has no non-static data member named %qD", type,
		       d->cur->index);
	      return error_mark_node;
	    }
	}

      /* If we processed all the member of the class, we are done.  */
      if (!field)
	break;

      field_init = reshape_init_r (TREE_TYPE (field), d,
				   /*first_initializer_p=*/false, complain);
      if (field_init == error_mark_node)
	return error_mark_node;

      if (d->cur == old_cur && d->cur->index)
	{
	  /* This can happen with an invalid initializer for a flexible
	     array member (c++/54441).  */
	  if (complain & tf_error)
	    error ("invalid initializer for %q#D", field);
	  return error_mark_node;
	}

      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init), field, field_init);

      /* [dcl.init.aggr]

	When a union  is  initialized with a brace-enclosed
	initializer, the braces shall only contain an
	initializer for the first member of the union.  */
      if (TREE_CODE (type) == UNION_TYPE)
	break;

      field = next_initializable_field (DECL_CHAIN (field));
    }

  return new_init;
}

/* Subroutine of reshape_init_r.  We're in a context where C99 initializer
   designators are not valid; either complain or return true to indicate
   that reshape_init_r should return error_mark_node.  */

static bool
has_designator_problem (reshape_iter *d, tsubst_flags_t complain)
{
  if (d->cur->index)
    {
      if (complain & tf_error)
	error ("C99 designator %qE outside aggregate initializer",
	       d->cur->index);
      else
	return true;
    }
  return false;
}

/* Subroutine of reshape_init, which processes a single initializer (part of
   a CONSTRUCTOR). TYPE is the type of the variable being initialized, D is the
   iterator within the CONSTRUCTOR which points to the initializer to process.
   FIRST_INITIALIZER_P is true if this is the first initializer of the
   outermost CONSTRUCTOR node.  */

static tree
reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
		tsubst_flags_t complain)
{
  tree init = d->cur->value;

  if (error_operand_p (init))
    return error_mark_node;

  if (first_initializer_p && !CP_AGGREGATE_TYPE_P (type)
      && has_designator_problem (d, complain))
    return error_mark_node;

  if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      /* A complex type can be initialized from one or two initializers,
	 but braces are not elided.  */
      d->cur++;
      if (BRACE_ENCLOSED_INITIALIZER_P (init))
	{
	  if (CONSTRUCTOR_NELTS (init) > 2)
	    {
	      if (complain & tf_error)
		error ("too many initializers for %qT", type);
	      else
		return error_mark_node;
	    }
	}
      else if (first_initializer_p && d->cur != d->end)
	{
	  vec<constructor_elt, va_gc> *v = 0;
	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, init);
	  CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, d->cur->value);
	  if (has_designator_problem (d, complain))
	    return error_mark_node;
	  d->cur++;
	  init = build_constructor (init_list_type_node, v);
	}
      return init;
    }

  /* A non-aggregate type is always initialized with a single
     initializer.  */
  if (!CP_AGGREGATE_TYPE_P (type))
    {
      /* It is invalid to initialize a non-aggregate type with a
	 brace-enclosed initializer before C++0x.
	 We need to check for BRACE_ENCLOSED_INITIALIZER_P here because
	 of g++.old-deja/g++.mike/p7626.C: a pointer-to-member constant is
	 a CONSTRUCTOR (with a record type).  */
      if (TREE_CODE (init) == CONSTRUCTOR
	  /* Don't complain about a capture-init.  */
	  && !CONSTRUCTOR_IS_DIRECT_INIT (init)
	  && BRACE_ENCLOSED_INITIALIZER_P (init))  /* p7626.C */
	{
	  if (SCALAR_TYPE_P (type))
	    {
	      if (cxx_dialect < cxx11
		  /* Isn't value-initialization.  */
		  || CONSTRUCTOR_NELTS (init) > 0)
		{
		  if (complain & tf_error)
		    error ("braces around scalar initializer for type %qT",
			   type);
		  init = error_mark_node;
		}
	    }
	  else
	    maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
	}

      d->cur++;
      return init;
    }

  /* "If T is a class type and the initializer list has a single element of
     type cv U, where U is T or a class derived from T, the object is
     initialized from that element."  Even if T is an aggregate.  */
  if (cxx_dialect >= cxx11 && (CLASS_TYPE_P (type) || VECTOR_TYPE_P (type))
      && first_initializer_p
      && d->end - d->cur == 1
      && reference_related_p (type, TREE_TYPE (init)))
    {
      d->cur++;
      return init;
    }

  /* [dcl.init.aggr]

     All implicit type conversions (clause _conv_) are considered when
     initializing the aggregate member with an initializer from an
     initializer-list.  If the initializer can initialize a member,
     the member is initialized.  Otherwise, if the member is itself a
     non-empty subaggregate, brace elision is assumed and the
     initializer is considered for the initialization of the first
     member of the subaggregate.  */
  if (TREE_CODE (init) != CONSTRUCTOR
      /* But don't try this for the first initializer, since that would be
	 looking through the outermost braces; A a2 = { a1 }; is not a
	 valid aggregate initialization.  */
      && !first_initializer_p
      && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (init))
	  || can_convert_arg (type, TREE_TYPE (init), init, LOOKUP_NORMAL,
			      complain)))
    {
      d->cur++;
      return init;
    }

  /* [dcl.init.string]

      A char array (whether plain char, signed char, or unsigned char)
      can be initialized by a string-literal (optionally enclosed in
      braces); a wchar_t array can be initialized by a wide
      string-literal (optionally enclosed in braces).  */
  if (TREE_CODE (type) == ARRAY_TYPE
      && char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type))))
    {
      tree str_init = init;

      /* Strip one level of braces if and only if they enclose a single
	 element (as allowed by [dcl.init.string]).  */
      if (!first_initializer_p
	  && TREE_CODE (str_init) == CONSTRUCTOR
	  && CONSTRUCTOR_NELTS (str_init) == 1)
	{
	  str_init = (*CONSTRUCTOR_ELTS (str_init))[0].value;
	}

      /* If it's a string literal, then it's the initializer for the array
	 as a whole. Otherwise, continue with normal initialization for
	 array types (one value per array element).  */
      if (TREE_CODE (str_init) == STRING_CST)
	{
	  if (has_designator_problem (d, complain))
	    return error_mark_node;
	  d->cur++;
	  return str_init;
	}
    }

  /* The following cases are about aggregates. If we are not within a full
     initializer already, and there is not a CONSTRUCTOR, it means that there
     is a missing set of braces (that is, we are processing the case for
     which reshape_init exists).  */
  if (!first_initializer_p)
    {
      if (TREE_CODE (init) == CONSTRUCTOR)
	{
	  if (TREE_TYPE (init) && TYPE_PTRMEMFUNC_P (TREE_TYPE (init)))
	    /* There is no need to reshape pointer-to-member function
	       initializers, as they are always constructed correctly
	       by the front end.  */
           ;
	  else if (COMPOUND_LITERAL_P (init))
	  /* For a nested compound literal, there is no need to reshape since
	     brace elision is not allowed. Even if we decided to allow it,
	     we should add a call to reshape_init in finish_compound_literal,
	     before calling digest_init, so changing this code would still
	     not be necessary.  */
	    gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (init));
	  else
	    {
	      ++d->cur;
	      gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
	      return reshape_init (type, init, complain);
	    }
	}

      if (complain & tf_warning)
	warning (OPT_Wmissing_braces,
		 "missing braces around initializer for %qT",
		 type);
    }

  /* Dispatch to specialized routines.  */
  if (CLASS_TYPE_P (type))
    return reshape_init_class (type, d, first_initializer_p, complain);
  else if (TREE_CODE (type) == ARRAY_TYPE)
    return reshape_init_array (type, d, complain);
  else if (VECTOR_TYPE_P (type))
    return reshape_init_vector (type, d, complain);
  else
    gcc_unreachable();
}

/* Undo the brace-elision allowed by [dcl.init.aggr] in a
   brace-enclosed aggregate initializer.

   INIT is the CONSTRUCTOR containing the list of initializers describing
   a brace-enclosed initializer for an entity of the indicated aggregate TYPE.
   It may not presently match the shape of the TYPE; for example:

     struct S { int a; int b; };
     struct S a[] = { 1, 2, 3, 4 };

   Here INIT will hold a vector of four elements, rather than a
   vector of two elements, each itself a vector of two elements.  This
   routine transforms INIT from the former form into the latter.  The
   revised CONSTRUCTOR node is returned.  */

tree
reshape_init (tree type, tree init, tsubst_flags_t complain)
{
  vec<constructor_elt, va_gc> *v;
  reshape_iter d;
  tree new_init;

  gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));

  v = CONSTRUCTOR_ELTS (init);

  /* An empty constructor does not need reshaping, and it is always a valid
     initializer.  */
  if (vec_safe_is_empty (v))
    return init;

  /* Handle [dcl.init.list] direct-list-initialization from
     single element of enumeration with a fixed underlying type.  */
  if (is_direct_enum_init (type, init))
    {
      tree elt = CONSTRUCTOR_ELT (init, 0)->value;
      type = cv_unqualified (type);
      if (check_narrowing (ENUM_UNDERLYING_TYPE (type), elt, complain))
	{
	  warning_sentinel w (warn_useless_cast);
	  warning_sentinel w2 (warn_ignored_qualifiers);
	  return cp_build_c_cast (type, elt, tf_warning_or_error);
	}
      else
	return error_mark_node;
    }

  /* Recurse on this CONSTRUCTOR.  */
  d.cur = &(*v)[0];
  d.end = d.cur + v->length ();

  new_init = reshape_init_r (type, &d, true, complain);
  if (new_init == error_mark_node)
    return error_mark_node;

  /* Make sure all the element of the constructor were used. Otherwise,
     issue an error about exceeding initializers.  */
  if (d.cur != d.end)
    {
      if (complain & tf_error)
	error ("too many initializers for %qT", type);
      return error_mark_node;
    }

  if (CONSTRUCTOR_IS_DIRECT_INIT (init)
      && BRACE_ENCLOSED_INITIALIZER_P (new_init))
    CONSTRUCTOR_IS_DIRECT_INIT (new_init) = true;

  return new_init;
}

/* Verify array initializer.  Returns true if errors have been reported.  */

bool
check_array_initializer (tree decl, tree type, tree init)
{
  tree element_type = TREE_TYPE (type);

  /* The array type itself need not be complete, because the
     initializer may tell us how many elements are in the array.
     But, the elements of the array must be complete.  */
  if (!COMPLETE_TYPE_P (complete_type (element_type)))
    {
      if (decl)
	error_at (DECL_SOURCE_LOCATION (decl),
		  "elements of array %q#D have incomplete type", decl);
      else
	error ("elements of array %q#T have incomplete type", type);
      return true;
    }
  /* A compound literal can't have variable size.  */
  if (init && !decl
      && ((COMPLETE_TYPE_P (type) && !TREE_CONSTANT (TYPE_SIZE (type)))
	  || !TREE_CONSTANT (TYPE_SIZE (element_type))))
    {
      error ("variable-sized compound literal");
      return true;
    }
  return false;
}

/* Subroutine of check_initializer; args are passed down from that function.
   Set stmts_are_full_exprs_p to 1 across a call to build_aggr_init.  */

static tree
build_aggr_init_full_exprs (tree decl, tree init, int flags)
     
{
  gcc_assert (stmts_are_full_exprs_p ());
  return build_aggr_init (decl, init, flags, tf_warning_or_error);
}

/* Verify INIT (the initializer for DECL), and record the
   initialization in DECL_INITIAL, if appropriate.  CLEANUP is as for
   grok_reference_init.

   If the return value is non-NULL, it is an expression that must be
   evaluated dynamically to initialize DECL.  */

static tree
check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups)
{
  tree type = TREE_TYPE (decl);
  tree init_code = NULL;
  tree core_type;

  /* Things that are going to be initialized need to have complete
     type.  */
  TREE_TYPE (decl) = type = complete_type (TREE_TYPE (decl));

  if (DECL_HAS_VALUE_EXPR_P (decl))
    {
      /* A variable with DECL_HAS_VALUE_EXPR_P set is just a placeholder,
	 it doesn't have storage to be initialized.  */
      gcc_assert (init == NULL_TREE);
      return NULL_TREE;
    }

  if (type == error_mark_node)
    /* We will have already complained.  */
    return NULL_TREE;

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      if (check_array_initializer (decl, type, init))
	return NULL_TREE;
    }
  else if (!COMPLETE_TYPE_P (type))
    {
      error_at (DECL_SOURCE_LOCATION (decl),
		"%q#D has incomplete type", decl);
      TREE_TYPE (decl) = error_mark_node;
      return NULL_TREE;
    }
  else
    /* There is no way to make a variable-sized class type in GNU C++.  */
    gcc_assert (TREE_CONSTANT (TYPE_SIZE (type)));

  if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
    {
      int init_len = CONSTRUCTOR_NELTS (init);
      if (SCALAR_TYPE_P (type))
	{
	  if (init_len == 0)
	    {
	      maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
	      init = build_zero_init (type, NULL_TREE, false);
	    }
	  else if (init_len != 1 && TREE_CODE (type) != COMPLEX_TYPE)
	    {
	      error_at (cp_expr_loc_or_loc (init, DECL_SOURCE_LOCATION (decl)),
			"scalar object %qD requires one element in "
			"initializer", decl);
	      TREE_TYPE (decl) = error_mark_node;
	      return NULL_TREE;
	    }
	}
    }

  if (TREE_CODE (decl) == CONST_DECL)
    {
      gcc_assert (!TYPE_REF_P (type));

      DECL_INITIAL (decl) = init;

      gcc_assert (init != NULL_TREE);
      init = NULL_TREE;
    }
  else if (!init && DECL_REALLY_EXTERN (decl))
    ;
  else if (init || type_build_ctor_call (type)
	   || TYPE_REF_P (type))
    {
      if (TYPE_REF_P (type))
	{
	  init = grok_reference_init (decl, type, init, flags);
	  flags |= LOOKUP_ALREADY_DIGESTED;
	}
      else if (!init)
	check_for_uninitialized_const_var (decl, /*constexpr_context_p=*/false,
					   tf_warning_or_error);
      /* Do not reshape constructors of vectors (they don't need to be
	 reshaped.  */
      else if (BRACE_ENCLOSED_INITIALIZER_P (init))
	{
	  if (is_std_init_list (type))
	    {
	      init = perform_implicit_conversion (type, init,
						  tf_warning_or_error);
	      flags |= LOOKUP_ALREADY_DIGESTED;
	    }
	  else if (TYPE_NON_AGGREGATE_CLASS (type))
	    {
	      /* Don't reshape if the class has constructors.  */
	      if (cxx_dialect == cxx98)
		error_at (cp_expr_loc_or_loc (init, DECL_SOURCE_LOCATION (decl)),
			  "in C++98 %qD must be initialized by "
			  "constructor, not by %<{...}%>",
			  decl);
	    }
	  else if (VECTOR_TYPE_P (type) && TYPE_VECTOR_OPAQUE (type))
	    {
	      error ("opaque vector types cannot be initialized");
	      init = error_mark_node;
	    }
	  else
	    {
	      init = reshape_init (type, init, tf_warning_or_error);
	      flags |= LOOKUP_NO_NARROWING;
	    }
	}
      else if (TREE_CODE (init) == TREE_LIST
	       && TREE_TYPE (init) != unknown_type_node
	       && !MAYBE_CLASS_TYPE_P (type))
	{
	  gcc_assert (TREE_CODE (decl) != RESULT_DECL);

	  /* We get here with code like `int a (2);' */
	  init = build_x_compound_expr_from_list (init, ELK_INIT,
						  tf_warning_or_error);
	}

      /* If DECL has an array type without a specific bound, deduce the
	 array size from the initializer.  */
      maybe_deduce_size_from_array_init (decl, init);
      type = TREE_TYPE (decl);
      if (type == error_mark_node)
	return NULL_TREE;

      if (((type_build_ctor_call (type) || CLASS_TYPE_P (type))
	   && !(flags & LOOKUP_ALREADY_DIGESTED)
	   && !(init && BRACE_ENCLOSED_INITIALIZER_P (init)
		&& CP_AGGREGATE_TYPE_P (type)
		&& (CLASS_TYPE_P (type)
		    || !TYPE_NEEDS_CONSTRUCTING (type)
		    || type_has_extended_temps (type))))
	  || (DECL_DECOMPOSITION_P (decl) && TREE_CODE (type) == ARRAY_TYPE))
	{
	  init_code = build_aggr_init_full_exprs (decl, init, flags);

	  /* A constructor call is a non-trivial initializer even if
	     it isn't explicitly written.  */
	  if (TREE_SIDE_EFFECTS (init_code))
	    DECL_NONTRIVIALLY_INITIALIZED_P (decl) = true;

	  /* If this is a constexpr initializer, expand_default_init will
	     have returned an INIT_EXPR rather than a CALL_EXPR.  In that
	     case, pull the initializer back out and pass it down into
	     store_init_value.  */
	  while (TREE_CODE (init_code) == EXPR_STMT
		 || TREE_CODE (init_code) == CONVERT_EXPR)
	    init_code = TREE_OPERAND (init_code, 0);
	  if (TREE_CODE (init_code) == INIT_EXPR)
	    {
	      init = TREE_OPERAND (init_code, 1);
	      init_code = NULL_TREE;
	      /* Don't call digest_init; it's unnecessary and will complain
		 about aggregate initialization of non-aggregate classes.  */
	      flags |= LOOKUP_ALREADY_DIGESTED;
	    }
	  else if (DECL_DECLARED_CONSTEXPR_P (decl))
	    {
	      /* Declared constexpr, but no suitable initializer; massage
		 init appropriately so we can pass it into store_init_value
		 for the error.  */
	      if (CLASS_TYPE_P (type)
		  && (!init || TREE_CODE (init) == TREE_LIST))
		{
		  init = build_functional_cast (type, init, tf_none);
		  if (TREE_CODE (init) == TARGET_EXPR)
		    TARGET_EXPR_DIRECT_INIT_P (init) = true;
		}
	      init_code = NULL_TREE;
	    }
	  else
	    init = NULL_TREE;
	}

      if (init && TREE_CODE (init) != TREE_VEC)
	{
	  /* In aggregate initialization of a variable, each element
	     initialization is a full-expression because there is no
	     enclosing expression.  */
	  gcc_assert (stmts_are_full_exprs_p ());

	  init_code = store_init_value (decl, init, cleanups, flags);

	  if (DECL_INITIAL (decl)
	      && TREE_CODE (DECL_INITIAL (decl)) == CONSTRUCTOR
	      && !vec_safe_is_empty (CONSTRUCTOR_ELTS (DECL_INITIAL (decl))))
	    {
	      tree elt = CONSTRUCTOR_ELTS (DECL_INITIAL (decl))->last ().value;
	      if (TREE_CODE (TREE_TYPE (elt)) == ARRAY_TYPE
		  && TYPE_SIZE (TREE_TYPE (elt)) == NULL_TREE)
		cp_complete_array_type (&TREE_TYPE (elt), elt, false);
	    }

	  if (pedantic && TREE_CODE (type) == ARRAY_TYPE
	      && DECL_INITIAL (decl)
	      && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
	      && PAREN_STRING_LITERAL_P (DECL_INITIAL (decl)))
	    warning_at (cp_expr_loc_or_loc (DECL_INITIAL (decl),
					 DECL_SOURCE_LOCATION (decl)),
			0, "array %qD initialized by parenthesized "
			"string literal %qE",
			decl, DECL_INITIAL (decl));
	  init = NULL;
	}
    }
  else
    {
      if (CLASS_TYPE_P (core_type = strip_array_types (type))
	  && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
	      || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
	diagnose_uninitialized_cst_or_ref_member (core_type, /*using_new=*/false,
						  /*complain=*/true);

      check_for_uninitialized_const_var (decl, /*constexpr_context_p=*/false,
					 tf_warning_or_error);
    }

  if (init && init != error_mark_node)
    init_code = build2 (INIT_EXPR, type, decl, init);

  if (init_code)
    {
      /* We might have set these in cp_finish_decl.  */
      DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = false;
      TREE_CONSTANT (decl) = false;
    }

  if (init_code
      && (DECL_IN_AGGR_P (decl)
	  && DECL_INITIALIZED_IN_CLASS_P (decl)
	  && !DECL_VAR_DECLARED_INLINE_P (decl)))
    {
      static int explained = 0;

      if (cxx_dialect < cxx11)
	error ("initializer invalid for static member with constructor");
      else if (cxx_dialect < cxx17)
	error ("non-constant in-class initialization invalid for static "
	       "member %qD", decl);
      else
	error ("non-constant in-class initialization invalid for non-inline "
	       "static member %qD", decl);
      if (!explained)
	{
	  inform (input_location,
		  "(an out of class initialization is required)");
	  explained = 1;
	}
      return NULL_TREE;
    }

  return init_code;
}

/* If DECL is not a local variable, give it RTL.  */

static void
make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
{
  int toplev = toplevel_bindings_p ();
  int defer_p;

  /* Set the DECL_ASSEMBLER_NAME for the object.  */
  if (asmspec)
    {
      /* The `register' keyword, when used together with an
	 asm-specification, indicates that the variable should be
	 placed in a particular register.  */
      if (VAR_P (decl) && DECL_REGISTER (decl))
	{
	  set_user_assembler_name (decl, asmspec);
	  DECL_HARD_REGISTER (decl) = 1;
	}
      else
	{
	  if (TREE_CODE (decl) == FUNCTION_DECL
	      && fndecl_built_in_p (decl, BUILT_IN_NORMAL))
	    set_builtin_user_assembler_name (decl, asmspec);
	  set_user_assembler_name (decl, asmspec);
	}
    }

  /* Handle non-variables up front.  */
  if (!VAR_P (decl))
    {
      rest_of_decl_compilation (decl, toplev, at_eof);
      return;
    }

  /* If we see a class member here, it should be a static data
     member.  */
  if (DECL_LANG_SPECIFIC (decl) && DECL_IN_AGGR_P (decl))
    {
      gcc_assert (TREE_STATIC (decl));
      /* An in-class declaration of a static data member should be
	 external; it is only a declaration, and not a definition.  */
      if (init == NULL_TREE)
	gcc_assert (DECL_EXTERNAL (decl)
		    || !TREE_PUBLIC (decl)
		    || DECL_INLINE_VAR_P (decl));
    }

  /* We don't create any RTL for local variables.  */
  if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
    return;

  /* We defer emission of local statics until the corresponding
     DECL_EXPR is expanded.  But with constexpr its function might never
     be expanded, so go ahead and tell cgraph about the variable now.  */
  defer_p = ((DECL_FUNCTION_SCOPE_P (decl)
	      && !var_in_maybe_constexpr_fn (decl))
	     || DECL_VIRTUAL_P (decl));

  /* Defer template instantiations.  */
  if (DECL_LANG_SPECIFIC (decl)
      && DECL_IMPLICIT_INSTANTIATION (decl))
    defer_p = 1;

  /* If we're not deferring, go ahead and assemble the variable.  */
  if (!defer_p)
    rest_of_decl_compilation (decl, toplev, at_eof);
}

/* walk_tree helper for wrap_temporary_cleanups, below.  */

static tree
wrap_cleanups_r (tree *stmt_p, int *walk_subtrees, void *data)
{
  /* Stop at types or full-expression boundaries.  */
  if (TYPE_P (*stmt_p)
      || TREE_CODE (*stmt_p) == CLEANUP_POINT_EXPR)
    {
      *walk_subtrees = 0;
      return NULL_TREE;
    }

  if (TREE_CODE (*stmt_p) == TARGET_EXPR)
    {
      tree guard = (tree)data;
      tree tcleanup = TARGET_EXPR_CLEANUP (*stmt_p);

      tcleanup = build2 (TRY_CATCH_EXPR, void_type_node, tcleanup, guard);
      /* Tell honor_protect_cleanup_actions to handle this as a separate
	 cleanup.  */
      TRY_CATCH_IS_CLEANUP (tcleanup) = 1;
 
      TARGET_EXPR_CLEANUP (*stmt_p) = tcleanup;
    }

  return NULL_TREE;
}

/* We're initializing a local variable which has a cleanup GUARD.  If there
   are any temporaries used in the initializer INIT of this variable, we
   need to wrap their cleanups with TRY_CATCH_EXPR (, GUARD) so that the
   variable will be cleaned up properly if one of them throws.

   Unfortunately, there's no way to express this properly in terms of
   nesting, as the regions for the temporaries overlap the region for the
   variable itself; if there are two temporaries, the variable needs to be
   the first thing destroyed if either of them throws.  However, we only
   want to run the variable's cleanup if it actually got constructed.  So
   we need to guard the temporary cleanups with the variable's cleanup if
   they are run on the normal path, but not if they are run on the
   exceptional path.  We implement this by telling
   honor_protect_cleanup_actions to strip the variable cleanup from the
   exceptional path.  */

static void
wrap_temporary_cleanups (tree init, tree guard)
{
  cp_walk_tree_without_duplicates (&init, wrap_cleanups_r, (void *)guard);
}

/* Generate code to initialize DECL (a local variable).  */

static void
initialize_local_var (tree decl, tree init)
{
  tree type = TREE_TYPE (decl);
  tree cleanup;
  int already_used;

  gcc_assert (VAR_P (decl)
	      || TREE_CODE (decl) == RESULT_DECL);
  gcc_assert (!TREE_STATIC (decl));

  if (DECL_SIZE (decl) == NULL_TREE)
    {
      /* If we used it already as memory, it must stay in memory.  */
      DECL_INITIAL (decl) = NULL_TREE;
      TREE_ADDRESSABLE (decl) = TREE_USED (decl);
      return;
    }

  if (type == error_mark_node)
    return;

  /* Compute and store the initial value.  */
  already_used = TREE_USED (decl) || TREE_USED (type);
  if (TREE_USED (type))
    DECL_READ_P (decl) = 1;

  /* Generate a cleanup, if necessary.  */
  cleanup = cxx_maybe_build_cleanup (decl, tf_warning_or_error);

  /* Perform the initialization.  */
  if (init)
    {
      tree rinit = (TREE_CODE (init) == INIT_EXPR
		    ? TREE_OPERAND (init, 1) : NULL_TREE);
      if (rinit && !TREE_SIDE_EFFECTS (rinit))
	{
	  /* Stick simple initializers in DECL_INITIAL so that
	     -Wno-init-self works (c++/34772).  */
	  gcc_assert (TREE_OPERAND (init, 0) == decl);
	  DECL_INITIAL (decl) = rinit;

	  if (warn_init_self && TYPE_REF_P (type))
	    {
	      STRIP_NOPS (rinit);
	      if (rinit == decl)
		warning_at (DECL_SOURCE_LOCATION (decl),
			    OPT_Winit_self,
			    "reference %qD is initialized with itself", decl);
	    }
	}
      else
	{
	  int saved_stmts_are_full_exprs_p;

	  /* If we're only initializing a single object, guard the
	     destructors of any temporaries used in its initializer with
	     its destructor.  This isn't right for arrays because each
	     element initialization is a full-expression.  */
	  if (cleanup && TREE_CODE (type) != ARRAY_TYPE)
	    wrap_temporary_cleanups (init, cleanup);

	  gcc_assert (building_stmt_list_p ());
	  saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
	  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
	  finish_expr_stmt (init);
	  current_stmt_tree ()->stmts_are_full_exprs_p =
	    saved_stmts_are_full_exprs_p;
	}
    }

  /* Set this to 0 so we can tell whether an aggregate which was
     initialized was ever used.  Don't do this if it has a
     destructor, so we don't complain about the 'resource
     allocation is initialization' idiom.  Now set
     attribute((unused)) on types so decls of that type will be
     marked used. (see TREE_USED, above.)  */
  if (TYPE_NEEDS_CONSTRUCTING (type)
      && ! already_used
      && TYPE_HAS_TRIVIAL_DESTRUCTOR (type)
      && DECL_NAME (decl))
    TREE_USED (decl) = 0;
  else if (already_used)
    TREE_USED (decl) = 1;

  if (cleanup)
    finish_decl_cleanup (decl, cleanup);
}

/* DECL is a VAR_DECL for a compiler-generated variable with static
   storage duration (like a virtual table) whose initializer is a
   compile-time constant.  Initialize the variable and provide it to the
   back end.  */

void
initialize_artificial_var (tree decl, vec<constructor_elt, va_gc> *v)
{
  tree init;
  gcc_assert (DECL_ARTIFICIAL (decl));
  init = build_constructor (TREE_TYPE (decl), v);
  gcc_assert (TREE_CODE (init) == CONSTRUCTOR);
  DECL_INITIAL (decl) = init;
  DECL_INITIALIZED_P (decl) = 1;
  /* Mark the decl as constexpr so that we can access its content
     at compile time.  */
  DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
  DECL_DECLARED_CONSTEXPR_P (decl) = true;
  determine_visibility (decl);
  layout_var_decl (decl);
  maybe_commonize_var (decl);
  make_rtl_for_nonlocal_decl (decl, init, /*asmspec=*/NULL);
}

/* INIT is the initializer for a variable, as represented by the
   parser.  Returns true iff INIT is value-dependent.  */

static bool
value_dependent_init_p (tree init)
{
  if (TREE_CODE (init) == TREE_LIST)
    /* A parenthesized initializer, e.g.: int i (3, 2); ? */
    return any_value_dependent_elements_p (init);
  else if (TREE_CODE (init) == CONSTRUCTOR)
  /* A brace-enclosed initializer, e.g.: int i = { 3 }; ? */
    {
      if (dependent_type_p (TREE_TYPE (init)))
	return true;

      vec<constructor_elt, va_gc> *elts;
      size_t nelts;
      size_t i;

      elts = CONSTRUCTOR_ELTS (init);
      nelts = vec_safe_length (elts);
      for (i = 0; i < nelts; ++i)
	if (value_dependent_init_p ((*elts)[i].value))
	  return true;
    }
  else
    /* It must be a simple expression, e.g., int i = 3;  */
    return value_dependent_expression_p (init);
  
  return false;
}

// Returns true if a DECL is VAR_DECL with the concept specifier.
static inline bool
is_concept_var (tree decl)
{
  return (VAR_P (decl)
	  // Not all variables have DECL_LANG_SPECIFIC.
          && DECL_LANG_SPECIFIC (decl)
          && DECL_DECLARED_CONCEPT_P (decl));
}

/* A helper function to be called via walk_tree.  If any label exists
   under *TP, it is (going to be) forced.  Set has_forced_label_in_static.  */

static tree
notice_forced_label_r (tree *tp, int *walk_subtrees, void *)
{
  if (TYPE_P (*tp))
    *walk_subtrees = 0;
  if (TREE_CODE (*tp) == LABEL_DECL)
    cfun->has_forced_label_in_static = 1;
  return NULL_TREE;
}

/* Finish processing of a declaration;
   install its line number and initial value.
   If the length of an array type is not known before,
   it must be determined now, from the initial value, or it is an error.

   INIT is the initializer (if any) for DECL.  If INIT_CONST_EXPR_P is
   true, then INIT is an integral constant expression.

   FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0
   if the (init) syntax was used.  */

void
cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
		tree asmspec_tree, int flags)
{
  tree type;
  vec<tree, va_gc> *cleanups = NULL;
  const char *asmspec = NULL;
  int was_readonly = 0;
  bool var_definition_p = false;
  tree auto_node;

  if (decl == error_mark_node)
    return;
  else if (! decl)
    {
      if (init)
	error ("assignment (not initialization) in declaration");
      return;
    }

  gcc_assert (TREE_CODE (decl) != RESULT_DECL);
  /* Parameters are handled by store_parm_decls, not cp_finish_decl.  */
  gcc_assert (TREE_CODE (decl) != PARM_DECL);

  type = TREE_TYPE (decl);
  if (type == error_mark_node)
    return;

  /* Warn about register storage specifiers except when in GNU global
     or local register variable extension.  */
  if (VAR_P (decl) && DECL_REGISTER (decl) && asmspec_tree == NULL_TREE)
    {
      if (cxx_dialect >= cxx17)
	pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
		 "ISO C++17 does not allow %<register%> storage "
		 "class specifier");
      else
	warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
		    "%<register%> storage class specifier used");
    }

  /* If a name was specified, get the string.  */
  if (at_namespace_scope_p ())
    asmspec_tree = maybe_apply_renaming_pragma (decl, asmspec_tree);
  if (asmspec_tree && asmspec_tree != error_mark_node)
    asmspec = TREE_STRING_POINTER (asmspec_tree);

  if (current_class_type
      && CP_DECL_CONTEXT (decl) == current_class_type
      && TYPE_BEING_DEFINED (current_class_type)
      && !CLASSTYPE_TEMPLATE_INSTANTIATION (current_class_type)
      && (DECL_INITIAL (decl) || init))
    DECL_INITIALIZED_IN_CLASS_P (decl) = 1;

  /* Do auto deduction unless decl is a function or an uninstantiated
     template specialization.  */
  if (TREE_CODE (decl) != FUNCTION_DECL
      && !(init == NULL_TREE
	   && DECL_LANG_SPECIFIC (decl)
	   && DECL_TEMPLATE_INSTANTIATION (decl)
	   && !DECL_TEMPLATE_INSTANTIATED (decl))
      && (auto_node = type_uses_auto (type)))
    {
      tree d_init;
      if (init == NULL_TREE)
	gcc_assert (CLASS_PLACEHOLDER_TEMPLATE (auto_node));
      d_init = init;
      if (d_init)
	{
	  if (TREE_CODE (d_init) == TREE_LIST
	      && !CLASS_PLACEHOLDER_TEMPLATE (auto_node))
	    d_init = build_x_compound_expr_from_list (d_init, ELK_INIT,
						      tf_warning_or_error);
	  d_init = resolve_nondeduced_context (d_init, tf_warning_or_error);
	}
      enum auto_deduction_context adc = adc_variable_type;
      if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
	adc = adc_decomp_type;
      type = TREE_TYPE (decl) = do_auto_deduction (type, d_init, auto_node,
						   tf_warning_or_error, adc,
						   NULL_TREE, flags);
      if (type == error_mark_node)
	return;
      if (TREE_CODE (type) == FUNCTION_TYPE)
	{
	  error ("initializer for %<decltype(auto) %D%> has function type "
		 "(did you forget the %<()%> ?)", decl);
	  TREE_TYPE (decl) = error_mark_node;
	  return;
	}
      cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
    }

  if (ensure_literal_type_for_constexpr_object (decl) == error_mark_node)
    {
      DECL_DECLARED_CONSTEXPR_P (decl) = 0;
      if (VAR_P (decl) && DECL_CLASS_SCOPE_P (decl))
	{
	  init = NULL_TREE;
	  DECL_EXTERNAL (decl) = 1;
	}
    }

  if (VAR_P (decl)
      && DECL_CLASS_SCOPE_P (decl)
      && DECL_INITIALIZED_IN_CLASS_P (decl))
    check_static_variable_definition (decl, type);

  if (init && TREE_CODE (decl) == FUNCTION_DECL)
    {
      tree clone;
      if (init == ridpointers[(int)RID_DELETE])
	{
	  /* FIXME check this is 1st decl.  */
	  DECL_DELETED_FN (decl) = 1;
	  DECL_DECLARED_INLINE_P (decl) = 1;
	  DECL_INITIAL (decl) = error_mark_node;
	  FOR_EACH_CLONE (clone, decl)
	    {
	      DECL_DELETED_FN (clone) = 1;
	      DECL_DECLARED_INLINE_P (clone) = 1;
	      DECL_INITIAL (clone) = error_mark_node;
	    }
	  init = NULL_TREE;
	}
      else if (init == ridpointers[(int)RID_DEFAULT])
	{
	  if (defaultable_fn_check (decl))
	    DECL_DEFAULTED_FN (decl) = 1;
	  else
	    DECL_INITIAL (decl) = NULL_TREE;
	}
    }

  if (init && VAR_P (decl))
    {
      DECL_NONTRIVIALLY_INITIALIZED_P (decl) = 1;
      /* If DECL is a reference, then we want to know whether init is a
	 reference constant; init_const_expr_p as passed tells us whether
	 it's an rvalue constant.  */
      if (TYPE_REF_P (type))
	init_const_expr_p = potential_constant_expression (init);
      if (init_const_expr_p)
	{
	  /* Set these flags now for templates.  We'll update the flags in
	     store_init_value for instantiations.  */
	  DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = 1;
	  if (decl_maybe_constant_var_p (decl)
	      /* FIXME setting TREE_CONSTANT on refs breaks the back end.  */
	      && !TYPE_REF_P (type))
	    TREE_CONSTANT (decl) = 1;
	}
    }

  if (processing_template_decl)
    {
      bool type_dependent_p;

      /* Add this declaration to the statement-tree.  */
      if (at_function_scope_p ())
	add_decl_expr (decl);

      type_dependent_p = dependent_type_p (type);

      if (check_for_bare_parameter_packs (init))
	{
	  init = NULL_TREE;
	  DECL_INITIAL (decl) = NULL_TREE;
	}

      /* Generally, initializers in templates are expanded when the
	 template is instantiated.  But, if DECL is a variable constant
	 then it can be used in future constant expressions, so its value
	 must be available. */

      bool dep_init = false;

      if (!VAR_P (decl) || type_dependent_p)
	/* We can't do anything if the decl has dependent type.  */;
      else if (!init && is_concept_var (decl))
	{
	  error ("variable concept has no initializer");
	  init = boolean_true_node;
	}
      else if (init
	       && init_const_expr_p
	       && !TYPE_REF_P (type)
	       && decl_maybe_constant_var_p (decl)
	       && !(dep_init = value_dependent_init_p (init)))
	{
	  /* This variable seems to be a non-dependent constant, so process
	     its initializer.  If check_initializer returns non-null the
	     initialization wasn't constant after all.  */
	  tree init_code;
	  cleanups = make_tree_vector ();
	  init_code = check_initializer (decl, init, flags, &cleanups);
	  if (init_code == NULL_TREE)
	    init = NULL_TREE;
	  release_tree_vector (cleanups);
	}
      else
	{
	  gcc_assert (!DECL_PRETTY_FUNCTION_P (decl));
	  /* Deduce array size even if the initializer is dependent.  */
	  maybe_deduce_size_from_array_init (decl, init);
	  /* And complain about multiple initializers.  */
	  if (init && TREE_CODE (init) == TREE_LIST && TREE_CHAIN (init)
	      && !MAYBE_CLASS_TYPE_P (type))
	    init = build_x_compound_expr_from_list (init, ELK_INIT,
						    tf_warning_or_error);
	}

      if (init)
	DECL_INITIAL (decl) = init;

      if (dep_init)
	{
	  retrofit_lang_decl (decl);
	  SET_DECL_DEPENDENT_INIT_P (decl, true);
	}
      return;
    }

  /* Just store non-static data member initializers for later.  */
  if (init && TREE_CODE (decl) == FIELD_DECL)
    DECL_INITIAL (decl) = init;

  /* Take care of TYPE_DECLs up front.  */
  if (TREE_CODE (decl) == TYPE_DECL)
    {
      if (type != error_mark_node
	  && MAYBE_CLASS_TYPE_P (type) && DECL_NAME (decl))
	{
	  if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type)
	    warning (0, "shadowing previous type declaration of %q#D", decl);
	  set_identifier_type_value (DECL_NAME (decl), decl);
	}

      /* If we have installed this as the canonical typedef for this
	 type, and that type has not been defined yet, delay emitting
	 the debug information for it, as we will emit it later.  */
      if (TYPE_MAIN_DECL (TREE_TYPE (decl)) == decl
	  && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
	TYPE_DECL_SUPPRESS_DEBUG (decl) = 1;

      rest_of_decl_compilation (decl, DECL_FILE_SCOPE_P (decl),
				at_eof);
      return;
    }

  /* A reference will be modified here, as it is initialized.  */
  if (! DECL_EXTERNAL (decl)
      && TREE_READONLY (decl)
      && TYPE_REF_P (type))
    {
      was_readonly = 1;
      TREE_READONLY (decl) = 0;
    }

  if (VAR_P (decl))
    {
      /* If this is a local variable that will need a mangled name,
	 register it now.  We must do this before processing the
	 initializer for the variable, since the initialization might
	 require a guard variable, and since the mangled name of the
	 guard variable will depend on the mangled name of this
	 variable.  */
      if (DECL_FUNCTION_SCOPE_P (decl)
	  && TREE_STATIC (decl)
	  && !DECL_ARTIFICIAL (decl))
	{
	  /* The variable holding an anonymous union will have had its
	     discriminator set in finish_anon_union, after which it's
	     NAME will have been cleared.  */
	  if (DECL_NAME (decl))
	    determine_local_discriminator (decl);
	  /* Normally has_forced_label_in_static is set during GIMPLE
	     lowering, but [cd]tors are never actually compiled directly.
	     We need to set this early so we can deal with the label
	     address extension.  */
	  if ((DECL_CONSTRUCTOR_P (current_function_decl)
	       || DECL_DESTRUCTOR_P (current_function_decl))
	      && init)
	    {
	      walk_tree (&init, notice_forced_label_r, NULL, NULL);
	      add_local_decl (cfun, decl);
	    }
	  /* And make sure it's in the symbol table for
	     c_parse_final_cleanups to find.  */
	  varpool_node::get_create (decl);
	}

      /* Convert the initializer to the type of DECL, if we have not
	 already initialized DECL.  */
      if (!DECL_INITIALIZED_P (decl)
	  /* If !DECL_EXTERNAL then DECL is being defined.  In the
	     case of a static data member initialized inside the
	     class-specifier, there can be an initializer even if DECL
	     is *not* defined.  */
	  && (!DECL_EXTERNAL (decl) || init))
	{
	  cleanups = make_tree_vector ();
	  init = check_initializer (decl, init, flags, &cleanups);

	  /* Handle:

	     [dcl.init]

	     The memory occupied by any object of static storage
	     duration is zero-initialized at program startup before
	     any other initialization takes place.

	     We cannot create an appropriate initializer until after
	     the type of DECL is finalized.  If DECL_INITIAL is set,
	     then the DECL is statically initialized, and any
	     necessary zero-initialization has already been performed.  */
	  if (TREE_STATIC (decl) && !DECL_INITIAL (decl))
	    DECL_INITIAL (decl) = build_zero_init (TREE_TYPE (decl),
						   /*nelts=*/NULL_TREE,
						   /*static_storage_p=*/true);
	  /* Remember that the initialization for this variable has
	     taken place.  */
	  DECL_INITIALIZED_P (decl) = 1;
	  /* This declaration is the definition of this variable,
	     unless we are initializing a static data member within
	     the class specifier.  */
	  if (!DECL_EXTERNAL (decl))
	    var_definition_p = true;
	}
      /* If the variable has an array type, lay out the type, even if
	 there is no initializer.  It is valid to index through the
	 array, and we must get TYPE_ALIGN set correctly on the array
	 type.  */
      else if (TREE_CODE (type) == ARRAY_TYPE)
	layout_type (type);

      if (TREE_STATIC (decl)
	  && !at_function_scope_p ()
	  && current_function_decl == NULL)
	/* So decl is a global variable or a static member of a
	   non local class. Record the types it uses
	   so that we can decide later to emit debug info for them.  */
	record_types_used_by_current_var_decl (decl);
    }

  /* Add this declaration to the statement-tree.  This needs to happen
     after the call to check_initializer so that the DECL_EXPR for a
     reference temp is added before the DECL_EXPR for the reference itself.  */
  if (DECL_FUNCTION_SCOPE_P (decl))
    {
      /* If we're building a variable sized type, and we might be
	 reachable other than via the top of the current binding
	 level, then create a new BIND_EXPR so that we deallocate
	 the object at the right time.  */
      if (VAR_P (decl)
	  && DECL_SIZE (decl)
	  && !TREE_CONSTANT (DECL_SIZE (decl))
	  && STATEMENT_LIST_HAS_LABEL (cur_stmt_list))
	{
	  tree bind;
	  bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
	  TREE_SIDE_EFFECTS (bind) = 1;
	  add_stmt (bind);
	  BIND_EXPR_BODY (bind) = push_stmt_list ();
	}
      add_decl_expr (decl);
    }

  /* Let the middle end know about variables and functions -- but not
     static data members in uninstantiated class templates.  */
  if (VAR_OR_FUNCTION_DECL_P (decl))
    {
      if (VAR_P (decl))
	{
	  layout_var_decl (decl);
	  maybe_commonize_var (decl);
	}

      /* This needs to happen after the linkage is set. */
      determine_visibility (decl);

      if (var_definition_p && TREE_STATIC (decl))
	{
	  /* If a TREE_READONLY variable needs initialization
	     at runtime, it is no longer readonly and we need to
	     avoid MEM_READONLY_P being set on RTL created for it.  */
	  if (init)
	    {
	      if (TREE_READONLY (decl))
		TREE_READONLY (decl) = 0;
	      was_readonly = 0;
	    }
	  else if (was_readonly)
	    TREE_READONLY (decl) = 1;

	  /* Likewise if it needs destruction.  */
	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
	    TREE_READONLY (decl) = 0;
	}

      make_rtl_for_nonlocal_decl (decl, init, asmspec);

      /* Check for abstractness of the type. Notice that there is no
	 need to strip array types here since the check for those types
	 is already done within create_array_type_for_decl.  */
      abstract_virtuals_error (decl, type);

      if (TREE_TYPE (decl) == error_mark_node)
	/* No initialization required.  */
	;
      else if (TREE_CODE (decl) == FUNCTION_DECL)
	{
	  if (init)
	    {
	      if (init == ridpointers[(int)RID_DEFAULT])
		{
		  /* An out-of-class default definition is defined at
		     the point where it is explicitly defaulted.  */
		  if (DECL_DELETED_FN (decl))
		    maybe_explain_implicit_delete (decl);
		  else if (DECL_INITIAL (decl) == error_mark_node)
		    synthesize_method (decl);
		}
	      else
		error ("function %q#D is initialized like a variable", decl);
	    }
	  /* else no initialization required.  */
	}
      else if (DECL_EXTERNAL (decl)
	       && ! (DECL_LANG_SPECIFIC (decl)
		     && DECL_NOT_REALLY_EXTERN (decl)))
	{
	  if (init)
	    DECL_INITIAL (decl) = init;
	}
      /* A variable definition.  */
      else if (DECL_FUNCTION_SCOPE_P (decl) && !TREE_STATIC (decl))
	/* Initialize the local variable.  */
	initialize_local_var (decl, init);

      /* If a variable is defined, and then a subsequent
	 definition with external linkage is encountered, we will
	 get here twice for the same variable.  We want to avoid
	 calling expand_static_init more than once.  For variables
	 that are not static data members, we can call
	 expand_static_init only when we actually process the
	 initializer.  It is not legal to redeclare a static data
	 member, so this issue does not arise in that case.  */
      else if (var_definition_p && TREE_STATIC (decl))
	expand_static_init (decl, init);
    }

  /* If a CLEANUP_STMT was created to destroy a temporary bound to a
     reference, insert it in the statement-tree now.  */
  if (cleanups)
    {
      unsigned i; tree t;
      FOR_EACH_VEC_ELT (*cleanups, i, t)
	push_cleanup (decl, t, false);
      release_tree_vector (cleanups);
    }

  if (was_readonly)
    TREE_READONLY (decl) = 1;

  if (flag_openmp
      && VAR_P (decl)
      && lookup_attribute ("omp declare target implicit",
			   DECL_ATTRIBUTES (decl)))
    {
      DECL_ATTRIBUTES (decl)
	= remove_attribute ("omp declare target implicit",
			    DECL_ATTRIBUTES (decl));
      complete_type (TREE_TYPE (decl));
      if (!cp_omp_mappable_type (TREE_TYPE (decl)))
	error ("%q+D in declare target directive does not have mappable type",
	       decl);
      else if (!lookup_attribute ("omp declare target",
				  DECL_ATTRIBUTES (decl))
	       && !lookup_attribute ("omp declare target link",
				     DECL_ATTRIBUTES (decl)))
	DECL_ATTRIBUTES (decl)
	  = tree_cons (get_identifier ("omp declare target"),
		       NULL_TREE, DECL_ATTRIBUTES (decl));
    }

  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
}

/* For class TYPE return itself or some its bases that contain
   any direct non-static data members.  Return error_mark_node if an
   error has been diagnosed.  */

static tree
find_decomp_class_base (location_t loc, tree type, tree ret)
{
  bool member_seen = false;
  for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    if (TREE_CODE (field) != FIELD_DECL
	|| DECL_ARTIFICIAL (field)
	|| DECL_UNNAMED_BIT_FIELD (field))
      continue;
    else if (ret)
      return type;
    else if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
      {
	if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
	  error_at (loc, "cannot decompose class type %qT because it has an "
			 "anonymous struct member", type);
	else
	  error_at (loc, "cannot decompose class type %qT because it has an "
			 "anonymous union member", type);
	inform (DECL_SOURCE_LOCATION (field), "declared here");
	return error_mark_node;
      }
    else if (!accessible_p (type, field, true))
      {
	error_at (loc, "cannot decompose inaccessible member %qD of %qT",
		  field, type);
	inform (DECL_SOURCE_LOCATION (field),
		TREE_PRIVATE (field)
		? G_("declared private here")
		: G_("declared protected here"));
	return error_mark_node;
      }
    else
      member_seen = true;

  tree base_binfo, binfo;
  tree orig_ret = ret;
  int i;
  if (member_seen)
    ret = type;
  for (binfo = TYPE_BINFO (type), i = 0;
       BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    {
      tree t = find_decomp_class_base (loc, TREE_TYPE (base_binfo), ret);
      if (t == error_mark_node)
	return error_mark_node;
      if (t != NULL_TREE && t != ret)
	{
	  if (ret == type)
	    {
	      error_at (loc, "cannot decompose class type %qT: both it and "
			     "its base class %qT have non-static data members",
			type, t);
	      return error_mark_node;
	    }
	  else if (orig_ret != NULL_TREE)
	    return t;
	  else if (ret != NULL_TREE)
	    {
	      error_at (loc, "cannot decompose class type %qT: its base "
			     "classes %qT and %qT have non-static data "
			     "members", type, ret, t);
	      return error_mark_node;
	    }
	  else
	    ret = t;
	}
    }
  return ret;
}

/* Return std::tuple_size<TYPE>::value.  */

static tree
get_tuple_size (tree type)
{
  tree args = make_tree_vec (1);
  TREE_VEC_ELT (args, 0) = type;
  tree inst = lookup_template_class (tuple_size_identifier, args,
				     /*in_decl*/NULL_TREE,
				     /*context*/std_node,
				     /*entering_scope*/false, tf_none);
  inst = complete_type (inst);
  if (inst == error_mark_node || !COMPLETE_TYPE_P (inst))
    return NULL_TREE;
  tree val = lookup_qualified_name (inst, value_identifier,
				    /*type*/false, /*complain*/false);
  if (TREE_CODE (val) == VAR_DECL || TREE_CODE (val) == CONST_DECL)
    val = maybe_constant_value (val);
  if (TREE_CODE (val) == INTEGER_CST)
    return val;
  else
    return error_mark_node;
}

/* Return std::tuple_element<I,TYPE>::type.  */

static tree
get_tuple_element_type (tree type, unsigned i)
{
  tree args = make_tree_vec (2);
  TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i);
  TREE_VEC_ELT (args, 1) = type;
  tree inst = lookup_template_class (tuple_element_identifier, args,
				     /*in_decl*/NULL_TREE,
				     /*context*/std_node,
				     /*entering_scope*/false,
				     tf_warning_or_error);
  return make_typename_type (inst, type_identifier,
			     none_type, tf_warning_or_error);
}

/* Return e.get<i>() or get<i>(e).  */

static tree
get_tuple_decomp_init (tree decl, unsigned i)
{
  tree targs = make_tree_vec (1);
  TREE_VEC_ELT (targs, 0) = build_int_cst (integer_type_node, i);

  tree etype = TREE_TYPE (decl);
  tree e = convert_from_reference (decl);

  /* [The id-expression] e is an lvalue if the type of the entity e is an
     lvalue reference and an xvalue otherwise.  */
  if (!TYPE_REF_P (etype)
      || TYPE_REF_IS_RVALUE (etype))
    e = move (e);

  tree fns = lookup_qualified_name (TREE_TYPE (e), get__identifier,
				    /*type*/false, /*complain*/false);
  bool use_member_get = false;

  /* To use a member get, member lookup must find at least one
     declaration that is a function template
     whose first template parameter is a non-type parameter.  */
  for (lkp_iterator iter (MAYBE_BASELINK_FUNCTIONS (fns)); iter; ++iter)
    {
      tree fn = *iter;
      if (TREE_CODE (fn) == TEMPLATE_DECL)
	{
	  tree tparms = DECL_TEMPLATE_PARMS (fn);
	  tree parm = TREE_VEC_ELT (INNERMOST_TEMPLATE_PARMS (tparms), 0);
	  if (TREE_CODE (TREE_VALUE (parm)) == PARM_DECL)
	    {
	      use_member_get = true;
	      break;
	    }
	}
    }

  if (use_member_get)
    {
      fns = lookup_template_function (fns, targs);
      return build_new_method_call (e, fns, /*args*/NULL,
				    /*path*/NULL_TREE, LOOKUP_NORMAL,
				    /*fn_p*/NULL, tf_warning_or_error);
    }
  else
    {
      vec<tree,va_gc> *args = make_tree_vector_single (e);
      fns = lookup_template_function (get__identifier, targs);
      fns = perform_koenig_lookup (fns, args, tf_warning_or_error);
      return finish_call_expr (fns, &args, /*novirt*/false,
			       /*koenig*/true, tf_warning_or_error);
    }
}

/* It's impossible to recover the decltype of a tuple decomposition variable
   based on the actual type of the variable, so store it in a hash table.  */

static GTY((cache)) tree_cache_map *decomp_type_table;
static void
store_decomp_type (tree v, tree t)
{
  if (!decomp_type_table)
    decomp_type_table = tree_cache_map::create_ggc (13);
  decomp_type_table->put (v, t);
}

tree
lookup_decomp_type (tree v)
{
  return *decomp_type_table->get (v);
}

/* Mangle a decomposition declaration if needed.  Arguments like
   in cp_finish_decomp.  */

void
cp_maybe_mangle_decomp (tree decl, tree first, unsigned int count)
{
  if (!processing_template_decl
      && !error_operand_p (decl)
      && DECL_NAMESPACE_SCOPE_P (decl))
    {
      auto_vec<tree, 16> v;
      v.safe_grow (count);
      tree d = first;
      for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
	v[count - i - 1] = d;
      SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v));
      maybe_apply_pragma_weak (decl);
    }
}

/* Finish a decomposition declaration.  DECL is the underlying declaration
   "e", FIRST is the head of a chain of decls for the individual identifiers
   chained through DECL_CHAIN in reverse order and COUNT is the number of
   those decls.  */

void
cp_finish_decomp (tree decl, tree first, unsigned int count)
{
  if (error_operand_p (decl))
    {
     error_out:
      while (count--)
	{
	  TREE_TYPE (first) = error_mark_node;
	  if (DECL_HAS_VALUE_EXPR_P (first))
	    {
	      SET_DECL_VALUE_EXPR (first, NULL_TREE);
	      DECL_HAS_VALUE_EXPR_P (first) = 0;
	    }
	  first = DECL_CHAIN (first);
	}
      if (DECL_P (decl) && DECL_NAMESPACE_SCOPE_P (decl))
	SET_DECL_ASSEMBLER_NAME (decl, get_identifier ("<decomp>"));
      return;
    }

  location_t loc = DECL_SOURCE_LOCATION (decl);
  if (type_dependent_expression_p (decl)
      /* This happens for range for when not in templates.
	 Still add the DECL_VALUE_EXPRs for later processing.  */
      || (!processing_template_decl
	  && type_uses_auto (TREE_TYPE (decl))))
    {
      for (unsigned int i = 0; i < count; i++)
	{
	  if (!DECL_HAS_VALUE_EXPR_P (first))
	    {
	      tree v = build_nt (ARRAY_REF, decl,
				 size_int (count - i - 1),
				 NULL_TREE, NULL_TREE);
	      SET_DECL_VALUE_EXPR (first, v);
	      DECL_HAS_VALUE_EXPR_P (first) = 1;
	    }
	  if (processing_template_decl)
	    fit_decomposition_lang_decl (first, decl);
	  first = DECL_CHAIN (first);
	}
      return;
    }

  auto_vec<tree, 16> v;
  v.safe_grow (count);
  tree d = first;
  for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d))
    {
      v[count - i - 1] = d;
      fit_decomposition_lang_decl (d, decl);
    }

  tree type = TREE_TYPE (decl);
  tree dexp = decl;

  if (TYPE_REF_P (type))
    {
      dexp = convert_from_reference (dexp);
      type = complete_type (TREE_TYPE (type));
      if (type == error_mark_node)
	goto error_out;
      if (!COMPLETE_TYPE_P (type))
	{
	  error_at (loc, "structured binding refers to incomplete type %qT",
		    type);
	  goto error_out;
	}
    }

  tree eltype = NULL_TREE;
  unsigned HOST_WIDE_INT eltscnt = 0;
  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      tree nelts;
      nelts = array_type_nelts_top (type);
      if (nelts == error_mark_node)
	goto error_out;
      if (!tree_fits_uhwi_p (nelts))
	{
	  error_at (loc, "cannot decompose variable length array %qT", type);
	  goto error_out;
	}
      eltscnt = tree_to_uhwi (nelts);
      if (count != eltscnt)
	{
       cnt_mismatch:
	  if (count > eltscnt)
	    error_n (loc, count,
		     "%u name provided for structured binding",
		     "%u names provided for structured binding", count);
	  else
	    error_n (loc, count,
		     "only %u name provided for structured binding",
		     "only %u names provided for structured binding", count);
	  inform_n (loc, eltscnt,
		    "while %qT decomposes into %wu element",
		    "while %qT decomposes into %wu elements",
		    type, eltscnt);
	  goto error_out;
	}
      eltype = TREE_TYPE (type);
      for (unsigned int i = 0; i < count; i++)
	{
	  TREE_TYPE (v[i]) = eltype;
	  layout_decl (v[i], 0);
	  if (processing_template_decl)
	    continue;
	  tree t = unshare_expr (dexp);
	  t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF,
			  eltype, t, size_int (i), NULL_TREE,
			  NULL_TREE);
	  SET_DECL_VALUE_EXPR (v[i], t);
	  DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
	}
    }
  /* 2 GNU extensions.  */
  else if (TREE_CODE (type) == COMPLEX_TYPE)
    {
      eltscnt = 2;
      if (count != eltscnt)
	goto cnt_mismatch;
      eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
      for (unsigned int i = 0; i < count; i++)
	{
	  TREE_TYPE (v[i]) = eltype;
	  layout_decl (v[i], 0);
	  if (processing_template_decl)
	    continue;
	  tree t = unshare_expr (dexp);
	  t = build1_loc (DECL_SOURCE_LOCATION (v[i]),
			  i ? IMAGPART_EXPR : REALPART_EXPR, eltype,
			  t);
	  SET_DECL_VALUE_EXPR (v[i], t);
	  DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
	}
    }
  else if (TREE_CODE (type) == VECTOR_TYPE)
    {
      if (!TYPE_VECTOR_SUBPARTS (type).is_constant (&eltscnt))
	{
	  error_at (loc, "cannot decompose variable length vector %qT", type);
	  goto error_out;
	}
      if (count != eltscnt)
	goto cnt_mismatch;
      eltype = cp_build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
      for (unsigned int i = 0; i < count; i++)
	{
	  TREE_TYPE (v[i]) = eltype;
	  layout_decl (v[i], 0);
	  if (processing_template_decl)
	    continue;
	  tree t = unshare_expr (dexp);
	  convert_vector_to_array_for_subscript (DECL_SOURCE_LOCATION (v[i]),
						 &t, size_int (i));
	  t = build4_loc (DECL_SOURCE_LOCATION (v[i]), ARRAY_REF,
			  eltype, t, size_int (i), NULL_TREE,
			  NULL_TREE);
	  SET_DECL_VALUE_EXPR (v[i], t);
	  DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
	}
    }
  else if (tree tsize = get_tuple_size (type))
    {
      if (tsize == error_mark_node)
	{
	  error_at (loc, "%<std::tuple_size<%T>::value%> is not an integral "
			 "constant expression", type);
	  goto error_out;
	}
      if (!tree_fits_uhwi_p (tsize))
	{
	  error_n (loc, count,
		   "%u name provided for structured binding",
		   "%u names provided for structured binding", count);
	  inform (loc, "while %qT decomposes into %E elements",
		  type, tsize);
	  goto error_out;
	}
      eltscnt = tree_to_uhwi (tsize);
      if (count != eltscnt)
	goto cnt_mismatch;
      int save_read = DECL_READ_P (decl);	
      for (unsigned i = 0; i < count; ++i)
	{
	  location_t sloc = input_location;
	  location_t dloc = DECL_SOURCE_LOCATION (v[i]);

	  input_location = dloc;
	  tree init = get_tuple_decomp_init (decl, i);
	  tree eltype = (init == error_mark_node ? error_mark_node
			 : get_tuple_element_type (type, i));
	  input_location = sloc;

	  if (init == error_mark_node || eltype == error_mark_node)
	    {
	      inform (dloc, "in initialization of structured binding "
		      "variable %qD", v[i]);
	      goto error_out;
	    }
	  /* Save the decltype away before reference collapse.  */
	  store_decomp_type (v[i], eltype);
	  eltype = cp_build_reference_type (eltype, !lvalue_p (init));
	  TREE_TYPE (v[i]) = eltype;
	  layout_decl (v[i], 0);
	  if (DECL_HAS_VALUE_EXPR_P (v[i]))
	    {
	      /* In this case the names are variables, not just proxies.  */
	      SET_DECL_VALUE_EXPR (v[i], NULL_TREE);
	      DECL_HAS_VALUE_EXPR_P (v[i]) = 0;
	    }
	  if (!processing_template_decl)
	    cp_finish_decl (v[i], init, /*constexpr*/false,
			    /*asm*/NULL_TREE, LOOKUP_NORMAL);
	}
      /* Ignore reads from the underlying decl performed during initialization
	 of the individual variables.  If those will be read, we'll mark
	 the underlying decl as read at that point.  */
      DECL_READ_P (decl) = save_read;
    }
  else if (TREE_CODE (type) == UNION_TYPE)
    {
      error_at (loc, "cannot decompose union type %qT", type);
      goto error_out;
    }
  else if (!CLASS_TYPE_P (type))
    {
      error_at (loc, "cannot decompose non-array non-class type %qT", type);
      goto error_out;
    }
  else if (LAMBDA_TYPE_P (type))
    {
      error_at (loc, "cannot decompose lambda closure type %qT", type);
      goto error_out;
    }
  else if (processing_template_decl && !COMPLETE_TYPE_P (type))
    pedwarn (loc, 0, "structured binding refers to incomplete class type %qT",
	     type);
  else
    {
      tree btype = find_decomp_class_base (loc, type, NULL_TREE);
      if (btype == error_mark_node)
	goto error_out;
      else if (btype == NULL_TREE)
	{
	  error_at (loc, "cannot decompose class type %qT without non-static "
			 "data members", type);
	  goto error_out;
	}
      for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
	if (TREE_CODE (field) != FIELD_DECL
	    || DECL_ARTIFICIAL (field)
	    || DECL_UNNAMED_BIT_FIELD (field))
	  continue;
	else
	  eltscnt++;
      if (count != eltscnt)
	goto cnt_mismatch;
      tree t = dexp;
      if (type != btype)
	{
	  t = convert_to_base (t, btype, /*check_access*/true,
			       /*nonnull*/false, tf_warning_or_error);
	  type = btype;
	}
      unsigned int i = 0;
      for (tree field = TYPE_FIELDS (btype); field; field = TREE_CHAIN (field))
	if (TREE_CODE (field) != FIELD_DECL
	    || DECL_ARTIFICIAL (field)
	    || DECL_UNNAMED_BIT_FIELD (field))
	  continue;
	else
	  {
	    tree tt = finish_non_static_data_member (field, unshare_expr (t),
						     NULL_TREE);
	    if (REFERENCE_REF_P (tt))
	      tt = TREE_OPERAND (tt, 0);
	    TREE_TYPE (v[i]) = TREE_TYPE (tt);
	    layout_decl (v[i], 0);
	    if (!processing_template_decl)
	      {
		SET_DECL_VALUE_EXPR (v[i], tt);
		DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
	      }
	    i++;
	  }
    }
  if (processing_template_decl)
    {
      for (unsigned int i = 0; i < count; i++)
	if (!DECL_HAS_VALUE_EXPR_P (v[i]))
	  {
	    tree a = build_nt (ARRAY_REF, decl, size_int (i),
			       NULL_TREE, NULL_TREE);
	    SET_DECL_VALUE_EXPR (v[i], a);
	    DECL_HAS_VALUE_EXPR_P (v[i]) = 1;
	  }
    }
}

/* Returns a declaration for a VAR_DECL as if:

     extern "C" TYPE NAME;

   had been seen.  Used to create compiler-generated global
   variables.  */

static tree
declare_global_var (tree name, tree type)
{
  tree decl;

  push_to_top_level ();
  decl = build_decl (input_location, VAR_DECL, name, type);
  TREE_PUBLIC (decl) = 1;
  DECL_EXTERNAL (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_CONTEXT (decl) = FROB_CONTEXT (global_namespace);
  /* If the user has explicitly declared this variable (perhaps
     because the code we are compiling is part of a low-level runtime
     library), then it is possible that our declaration will be merged
     with theirs by pushdecl.  */
  decl = pushdecl (decl);
  cp_finish_decl (decl, NULL_TREE, false, NULL_TREE, 0);
  pop_from_top_level ();

  return decl;
}

/* Returns the type for the argument to "__cxa_atexit" (or "atexit",
   if "__cxa_atexit" is not being used) corresponding to the function
   to be called when the program exits.  */

static tree
get_atexit_fn_ptr_type (void)
{
  tree fn_type;

  if (!atexit_fn_ptr_type_node)
    {
      tree arg_type;
      if (flag_use_cxa_atexit 
	  && !targetm.cxx.use_atexit_for_cxa_atexit ())
	/* The parameter to "__cxa_atexit" is "void (*)(void *)".  */
	arg_type = ptr_type_node;
      else
	/* The parameter to "atexit" is "void (*)(void)".  */
	arg_type = NULL_TREE;
      
      fn_type = build_function_type_list (void_type_node,
					  arg_type, NULL_TREE);
      atexit_fn_ptr_type_node = build_pointer_type (fn_type);
    }

  return atexit_fn_ptr_type_node;
}

/* Returns a pointer to the `atexit' function.  Note that if
   FLAG_USE_CXA_ATEXIT is nonzero, then this will actually be the new
   `__cxa_atexit' function specified in the IA64 C++ ABI.  */

static tree
get_atexit_node (void)
{
  tree atexit_fndecl;
  tree fn_type;
  tree fn_ptr_type;
  const char *name;
  bool use_aeabi_atexit;

  if (atexit_node)
    return atexit_node;

  if (flag_use_cxa_atexit && !targetm.cxx.use_atexit_for_cxa_atexit ())
    {
      /* The declaration for `__cxa_atexit' is:

	   int __cxa_atexit (void (*)(void *), void *, void *)

	 We build up the argument types and then the function type
	 itself.  */
      tree argtype0, argtype1, argtype2;

      use_aeabi_atexit = targetm.cxx.use_aeabi_atexit ();
      /* First, build the pointer-to-function type for the first
	 argument.  */
      fn_ptr_type = get_atexit_fn_ptr_type ();
      /* Then, build the rest of the argument types.  */
      argtype2 = ptr_type_node;
      if (use_aeabi_atexit)
	{
	  argtype1 = fn_ptr_type;
	  argtype0 = ptr_type_node;
	}
      else
	{
	  argtype1 = ptr_type_node;
	  argtype0 = fn_ptr_type;
	}
      /* And the final __cxa_atexit type.  */
      fn_type = build_function_type_list (integer_type_node,
					  argtype0, argtype1, argtype2,
					  NULL_TREE);
      if (use_aeabi_atexit)
	name = "__aeabi_atexit";
      else
	name = "__cxa_atexit";
    }
  else
    {
      /* The declaration for `atexit' is:

	   int atexit (void (*)());

	 We build up the argument types and then the function type
	 itself.  */
      fn_ptr_type = get_atexit_fn_ptr_type ();
      /* Build the final atexit type.  */
      fn_type = build_function_type_list (integer_type_node,
					  fn_ptr_type, NULL_TREE);
      name = "atexit";
    }

  /* Now, build the function declaration.  */
  push_lang_context (lang_name_c);
  atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
  mark_used (atexit_fndecl);
  pop_lang_context ();
  atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);

  return atexit_node;
}

/* Like get_atexit_node, but for thread-local cleanups.  */

static tree
get_thread_atexit_node (void)
{
  /* The declaration for `__cxa_thread_atexit' is:

     int __cxa_thread_atexit (void (*)(void *), void *, void *) */
  tree fn_type = build_function_type_list (integer_type_node,
					   get_atexit_fn_ptr_type (),
					   ptr_type_node, ptr_type_node,
					   NULL_TREE);

  /* Now, build the function declaration.  */
  tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
					     ECF_LEAF | ECF_NOTHROW);
  return decay_conversion (atexit_fndecl, tf_warning_or_error);
}

/* Returns the __dso_handle VAR_DECL.  */

static tree
get_dso_handle_node (void)
{
  if (dso_handle_node)
    return dso_handle_node;

  /* Declare the variable.  */
  dso_handle_node = declare_global_var (get_identifier ("__dso_handle"),
					ptr_type_node);

#ifdef HAVE_GAS_HIDDEN
  if (dso_handle_node != error_mark_node)
    {
      DECL_VISIBILITY (dso_handle_node) = VISIBILITY_HIDDEN;
      DECL_VISIBILITY_SPECIFIED (dso_handle_node) = 1;
    }
#endif

  return dso_handle_node;
}

/* Begin a new function with internal linkage whose job will be simply
   to destroy some particular variable.  */

static GTY(()) int start_cleanup_cnt;

static tree
start_cleanup_fn (void)
{
  char name[32];
  tree fntype;
  tree fndecl;
  bool use_cxa_atexit = flag_use_cxa_atexit
			&& !targetm.cxx.use_atexit_for_cxa_atexit ();

  push_to_top_level ();

  /* No need to mangle this.  */
  push_lang_context (lang_name_c);

  /* Build the name of the function.  */
  sprintf (name, "__tcf_%d", start_cleanup_cnt++);
  /* Build the function declaration.  */
  fntype = TREE_TYPE (get_atexit_fn_ptr_type ());
  fndecl = build_lang_decl (FUNCTION_DECL, get_identifier (name), fntype);
  /* It's a function with internal linkage, generated by the
     compiler.  */
  TREE_PUBLIC (fndecl) = 0;
  DECL_ARTIFICIAL (fndecl) = 1;
  /* Make the function `inline' so that it is only emitted if it is
     actually needed.  It is unlikely that it will be inlined, since
     it is only called via a function pointer, but we avoid unnecessary
     emissions this way.  */
  DECL_DECLARED_INLINE_P (fndecl) = 1;
  DECL_INTERFACE_KNOWN (fndecl) = 1;
  /* Build the parameter.  */
  if (use_cxa_atexit)
    {
      tree parmdecl = cp_build_parm_decl (fndecl, NULL_TREE, ptr_type_node);
      TREE_USED (parmdecl) = 1;
      DECL_READ_P (parmdecl) = 1;
      DECL_ARGUMENTS (fndecl) = parmdecl;
    }

  pushdecl (fndecl);
  start_preparsed_function (fndecl, NULL_TREE, SF_PRE_PARSED);

  pop_lang_context ();

  return current_function_decl;
}

/* Finish the cleanup function begun by start_cleanup_fn.  */

static void
end_cleanup_fn (void)
{
  expand_or_defer_fn (finish_function (/*inline_p=*/false));

  pop_from_top_level ();
}

/* Generate code to handle the destruction of DECL, an object with
   static storage duration.  */

tree
register_dtor_fn (tree decl)
{
  tree cleanup;
  tree addr;
  tree compound_stmt;
  tree fcall;
  tree type;
  bool ob_parm, dso_parm, use_dtor;
  tree arg0, arg1, arg2;
  tree atex_node;

  type = TREE_TYPE (decl);
  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
    return void_node;

  /* If we're using "__cxa_atexit" (or "__cxa_thread_atexit" or
     "__aeabi_atexit"), and DECL is a class object, we can just pass the
     destructor to "__cxa_atexit"; we don't have to build a temporary
     function to do the cleanup.  */
  dso_parm = (flag_use_cxa_atexit
	      && !targetm.cxx.use_atexit_for_cxa_atexit ());
  ob_parm = (CP_DECL_THREAD_LOCAL_P (decl) || dso_parm);
  use_dtor = ob_parm && CLASS_TYPE_P (type);
  if (use_dtor)
    {
      cleanup = get_class_binding (type, complete_dtor_identifier);

      /* Make sure it is accessible.  */
      perform_or_defer_access_check (TYPE_BINFO (type), cleanup, cleanup,
				     tf_warning_or_error);
    }
  else
    {
      /* Call build_cleanup before we enter the anonymous function so
	 that any access checks will be done relative to the current
	 scope, rather than the scope of the anonymous function.  */
      build_cleanup (decl);
  
      /* Now start the function.  */
      cleanup = start_cleanup_fn ();
      
      /* Now, recompute the cleanup.  It may contain SAVE_EXPRs that refer
	 to the original function, rather than the anonymous one.  That
	 will make the back end think that nested functions are in use,
	 which causes confusion.  */
      push_deferring_access_checks (dk_no_check);
      fcall = build_cleanup (decl);
      pop_deferring_access_checks ();
      
      /* Create the body of the anonymous function.  */
      compound_stmt = begin_compound_stmt (BCS_FN_BODY);
      finish_expr_stmt (fcall);
      finish_compound_stmt (compound_stmt);
      end_cleanup_fn ();
    }

  /* Call atexit with the cleanup function.  */
  mark_used (cleanup);
  cleanup = build_address (cleanup);

  if (CP_DECL_THREAD_LOCAL_P (decl))
    atex_node = get_thread_atexit_node ();
  else
    atex_node = get_atexit_node ();

  if (use_dtor)
    {
      /* We must convert CLEANUP to the type that "__cxa_atexit"
	 expects.  */
      cleanup = build_nop (get_atexit_fn_ptr_type (), cleanup);
      /* "__cxa_atexit" will pass the address of DECL to the
	 cleanup function.  */
      mark_used (decl);
      addr = build_address (decl);
      /* The declared type of the parameter to "__cxa_atexit" is
	 "void *".  For plain "T*", we could just let the
	 machinery in cp_build_function_call convert it -- but if the
	 type is "cv-qualified T *", then we need to convert it
	 before passing it in, to avoid spurious errors.  */
      addr = build_nop (ptr_type_node, addr);
    }
  else
    /* Since the cleanup functions we build ignore the address
       they're given, there's no reason to pass the actual address
       in, and, in general, it's cheaper to pass NULL than any
       other value.  */
    addr = null_pointer_node;

  if (dso_parm)
    arg2 = cp_build_addr_expr (get_dso_handle_node (),
			       tf_warning_or_error);
  else if (ob_parm)
    /* Just pass NULL to the dso handle parm if we don't actually
       have a DSO handle on this target.  */
    arg2 = null_pointer_node;
  else
    arg2 = NULL_TREE;

  if (ob_parm)
    {
      if (!CP_DECL_THREAD_LOCAL_P (decl)
	  && targetm.cxx.use_aeabi_atexit ())
	{
	  arg1 = cleanup;
	  arg0 = addr;
	}
      else
	{
	  arg1 = addr;
	  arg0 = cleanup;
	}
    }
  else
    {
      arg0 = cleanup;
      arg1 = NULL_TREE;
    }
  return cp_build_function_call_nary (atex_node, tf_warning_or_error,
				      arg0, arg1, arg2, NULL_TREE);
}

/* DECL is a VAR_DECL with static storage duration.  INIT, if present,
   is its initializer.  Generate code to handle the construction
   and destruction of DECL.  */

static void
expand_static_init (tree decl, tree init)
{
  gcc_assert (VAR_P (decl));
  gcc_assert (TREE_STATIC (decl));

  /* Some variables require no dynamic initialization.  */
  if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
    {
      /* Make sure the destructor is callable.  */
      cxx_maybe_build_cleanup (decl, tf_warning_or_error);
      if (!init)
	return;
    }

  if (CP_DECL_THREAD_LOCAL_P (decl) && DECL_GNU_TLS_P (decl)
      && !DECL_FUNCTION_SCOPE_P (decl))
    {
      if (init)
	error ("non-local variable %qD declared %<__thread%> "
	       "needs dynamic initialization", decl);
      else
	error ("non-local variable %qD declared %<__thread%> "
	       "has a non-trivial destructor", decl);
      static bool informed;
      if (!informed)
	{
	  inform (DECL_SOURCE_LOCATION (decl),
		  "C++11 %<thread_local%> allows dynamic initialization "
		  "and destruction");
	  informed = true;
	}
      return;
    }

  if (DECL_FUNCTION_SCOPE_P (decl))
    {
      /* Emit code to perform this initialization but once.  */
      tree if_stmt = NULL_TREE, inner_if_stmt = NULL_TREE;
      tree then_clause = NULL_TREE, inner_then_clause = NULL_TREE;
      tree guard, guard_addr;
      tree flag, begin;
      /* We don't need thread-safety code for thread-local vars.  */
      bool thread_guard = (flag_threadsafe_statics
			   && !CP_DECL_THREAD_LOCAL_P (decl));

      /* Emit code to perform this initialization but once.  This code
	 looks like:

	   static <type> guard;
	   if (!__atomic_load (guard.first_byte)) {
	     if (__cxa_guard_acquire (&guard)) {
	       bool flag = false;
	       try {
		 // Do initialization.
		 flag = true; __cxa_guard_release (&guard);
		 // Register variable for destruction at end of program.
	       } catch {
		 if (!flag) __cxa_guard_abort (&guard);
	       }
	     }
	   }

	 Note that the `flag' variable is only set to 1 *after* the
	 initialization is complete.  This ensures that an exception,
	 thrown during the construction, will cause the variable to
	 reinitialized when we pass through this code again, as per:

	   [stmt.dcl]

	   If the initialization exits by throwing an exception, the
	   initialization is not complete, so it will be tried again
	   the next time control enters the declaration.

	 This process should be thread-safe, too; multiple threads
	 should not be able to initialize the variable more than
	 once.  */

      /* Create the guard variable.  */
      guard = get_guard (decl);

      /* Begin the conditional initialization.  */
      if_stmt = begin_if_stmt ();

      finish_if_stmt_cond (get_guard_cond (guard, thread_guard), if_stmt);
      then_clause = begin_compound_stmt (BCS_NO_SCOPE);

      if (thread_guard)
	{
	  tree vfntype = NULL_TREE;
	  tree acquire_name, release_name, abort_name;
	  tree acquire_fn, release_fn, abort_fn;
	  guard_addr = build_address (guard);

	  acquire_name = get_identifier ("__cxa_guard_acquire");
	  release_name = get_identifier ("__cxa_guard_release");
	  abort_name = get_identifier ("__cxa_guard_abort");
	  acquire_fn = get_global_binding (acquire_name);
	  release_fn = get_global_binding (release_name);
	  abort_fn = get_global_binding (abort_name);
	  if (!acquire_fn)
	    acquire_fn = push_library_fn
	      (acquire_name, build_function_type_list (integer_type_node,
						       TREE_TYPE (guard_addr),
						       NULL_TREE),
	       NULL_TREE, ECF_NOTHROW | ECF_LEAF);
	  if (!release_fn || !abort_fn)
	    vfntype = build_function_type_list (void_type_node,
						TREE_TYPE (guard_addr),
						NULL_TREE);
	  if (!release_fn)
	    release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
					   ECF_NOTHROW | ECF_LEAF);
	  if (!abort_fn)
	    abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
					ECF_NOTHROW | ECF_LEAF);

	  inner_if_stmt = begin_if_stmt ();
	  finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
			       inner_if_stmt);

	  inner_then_clause = begin_compound_stmt (BCS_NO_SCOPE);
	  begin = get_target_expr (boolean_false_node);
	  flag = TARGET_EXPR_SLOT (begin);

	  TARGET_EXPR_CLEANUP (begin)
	    = build3 (COND_EXPR, void_type_node, flag,
		      void_node,
		      build_call_n (abort_fn, 1, guard_addr));
	  CLEANUP_EH_ONLY (begin) = 1;

	  /* Do the initialization itself.  */
	  init = add_stmt_to_compound (begin, init);
	  init = add_stmt_to_compound
	    (init, build2 (MODIFY_EXPR, void_type_node, flag, boolean_true_node));
	  init = add_stmt_to_compound
	    (init, build_call_n (release_fn, 1, guard_addr));
	}
      else
	init = add_stmt_to_compound (init, set_guard (guard));

      /* Use atexit to register a function for destroying this static
	 variable.  */
      init = add_stmt_to_compound (init, register_dtor_fn (decl));

      finish_expr_stmt (init);

      if (thread_guard)
	{
	  finish_compound_stmt (inner_then_clause);
	  finish_then_clause (inner_if_stmt);
	  finish_if_stmt (inner_if_stmt);
	}

      finish_compound_stmt (then_clause);
      finish_then_clause (if_stmt);
      finish_if_stmt (if_stmt);
    }
  else if (CP_DECL_THREAD_LOCAL_P (decl))
    tls_aggregates = tree_cons (init, decl, tls_aggregates);
  else
    static_aggregates = tree_cons (init, decl, static_aggregates);
}


/* Make TYPE a complete type based on INITIAL_VALUE.
   Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered,
   2 if there was no information (in which case assume 0 if DO_DEFAULT),
   3 if the initializer list is empty (in pedantic mode). */

int
cp_complete_array_type (tree *ptype, tree initial_value, bool do_default)
{
  int failure;
  tree type, elt_type;

  /* Don't get confused by a CONSTRUCTOR for some other type.  */
  if (initial_value && TREE_CODE (initial_value) == CONSTRUCTOR
      && !BRACE_ENCLOSED_INITIALIZER_P (initial_value)
      && TREE_CODE (TREE_TYPE (initial_value)) != ARRAY_TYPE)
    return 1;

  if (initial_value)
    {
      unsigned HOST_WIDE_INT i;
      tree value;

      /* An array of character type can be initialized from a
	 brace-enclosed string constant.

	 FIXME: this code is duplicated from reshape_init. Probably
	 we should just call reshape_init here?  */
      if (char_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (*ptype)))
	  && TREE_CODE (initial_value) == CONSTRUCTOR
	  && !vec_safe_is_empty (CONSTRUCTOR_ELTS (initial_value)))
	{
	  vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (initial_value);
	  tree value = (*v)[0].value;

	  if (TREE_CODE (value) == STRING_CST
	      && v->length () == 1)
	    initial_value = value;
	}

      /* If any of the elements are parameter packs, we can't actually
	 complete this type now because the array size is dependent.  */
      if (TREE_CODE (initial_value) == CONSTRUCTOR)
	{
	  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (initial_value), 
				      i, value)
	    {
	      if (PACK_EXPANSION_P (value))
		return 0;
	    }
	}
    }

  failure = complete_array_type (ptype, initial_value, do_default);

  /* We can create the array before the element type is complete, which
     means that we didn't have these two bits set in the original type
     either.  In completing the type, we are expected to propagate these
     bits.  See also complete_type which does the same thing for arrays
     of fixed size.  */
  type = *ptype;
  if (type != error_mark_node && TYPE_DOMAIN (type))
    {
      elt_type = TREE_TYPE (type);
      TYPE_NEEDS_CONSTRUCTING (type) = TYPE_NEEDS_CONSTRUCTING (elt_type);
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type);
    }

  return failure;
}

/* As above, but either give an error or reject zero-size arrays, depending
   on COMPLAIN.  */

int
cp_complete_array_type_or_error (tree *ptype, tree initial_value,
				 bool do_default, tsubst_flags_t complain)
{
  int failure;
  bool sfinae = !(complain & tf_error);
  /* In SFINAE context we can't be lenient about zero-size arrays.  */
  if (sfinae)
    ++pedantic;
  failure = cp_complete_array_type (ptype, initial_value, do_default);
  if (sfinae)
    --pedantic;
  if (failure)
    {
      if (sfinae)
	/* Not an error.  */;
      else if (failure == 1)
	error ("initializer fails to determine size of %qT", *ptype);
      else if (failure == 2)
	{
	  if (do_default)
	    error ("array size missing in %qT", *ptype);
	}
      else if (failure == 3)
	error ("zero-size array %qT", *ptype);
      *ptype = error_mark_node;
    }
  return failure;
}

/* Return zero if something is declared to be a member of type
   CTYPE when in the context of CUR_TYPE.  STRING is the error
   message to print in that case.  Otherwise, quietly return 1.  */

static int
member_function_or_else (tree ctype, tree cur_type, enum overload_flags flags)
{
  if (ctype && ctype != cur_type)
    {
      if (flags == DTOR_FLAG)
	error ("destructor for alien class %qT cannot be a member", ctype);
      else
	error ("constructor for alien class %qT cannot be a member", ctype);
      return 0;
    }
  return 1;
}

/* Subroutine of `grokdeclarator'.  */

/* Generate errors possibly applicable for a given set of specifiers.
   This is for ARM $7.1.2.  */

static void
bad_specifiers (tree object,
		enum bad_spec_place type,
		int virtualp,
		int quals,
		int inlinep,
		int friendp,
		int raises,
		const location_t* locations)
{
  switch (type)
    {
      case BSP_VAR:
	if (virtualp)
	  error_at (locations[ds_virtual],
		    "%qD declared as a %<virtual%> variable", object);
	if (quals)
	  error ("%<const%> and %<volatile%> function specifiers on "
	         "%qD invalid in variable declaration", object);
	break;
      case BSP_PARM:
	if (virtualp)
	  error_at (locations[ds_virtual],
		    "%qD declared as a %<virtual%> parameter", object);
	if (inlinep)
	  error_at (locations[ds_inline],
		    "%qD declared as an %<inline%> parameter", object);
	if (quals)
	  error ("%<const%> and %<volatile%> function specifiers on "
	  	 "%qD invalid in parameter declaration", object);
	break;
      case BSP_TYPE:
	if (virtualp)
	  error_at (locations[ds_virtual],
		    "%qD declared as a %<virtual%> type", object);
	if (inlinep)
	  error_at (locations[ds_inline],
		    "%qD declared as an %<inline%> type", object);
	if (quals)
	  error ("%<const%> and %<volatile%> function specifiers on "
	  	 "%qD invalid in type declaration", object);
	break;
      case BSP_FIELD:
	if (virtualp)
	  error_at (locations[ds_virtual],
		    "%qD declared as a %<virtual%> field", object);
	if (inlinep)
	  error_at (locations[ds_inline],
		    "%qD declared as an %<inline%> field", object);
	if (quals)
	  error ("%<const%> and %<volatile%> function specifiers on "
	  	 "%qD invalid in field declaration", object);
	break;
      default:
        gcc_unreachable();
    }
  if (friendp)
    error ("%q+D declared as a friend", object);
  if (raises
      && !flag_noexcept_type
      && (TREE_CODE (object) == TYPE_DECL
	  || (!TYPE_PTRFN_P (TREE_TYPE (object))
	      && !TYPE_REFFN_P (TREE_TYPE (object))
	      && !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))))
    error ("%q+D declared with an exception specification", object);
}

/* DECL is a member function or static data member and is presently
   being defined.  Check that the definition is taking place in a
   valid namespace.  */

static void
check_class_member_definition_namespace (tree decl)
{
  /* These checks only apply to member functions and static data
     members.  */
  gcc_assert (VAR_OR_FUNCTION_DECL_P (decl));
  /* We check for problems with specializations in pt.c in
     check_specialization_namespace, where we can issue better
     diagnostics.  */
  if (processing_specialization)
    return;
  /* We check this in check_explicit_instantiation_namespace.  */
  if (processing_explicit_instantiation)
    return;
  /* [class.mfct]

     A member function definition that appears outside of the
     class definition shall appear in a namespace scope enclosing
     the class definition.

     [class.static.data]

     The definition for a static data member shall appear in a
     namespace scope enclosing the member's class definition.  */
  if (!is_ancestor (current_namespace, DECL_CONTEXT (decl)))
    permerror (input_location, "definition of %qD is not in namespace enclosing %qT",
	       decl, DECL_CONTEXT (decl));
}

/* Build a PARM_DECL for the "this" parameter of FN.  TYPE is the
   METHOD_TYPE for a non-static member function; QUALS are the
   cv-qualifiers that apply to the function.  */

tree
build_this_parm (tree fn, tree type, cp_cv_quals quals)
{
  tree this_type;
  tree qual_type;
  tree parm;
  cp_cv_quals this_quals;

  if (CLASS_TYPE_P (type))
    {
      this_type
	= cp_build_qualified_type (type, quals & ~TYPE_QUAL_RESTRICT);
      this_type = build_pointer_type (this_type);
    }
  else
    this_type = type_of_this_parm (type);
  /* The `this' parameter is implicitly `const'; it cannot be
     assigned to.  */
  this_quals = (quals & TYPE_QUAL_RESTRICT) | TYPE_QUAL_CONST;
  qual_type = cp_build_qualified_type (this_type, this_quals);
  parm = build_artificial_parm (fn, this_identifier, qual_type);
  cp_apply_type_quals_to_decl (this_quals, parm);
  return parm;
}

/* DECL is a static member function.  Complain if it was declared
   with function-cv-quals.  */

static void
check_static_quals (tree decl, cp_cv_quals quals)
{
  if (quals != TYPE_UNQUALIFIED)
    error ("static member function %q#D declared with type qualifiers",
	   decl);
}

// Check that FN takes no arguments and returns bool.
static void
check_concept_fn (tree fn)
{
  // A constraint is nullary.
  if (DECL_ARGUMENTS (fn))
    error_at (DECL_SOURCE_LOCATION (fn),
	      "concept %q#D declared with function parameters", fn);

  // The declared return type of the concept shall be bool, and
  // it shall not be deduced from it definition.
  tree type = TREE_TYPE (TREE_TYPE (fn));
  if (is_auto (type))
    error_at (DECL_SOURCE_LOCATION (fn),
	      "concept %q#D declared with a deduced return type", fn);
  else if (type != boolean_type_node)
    error_at (DECL_SOURCE_LOCATION (fn),
	      "concept %q#D with non-%<bool%> return type %qT", fn, type);
}

/* Helper function.  Replace the temporary this parameter injected
   during cp_finish_omp_declare_simd with the real this parameter.  */

static tree
declare_simd_adjust_this (tree *tp, int *walk_subtrees, void *data)
{
  tree this_parm = (tree) data;
  if (TREE_CODE (*tp) == PARM_DECL
      && DECL_NAME (*tp) == this_identifier
      && *tp != this_parm)
    *tp = this_parm;
  else if (TYPE_P (*tp))
    *walk_subtrees = 0;
  return NULL_TREE;
}

/* CTYPE is class type, or null if non-class.
   TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE
   or METHOD_TYPE.
   DECLARATOR is the function's name.
   PARMS is a chain of PARM_DECLs for the function.
   VIRTUALP is truthvalue of whether the function is virtual or not.
   FLAGS are to be passed through to `grokclassfn'.
   QUALS are qualifiers indicating whether the function is `const'
   or `volatile'.
   RAISES is a list of exceptions that this function can raise.
   CHECK is 1 if we must find this method in CTYPE, 0 if we should
   not look, and -1 if we should not call `grokclassfn' at all.

   SFK is the kind of special function (if any) for the new function.

   Returns `NULL_TREE' if something goes wrong, after issuing
   applicable error messages.  */

static tree
grokfndecl (tree ctype,
	    tree type,
	    tree declarator,
	    tree parms,
	    tree orig_declarator,
	    const cp_decl_specifier_seq *declspecs,
	    tree decl_reqs,
	    int virtualp,
	    enum overload_flags flags,
	    cp_cv_quals quals,
	    cp_ref_qualifier rqual,
	    tree raises,
	    int check,
	    int friendp,
	    int publicp,
	    int inlinep,
	    bool deletedp,
	    special_function_kind sfk,
	    bool funcdef_flag,
	    bool late_return_type_p,
	    int template_count,
	    tree in_namespace,
	    tree* attrlist,
	    location_t location)
{
  tree decl;
  int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE;
  tree t;

  if (location == UNKNOWN_LOCATION)
    location = input_location;

  // Was the concept specifier present?
  bool concept_p = inlinep & 4;

  // Concept declarations must have a corresponding definition.
  if (concept_p && !funcdef_flag)
    {
      error_at (location, "concept %qD has no definition", declarator);
      return NULL_TREE;
    }

  type = build_cp_fntype_variant (type, rqual, raises, late_return_type_p);

  decl = build_lang_decl_loc (location, FUNCTION_DECL, declarator, type);

  /* Set the constraints on the declaration. */
  if (flag_concepts)
    {
      tree tmpl_reqs = NULL_TREE;
      if (processing_template_decl > template_class_depth (ctype))
        tmpl_reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);

      /* Adjust the required expression into a constraint. */
      if (decl_reqs)
        decl_reqs = normalize_expression (decl_reqs);

      tree ci = build_constraints (tmpl_reqs, decl_reqs);
      set_constraints (decl, ci);
    }

  if (TREE_CODE (type) == METHOD_TYPE)
    {
      tree parm = build_this_parm (decl, type, quals);
      DECL_CHAIN (parm) = parms;
      parms = parm;

      /* Allocate space to hold the vptr bit if needed.  */
      SET_DECL_ALIGN (decl, MINIMUM_METHOD_BOUNDARY);
    }

  DECL_ARGUMENTS (decl) = parms;
  for (t = parms; t; t = DECL_CHAIN (t))
    DECL_CONTEXT (t) = decl;

  /* Propagate volatile out from type to decl.  */
  if (TYPE_VOLATILE (type))
    TREE_THIS_VOLATILE (decl) = 1;

  /* Setup decl according to sfk.  */
  switch (sfk)
    {
    case sfk_constructor:
    case sfk_copy_constructor:
    case sfk_move_constructor:
      DECL_CXX_CONSTRUCTOR_P (decl) = 1;
      DECL_NAME (decl) = ctor_identifier;
      break;
    case sfk_destructor:
      DECL_CXX_DESTRUCTOR_P (decl) = 1;
      DECL_NAME (decl) = dtor_identifier;
      break;
    default:
      break;
    }

  if (friendp && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)
    {
      if (funcdef_flag)
	error_at (location,
		  "defining explicit specialization %qD in friend declaration",
		  orig_declarator);
      else
	{
	  tree fns = TREE_OPERAND (orig_declarator, 0);
	  tree args = TREE_OPERAND (orig_declarator, 1);

	  if (PROCESSING_REAL_TEMPLATE_DECL_P ())
	    {
	      /* Something like `template <class T> friend void f<T>()'.  */
	      error_at (location,
			"invalid use of template-id %qD in declaration "
			"of primary template",
			orig_declarator);
	      return NULL_TREE;
	    }


	  /* A friend declaration of the form friend void f<>().  Record
	     the information in the TEMPLATE_ID_EXPR.  */
	  SET_DECL_IMPLICIT_INSTANTIATION (decl);

	  gcc_assert (identifier_p (fns)
		      || TREE_CODE (fns) == OVERLOAD
		      || TREE_CODE (fns) == FUNCTION_DECL);
	  DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);

	  for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t))
	    if (TREE_PURPOSE (t)
		&& TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG)
	    {
	      error_at (defarg_location (TREE_PURPOSE (t)),
			"default arguments are not allowed in declaration "
			"of friend template specialization %qD",
			decl);
	      return NULL_TREE;
	    }

	  if (inlinep & 1)
	    {
	      error_at (declspecs->locations[ds_inline],
			"%<inline%> is not allowed in declaration of friend "
			"template specialization %qD",
			decl);
	      return NULL_TREE;
	    }
	}
    }

  /* C++17 11.3.6/4: "If a friend declaration specifies a default argument
     expression, that declaration shall be a definition..."  */
  if (friendp && !funcdef_flag)
    {
      for (tree t = FUNCTION_FIRST_USER_PARMTYPE (decl);
	   t && t != void_list_node; t = TREE_CHAIN (t))
	if (TREE_PURPOSE (t))
	  {
	    permerror (DECL_SOURCE_LOCATION (decl),
		       "friend declaration of %qD specifies default "
		       "arguments and isn't a definition", decl);
	    break;
	  }
    }

  /* If this decl has namespace scope, set that up.  */
  if (in_namespace)
    set_decl_namespace (decl, in_namespace, friendp);
  else if (!ctype)
    DECL_CONTEXT (decl) = FROB_CONTEXT (current_decl_namespace ());

  /* `main' and builtins have implicit 'C' linkage.  */
  if (ctype == NULL_TREE
      && DECL_FILE_SCOPE_P (decl)
      && current_lang_name == lang_name_cplusplus
      && (MAIN_NAME_P (declarator)
	  || (IDENTIFIER_LENGTH (declarator) > 10
	      && IDENTIFIER_POINTER (declarator)[0] == '_'
	      && IDENTIFIER_POINTER (declarator)[1] == '_'
	      && strncmp (IDENTIFIER_POINTER (declarator)+2,
			  "builtin_", 8) == 0)
	  || (targetcm.cxx_implicit_extern_c
	      && (targetcm.cxx_implicit_extern_c
		  (IDENTIFIER_POINTER (declarator))))))
    SET_DECL_LANGUAGE (decl, lang_c);

  /* Should probably propagate const out from type to decl I bet (mrs).  */
  if (staticp)
    {
      DECL_STATIC_FUNCTION_P (decl) = 1;
      DECL_CONTEXT (decl) = ctype;
    }

  if (deletedp)
    DECL_DELETED_FN (decl) = 1;

  if (ctype)
    {
      DECL_CONTEXT (decl) = ctype;
      if (funcdef_flag)
	check_class_member_definition_namespace (decl);
    }

  if (ctype == NULL_TREE && DECL_MAIN_P (decl))
    {
      if (PROCESSING_REAL_TEMPLATE_DECL_P())
	error_at (location, "cannot declare %<::main%> to be a template");
      if (inlinep & 1)
	error_at (declspecs->locations[ds_inline],
		  "cannot declare %<::main%> to be inline");
      if (inlinep & 2)
	error_at (declspecs->locations[ds_constexpr],
		  "cannot declare %<::main%> to be %<constexpr%>");
      if (!publicp)
	error_at (location, "cannot declare %<::main%> to be static");
      inlinep = 0;
      publicp = 1;
    }

  /* Members of anonymous types and local classes have no linkage; make
     them internal.  If a typedef is made later, this will be changed.  */
  if (ctype && (!TREE_PUBLIC (TYPE_MAIN_DECL (ctype))
		|| decl_function_context (TYPE_MAIN_DECL (ctype))))
    publicp = 0;

  if (publicp && cxx_dialect == cxx98)
    {
      /* [basic.link]: A name with no linkage (notably, the name of a class
	 or enumeration declared in a local scope) shall not be used to
	 declare an entity with linkage.

	 DR 757 relaxes this restriction for C++0x.  */
      no_linkage_error (decl);
    }

  TREE_PUBLIC (decl) = publicp;
  if (! publicp)
    {
      DECL_INTERFACE_KNOWN (decl) = 1;
      DECL_NOT_REALLY_EXTERN (decl) = 1;
    }

  /* If the declaration was declared inline, mark it as such.  */
  if (inlinep)
    {
      DECL_DECLARED_INLINE_P (decl) = 1;
      if (publicp)
	DECL_COMDAT (decl) = 1;
    }
  if (inlinep & 2)
    DECL_DECLARED_CONSTEXPR_P (decl) = true;

  // If the concept declaration specifier was found, check
  // that the declaration satisfies the necessary requirements.
  if (concept_p)
    {
      DECL_DECLARED_CONCEPT_P (decl) = true;
      check_concept_fn (decl);
    }

  DECL_EXTERNAL (decl) = 1;
  if (TREE_CODE (type) == FUNCTION_TYPE)
    {
      if (quals || rqual)
	TREE_TYPE (decl) = apply_memfn_quals (TREE_TYPE (decl),
					      TYPE_UNQUALIFIED,
					      REF_QUAL_NONE);

      if (quals)
	{
	  error (ctype
		 ? G_("static member function %qD cannot have cv-qualifier")
		 : G_("non-member function %qD cannot have cv-qualifier"),
		 decl);
	  quals = TYPE_UNQUALIFIED;
	}

      if (rqual)
	{
	  error (ctype
		 ? G_("static member function %qD cannot have ref-qualifier")
		 : G_("non-member function %qD cannot have ref-qualifier"),
		 decl);
	  rqual = REF_QUAL_NONE;
	}
    }

  if (deduction_guide_p (decl))
    {
      if (!DECL_NAMESPACE_SCOPE_P (decl))
	{
	  error_at (location, "deduction guide %qD must be declared at "
		    "namespace scope", decl);
	  return NULL_TREE;
	}
      if (funcdef_flag)
	error_at (location,
		  "deduction guide %qD must not have a function body", decl);
    }
  else if (IDENTIFIER_ANY_OP_P (DECL_NAME (decl))
	   && !grok_op_properties (decl, /*complain=*/true))
    return NULL_TREE;
  else if (UDLIT_OPER_P (DECL_NAME (decl)))
    {
      bool long_long_unsigned_p;
      bool long_double_p;
      const char *suffix = NULL;
      /* [over.literal]/6: Literal operators shall not have C linkage. */
      if (DECL_LANGUAGE (decl) == lang_c)
	{
	  error_at (location, "literal operator with C linkage");
	  maybe_show_extern_c_location ();
	  return NULL_TREE;
	}

      if (DECL_NAMESPACE_SCOPE_P (decl))
	{
	  if (!check_literal_operator_args (decl, &long_long_unsigned_p,
					    &long_double_p))
	    {
	      error_at (location, "%qD has invalid argument list", decl);
	      return NULL_TREE;
	    }

	  suffix = UDLIT_OP_SUFFIX (DECL_NAME (decl));
	  if (long_long_unsigned_p)
	    {
	      if (cpp_interpret_int_suffix (parse_in, suffix, strlen (suffix)))
		warning_at (location, 0, "integer suffix %qs"
			    " shadowed by implementation", suffix);
	    }
	  else if (long_double_p)
	    {
	      if (cpp_interpret_float_suffix (parse_in, suffix, strlen (suffix)))
		warning_at (location, 0, "floating point suffix %qs"
			    " shadowed by implementation", suffix);
	    }
	  /* 17.6.3.3.5  */
	  if (suffix[0] != '_'
	      && !in_system_header_at (location)
	      && !current_function_decl && !(friendp && !funcdef_flag))
	    warning_at (location, OPT_Wliteral_suffix,
			"literal operator suffixes not preceded by %<_%>"
			" are reserved for future standardization");
	}
      else
	{
	  error_at (location, "%qD must be a non-member function", decl);
	  return NULL_TREE;
	}
    }

  if (funcdef_flag)
    /* Make the init_value nonzero so pushdecl knows this is not
       tentative.  error_mark_node is replaced later with the BLOCK.  */
    DECL_INITIAL (decl) = error_mark_node;

  if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl))
    TREE_NOTHROW (decl) = 1;

  if (flag_openmp || flag_openmp_simd)
    {
      /* Adjust "omp declare simd" attributes.  */
      tree ods = lookup_attribute ("omp declare simd", *attrlist);
      if (ods)
	{
	  tree attr;
	  for (attr = ods; attr;
	       attr = lookup_attribute ("omp declare simd", TREE_CHAIN (attr)))
	    {
	      if (TREE_CODE (type) == METHOD_TYPE)
		walk_tree (&TREE_VALUE (attr), declare_simd_adjust_this,
			   DECL_ARGUMENTS (decl), NULL);
	      if (TREE_VALUE (attr) != NULL_TREE)
		{
		  tree cl = TREE_VALUE (TREE_VALUE (attr));
		  cl = c_omp_declare_simd_clauses_to_numbers
						(DECL_ARGUMENTS (decl), cl);
		  if (cl)
		    TREE_VALUE (TREE_VALUE (attr)) = cl;
		  else
		    TREE_VALUE (attr) = NULL_TREE;
		}
	    }
	}
    }

  /* Caller will do the rest of this.  */
  if (check < 0)
    return decl;

  if (ctype != NULL_TREE)
    grokclassfn (ctype, decl, flags);

  /* 12.4/3  */
  if (cxx_dialect >= cxx11
      && DECL_DESTRUCTOR_P (decl)
      && !TYPE_BEING_DEFINED (DECL_CONTEXT (decl))
      && !processing_template_decl)
    deduce_noexcept_on_destructor (decl);

  decl = check_explicit_specialization (orig_declarator, decl,
					template_count,
					2 * funcdef_flag +
					4 * (friendp != 0) +
	                                8 * concept_p,
					*attrlist);
  if (decl == error_mark_node)
    return NULL_TREE;

  if (DECL_STATIC_FUNCTION_P (decl))
    check_static_quals (decl, quals);

  if (attrlist)
    {
      cplus_decl_attributes (&decl, *attrlist, 0);
      *attrlist = NULL_TREE;
    }

  /* Check main's type after attributes have been applied.  */
  if (ctype == NULL_TREE && DECL_MAIN_P (decl))
    {
      if (!same_type_p (TREE_TYPE (TREE_TYPE (decl)),
			integer_type_node))
	{
	  tree oldtypeargs = TYPE_ARG_TYPES (TREE_TYPE (decl));
	  tree newtype;
	  error_at (declspecs->locations[ds_type_spec],
		    "%<::main%> must return %<int%>");
	  newtype = build_function_type (integer_type_node, oldtypeargs);
	  TREE_TYPE (decl) = newtype;
	}
      if (warn_main)
	check_main_parameter_types (decl);
    }

  if (ctype != NULL_TREE && check)
    {
      tree old_decl = check_classfn (ctype, decl,
				     (processing_template_decl
				      > template_class_depth (ctype))
				     ? current_template_parms
				     : NULL_TREE);

      if (old_decl == error_mark_node)
	return NULL_TREE;

      if (old_decl)
	{
	  tree ok;
	  tree pushed_scope;

	  if (TREE_CODE (old_decl) == TEMPLATE_DECL)
	    /* Because grokfndecl is always supposed to return a
	       FUNCTION_DECL, we pull out the DECL_TEMPLATE_RESULT
	       here.  We depend on our callers to figure out that its
	       really a template that's being returned.  */
	    old_decl = DECL_TEMPLATE_RESULT (old_decl);

	  if (DECL_STATIC_FUNCTION_P (old_decl)
	      && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
	    {
	      /* Remove the `this' parm added by grokclassfn.  */
	      revert_static_member_fn (decl);
	      check_static_quals (decl, quals);
	    }
	  if (DECL_ARTIFICIAL (old_decl))
	    {
	      error ("definition of implicitly-declared %qD", old_decl);
	      return NULL_TREE;
	    }
	  else if (DECL_DEFAULTED_FN (old_decl))
	    {
	      error ("definition of explicitly-defaulted %q+D", decl);
	      inform (DECL_SOURCE_LOCATION (old_decl),
		      "%q#D explicitly defaulted here", old_decl);
	      return NULL_TREE;
	    }

	  /* Since we've smashed OLD_DECL to its
	     DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
	  if (TREE_CODE (decl) == TEMPLATE_DECL)
	    decl = DECL_TEMPLATE_RESULT (decl);

	  /* Attempt to merge the declarations.  This can fail, in
	     the case of some invalid specialization declarations.  */
	  pushed_scope = push_scope (ctype);
	  ok = duplicate_decls (decl, old_decl, friendp);
	  if (pushed_scope)
	    pop_scope (pushed_scope);
	  if (!ok)
	    {
	      error ("no %q#D member function declared in class %qT",
		     decl, ctype);
	      return NULL_TREE;
	    }
	  if (ok == error_mark_node)
	    return NULL_TREE;
	  return old_decl;
	}
    }

  if (DECL_CONSTRUCTOR_P (decl) && !grok_ctor_properties (ctype, decl))
    return NULL_TREE;

  if (ctype == NULL_TREE || check)
    return decl;

  if (virtualp)
    DECL_VIRTUAL_P (decl) = 1;

  return decl;
}

/* decl is a FUNCTION_DECL.
   specifiers are the parsed virt-specifiers.

   Set flags to reflect the virt-specifiers.

   Returns decl.  */

static tree
set_virt_specifiers (tree decl, cp_virt_specifiers specifiers)
{
  if (decl == NULL_TREE)
    return decl;
  if (specifiers & VIRT_SPEC_OVERRIDE)
    DECL_OVERRIDE_P (decl) = 1;
  if (specifiers & VIRT_SPEC_FINAL)
    DECL_FINAL_P (decl) = 1;
  return decl;
}

/* DECL is a VAR_DECL for a static data member.  Set flags to reflect
   the linkage that DECL will receive in the object file.  */

static void
set_linkage_for_static_data_member (tree decl)
{
  /* A static data member always has static storage duration and
     external linkage.  Note that static data members are forbidden in
     local classes -- the only situation in which a class has
     non-external linkage.  */
  TREE_PUBLIC (decl) = 1;
  TREE_STATIC (decl) = 1;
  /* For non-template classes, static data members are always put
     out in exactly those files where they are defined, just as
     with ordinary namespace-scope variables.  */
  if (!processing_template_decl)
    DECL_INTERFACE_KNOWN (decl) = 1;
}

/* Create a VAR_DECL named NAME with the indicated TYPE.

   If SCOPE is non-NULL, it is the class type or namespace containing
   the variable.  If SCOPE is NULL, the variable should is created in
   the innermost enclosing scope.  */

static tree
grokvardecl (tree type,
	     tree name,
	     tree orig_declarator,
	     const cp_decl_specifier_seq *declspecs,
	     int initialized,
	     int type_quals,
	     int inlinep,
	     bool conceptp,
	     int template_count,
	     tree scope)
{
  tree decl;
  tree explicit_scope;

  gcc_assert (!name || identifier_p (name));

  bool constp = (type_quals & TYPE_QUAL_CONST) != 0;
  bool volatilep = (type_quals & TYPE_QUAL_VOLATILE) != 0;

  /* Compute the scope in which to place the variable, but remember
     whether or not that scope was explicitly specified by the user.   */
  explicit_scope = scope;
  if (!scope)
    {
      /* An explicit "extern" specifier indicates a namespace-scope
	 variable.  */
      if (declspecs->storage_class == sc_extern)
	scope = current_decl_namespace ();
      else if (!at_function_scope_p ())
	scope = current_scope ();
    }

  if (scope
      && (/* If the variable is a namespace-scope variable declared in a
	     template, we need DECL_LANG_SPECIFIC.  */
	  (TREE_CODE (scope) == NAMESPACE_DECL && processing_template_decl)
	  /* Similarly for namespace-scope variables with language linkage
	     other than C++.  */
	  || (TREE_CODE (scope) == NAMESPACE_DECL
	      && current_lang_name != lang_name_cplusplus)
	  /* Similarly for static data members.  */
	  || TYPE_P (scope)
	  /* Similarly for explicit specializations.  */
	  || (orig_declarator
	      && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR)))
    decl = build_lang_decl (VAR_DECL, name, type);
  else
    decl = build_decl (input_location, VAR_DECL, name, type);

  if (explicit_scope && TREE_CODE (explicit_scope) == NAMESPACE_DECL)
    set_decl_namespace (decl, explicit_scope, 0);
  else
    DECL_CONTEXT (decl) = FROB_CONTEXT (scope);

  if (declspecs->storage_class == sc_extern)
    {
      DECL_THIS_EXTERN (decl) = 1;
      DECL_EXTERNAL (decl) = !initialized;
    }

  if (DECL_CLASS_SCOPE_P (decl))
    {
      set_linkage_for_static_data_member (decl);
      /* This function is only called with out-of-class definitions.  */
      DECL_EXTERNAL (decl) = 0;
      check_class_member_definition_namespace (decl);
    }
  /* At top level, either `static' or no s.c. makes a definition
     (perhaps tentative), and absence of `static' makes it public.  */
  else if (toplevel_bindings_p ())
    {
      TREE_PUBLIC (decl) = (declspecs->storage_class != sc_static
			    && (DECL_THIS_EXTERN (decl)
				|| ! constp
				|| volatilep
				|| inlinep));
      TREE_STATIC (decl) = ! DECL_EXTERNAL (decl);
    }
  /* Not at top level, only `static' makes a static definition.  */
  else
    {
      TREE_STATIC (decl) = declspecs->storage_class == sc_static;
      TREE_PUBLIC (decl) = DECL_EXTERNAL (decl);
    }

  if (decl_spec_seq_has_spec_p (declspecs, ds_thread))
    {
      if (DECL_EXTERNAL (decl) || TREE_STATIC (decl))
	{
	  CP_DECL_THREAD_LOCAL_P (decl) = true;
	  if (!processing_template_decl)
	    set_decl_tls_model (decl, decl_default_tls_model (decl));
	}
      if (declspecs->gnu_thread_keyword_p)
	SET_DECL_GNU_TLS_P (decl);
    }

  /* If the type of the decl has no linkage, make sure that we'll
     notice that in mark_used.  */
  if (cxx_dialect > cxx98
      && decl_linkage (decl) != lk_none
      && DECL_LANG_SPECIFIC (decl) == NULL
      && !DECL_EXTERN_C_P (decl)
      && no_linkage_check (TREE_TYPE (decl), /*relaxed_p=*/false))
    retrofit_lang_decl (decl);

  if (TREE_PUBLIC (decl))
    {
      /* [basic.link]: A name with no linkage (notably, the name of a class
	 or enumeration declared in a local scope) shall not be used to
	 declare an entity with linkage.

	 DR 757 relaxes this restriction for C++0x.  */
      if (cxx_dialect < cxx11)
	no_linkage_error (decl);
    }
  else
    DECL_INTERFACE_KNOWN (decl) = 1;

  if (DECL_NAME (decl)
      && MAIN_NAME_P (DECL_NAME (decl))
      && scope == global_namespace)
    error ("cannot declare %<::main%> to be a global variable");

  /* Check that the variable can be safely declared as a concept.
     Note that this also forbids explicit specializations.  */
  if (conceptp)
    {
      if (!processing_template_decl)
        {
          error_at (declspecs->locations[ds_concept],
		    "a non-template variable cannot be %<concept%>");
          return NULL_TREE;
        }
      else
        DECL_DECLARED_CONCEPT_P (decl) = true;
      if (!same_type_ignoring_top_level_qualifiers_p (type, boolean_type_node))
	error_at (declspecs->locations[ds_type_spec],
		  "concept must have type %<bool%>");
    }
  else if (flag_concepts
	   && processing_template_decl > template_class_depth (scope))
    {
      tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
      tree ci = build_constraints (reqs, NULL_TREE);
      set_constraints (decl, ci);
    }

  // Handle explicit specializations and instantiations of variable templates.
  if (orig_declarator)
    decl = check_explicit_specialization (orig_declarator, decl,
					  template_count, conceptp * 8);

  return decl != error_mark_node ? decl : NULL_TREE;
}

/* Create and return a canonical pointer to member function type, for
   TYPE, which is a POINTER_TYPE to a METHOD_TYPE.  */

tree
build_ptrmemfunc_type (tree type)
{
  tree field, fields;
  tree t;

  if (type == error_mark_node)
    return type;

  /* Make sure that we always have the unqualified pointer-to-member
     type first.  */
  if (cp_cv_quals quals = cp_type_quals (type))
    {
      tree unqual = build_ptrmemfunc_type (TYPE_MAIN_VARIANT (type));
      return cp_build_qualified_type (unqual, quals);
    }

  /* If a canonical type already exists for this type, use it.  We use
     this method instead of type_hash_canon, because it only does a
     simple equality check on the list of field members.  */

  t = TYPE_PTRMEMFUNC_TYPE (type);
  if (t)
    return t;

  t = make_node (RECORD_TYPE);

  /* Let the front end know this is a pointer to member function.  */
  TYPE_PTRMEMFUNC_FLAG (t) = 1;

  field = build_decl (input_location, FIELD_DECL, pfn_identifier, type);
  fields = field;

  field = build_decl (input_location, FIELD_DECL, delta_identifier, 
		      delta_type_node);
  DECL_CHAIN (field) = fields;
  fields = field;

  finish_builtin_struct (t, "__ptrmemfunc_type", fields, ptr_type_node);

  /* Zap out the name so that the back end will give us the debugging
     information for this anonymous RECORD_TYPE.  */
  TYPE_NAME (t) = NULL_TREE;

  /* Cache this pointer-to-member type so that we can find it again
     later.  */
  TYPE_PTRMEMFUNC_TYPE (type) = t;

  if (TYPE_STRUCTURAL_EQUALITY_P (type))
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (TYPE_CANONICAL (type) != type)
    TYPE_CANONICAL (t) = build_ptrmemfunc_type (TYPE_CANONICAL (type));

  return t;
}

/* Create and return a pointer to data member type.  */

tree
build_ptrmem_type (tree class_type, tree member_type)
{
  if (TREE_CODE (member_type) == METHOD_TYPE)
    {
      cp_cv_quals quals = type_memfn_quals (member_type);
      cp_ref_qualifier rqual = type_memfn_rqual (member_type);
      member_type = build_memfn_type (member_type, class_type, quals, rqual);
      return build_ptrmemfunc_type (build_pointer_type (member_type));
    }
  else
    {
      gcc_assert (TREE_CODE (member_type) != FUNCTION_TYPE);
      return build_offset_type (class_type, member_type);
    }
}

/* DECL is a VAR_DECL defined in-class, whose TYPE is also given.
   Check to see that the definition is valid.  Issue appropriate error
   messages.  */

static void
check_static_variable_definition (tree decl, tree type)
{
  /* Avoid redundant diagnostics on out-of-class definitions.  */
  if (!current_class_type || !TYPE_BEING_DEFINED (current_class_type))
    ;
  /* Can't check yet if we don't know the type.  */
  else if (dependent_type_p (type))
    ;
  /* If DECL is declared constexpr, we'll do the appropriate checks
     in check_initializer.  Similarly for inline static data members.  */
  else if (DECL_P (decl)
      && (DECL_DECLARED_CONSTEXPR_P (decl)
	  || undeduced_auto_decl (decl)
	  || DECL_VAR_DECLARED_INLINE_P (decl)))
    ;
  else if (cxx_dialect >= cxx11 && !INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    {
      if (!COMPLETE_TYPE_P (type))
	error_at (DECL_SOURCE_LOCATION (decl),
		  "in-class initialization of static data member %q#D of "
		  "incomplete type", decl);
      else if (literal_type_p (type))
	permerror (DECL_SOURCE_LOCATION (decl),
		   "%<constexpr%> needed for in-class initialization of "
		   "static data member %q#D of non-integral type", decl);
      else
	error_at (DECL_SOURCE_LOCATION (decl),
		  "in-class initialization of static data member %q#D of "
		  "non-literal type", decl);
    }
  /* Motion 10 at San Diego: If a static const integral data member is
     initialized with an integral constant expression, the initializer
     may appear either in the declaration (within the class), or in
     the definition, but not both.  If it appears in the class, the
     member is a member constant.  The file-scope definition is always
     required.  */
  else if (!ARITHMETIC_TYPE_P (type) && TREE_CODE (type) != ENUMERAL_TYPE)
    error_at (DECL_SOURCE_LOCATION (decl),
	      "invalid in-class initialization of static data member "
	      "of non-integral type %qT",
	      type);
  else if (!CP_TYPE_CONST_P (type))
    error_at (DECL_SOURCE_LOCATION (decl),
	      "ISO C++ forbids in-class initialization of non-const "
	      "static member %qD",
	      decl);
  else if (!INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
	     "ISO C++ forbids initialization of member constant "
	     "%qD of non-integral type %qT", decl, type);
}

/* *expr_p is part of the TYPE_SIZE of a variably-sized array.  If any
   SAVE_EXPRs in *expr_p wrap expressions with side-effects, break those
   expressions out into temporary variables so that walk_tree doesn't
   step into them (c++/15764).  */

static tree
stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
{
  hash_set<tree> *pset = (hash_set<tree> *)data;
  tree expr = *expr_p;
  if (TREE_CODE (expr) == SAVE_EXPR)
    {
      tree op = TREE_OPERAND (expr, 0);
      cp_walk_tree (&op, stabilize_save_expr_r, data, pset);
      if (TREE_SIDE_EFFECTS (op))
	TREE_OPERAND (expr, 0) = get_temp_regvar (TREE_TYPE (op), op);
      *walk_subtrees = 0;
    }
  else if (!EXPR_P (expr) || !TREE_SIDE_EFFECTS (expr))
    *walk_subtrees = 0;
  return NULL;
}

/* Entry point for the above.  */

static void
stabilize_vla_size (tree size)
{
  hash_set<tree> pset;
  /* Break out any function calls into temporary variables.  */
  cp_walk_tree (&size, stabilize_save_expr_r, &pset, &pset);
}

/* Reduce a SIZEOF_EXPR to its value.  */

tree
fold_sizeof_expr (tree t)
{
  tree r;
  if (SIZEOF_EXPR_TYPE_P (t))
    r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
				    SIZEOF_EXPR, false, false);
  else if (TYPE_P (TREE_OPERAND (t, 0)))
    r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
				    false, false);
  else
    r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
				    false);
  if (r == error_mark_node)
    r = size_one_node;
  return r;
}

/* Given the SIZE (i.e., number of elements) in an array, compute
   an appropriate index type for the array.  If non-NULL, NAME is
   the name of the entity being declared.  */

static tree
compute_array_index_type_loc (location_t name_loc, tree name, tree size,
			      tsubst_flags_t complain)
{
  tree itype;
  tree osize = size;

  if (error_operand_p (size))
    return error_mark_node;

  location_t loc = cp_expr_loc_or_loc (size, name ? name_loc : input_location);

  if (!type_dependent_expression_p (size))
    {
      osize = size = mark_rvalue_use (size);

      if (cxx_dialect < cxx11 && TREE_CODE (size) == NOP_EXPR
	  && TREE_SIDE_EFFECTS (size))
	/* In C++98, we mark a non-constant array bound with a magic
	   NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case.  */;
      else
	{
	  size = instantiate_non_dependent_expr_sfinae (size, complain);
	  size = build_converted_constant_expr (size_type_node, size, complain);
	  size = maybe_constant_value (size);

	  if (!TREE_CONSTANT (size))
	    size = osize;
	}

      if (error_operand_p (size))
	return error_mark_node;

      /* The array bound must be an integer type.  */
      tree type = TREE_TYPE (size);
      if (!INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
	{
	  if (!(complain & tf_error))
	    return error_mark_node;
	  if (name)
	    error_at (loc, "size of array %qD has non-integral type %qT",
		      name, type);
	  else
	    error_at (loc, "size of array has non-integral type %qT", type);
	  size = integer_one_node;
	}
    }

  /* A type is dependent if it is...an array type constructed from any
     dependent type or whose size is specified by a constant expression
     that is value-dependent.  */
  /* We can only call value_dependent_expression_p on integral constant
     expressions; treat non-constant expressions as dependent, too.  */
  if (processing_template_decl
      && (type_dependent_expression_p (size)
	  || !TREE_CONSTANT (size) || value_dependent_expression_p (size)))
    {
      /* We cannot do any checking for a SIZE that isn't known to be
	 constant. Just build the index type and mark that it requires
	 structural equality checks.  */
      itype = build_index_type (build_min (MINUS_EXPR, sizetype,
					   size, size_one_node));
      TYPE_DEPENDENT_P (itype) = 1;
      TYPE_DEPENDENT_P_VALID (itype) = 1;
      SET_TYPE_STRUCTURAL_EQUALITY (itype);
      return itype;
    }

  if (TREE_CODE (size) != INTEGER_CST)
    {
      tree folded = cp_fully_fold (size);
      if (TREE_CODE (folded) == INTEGER_CST)
	{
	  if (name)
	    pedwarn (loc, OPT_Wpedantic, "size of array %qD is not an "
		     "integral constant-expression", name);
	  else
	    pedwarn (loc, OPT_Wpedantic,
		     "size of array is not an integral constant-expression");
	}
      /* Use the folded result for VLAs, too; it will have resolved
	 SIZEOF_EXPR.  */
      size = folded;
    }

  /* Normally, the array-bound will be a constant.  */
  if (TREE_CODE (size) == INTEGER_CST)
    {
      /* An array must have a positive number of elements.  */
      if (!valid_constant_size_p (size))
	{
	  if (!(complain & tf_error))
	    return error_mark_node;

	  if (name)
	    error_at (loc, "size of array %qD is negative", name);
	  else
	    error_at (loc, "size of array is negative");
	  size = integer_one_node;
	}
      /* As an extension we allow zero-sized arrays.  */
      else if (integer_zerop (size))
	{
	  if (!(complain & tf_error))
	    /* We must fail if performing argument deduction (as
	       indicated by the state of complain), so that
	       another substitution can be found.  */
	    return error_mark_node;
	  else if (in_system_header_at (input_location))
	    /* Allow them in system headers because glibc uses them.  */;
	  else if (name)
	    pedwarn (loc, OPT_Wpedantic,
		     "ISO C++ forbids zero-size array %qD", name);
	  else
	    pedwarn (loc, OPT_Wpedantic,
		     "ISO C++ forbids zero-size array");
	}
    }
  else if (TREE_CONSTANT (size)
	   /* We don't allow VLAs at non-function scopes, or during
	      tentative template substitution.  */
	   || !at_function_scope_p ()
	   || !(complain & tf_error))
    {
      if (!(complain & tf_error))
	return error_mark_node;
      /* `(int) &fn' is not a valid array bound.  */
      if (name)
	error_at (loc,
		  "size of array %qD is not an integral constant-expression",
		  name);
      else
	error_at (loc, "size of array is not an integral constant-expression");
      size = integer_one_node;
    }
  else if (pedantic && warn_vla != 0)
    {
      if (name)
	pedwarn (name_loc, OPT_Wvla,
		 "ISO C++ forbids variable length array %qD", name);
      else
	pedwarn (input_location, OPT_Wvla,
		 "ISO C++ forbids variable length array");
    }
  else if (warn_vla > 0)
    {
      if (name)
	warning_at (name_loc, OPT_Wvla, 
		    "variable length array %qD is used", name);
      else
	warning (OPT_Wvla, 
                 "variable length array is used");
    }

  if (processing_template_decl && !TREE_CONSTANT (size))
    /* A variable sized array.  */
    itype = build_min (MINUS_EXPR, sizetype, size, integer_one_node);
  else
    {
      /* Compute the index of the largest element in the array.  It is
	 one less than the number of elements in the array.  We save
	 and restore PROCESSING_TEMPLATE_DECL so that computations in
	 cp_build_binary_op will be appropriately folded.  */
      {
	processing_template_decl_sentinel s;
	itype = cp_build_binary_op (input_location,
				    MINUS_EXPR,
				    cp_convert (ssizetype, size, complain),
				    cp_convert (ssizetype, integer_one_node,
						complain),
				    complain);
	itype = maybe_constant_value (itype);
      }

      if (!TREE_CONSTANT (itype))
	{
	  /* A variable sized array.  */
	  itype = variable_size (itype);

	  stabilize_vla_size (itype);

	  if (sanitize_flags_p (SANITIZE_VLA)
	      && current_function_decl != NULL_TREE)
	    {
	      /* We have to add 1 -- in the ubsan routine we generate
		 LE_EXPR rather than LT_EXPR.  */
	      tree t = fold_build2 (PLUS_EXPR, TREE_TYPE (itype), itype,
				    build_one_cst (TREE_TYPE (itype)));
	      t = ubsan_instrument_vla (input_location, t);
	      finish_expr_stmt (t);
	    }
	}
      /* Make sure that there was no overflow when creating to a signed
	 index type.  (For example, on a 32-bit machine, an array with
	 size 2^32 - 1 is too big.)  */
      else if (TREE_CODE (itype) == INTEGER_CST
	       && TREE_OVERFLOW (itype))
	{
	  if (!(complain & tf_error))
	    return error_mark_node;
	  error ("overflow in array dimension");
	  TREE_OVERFLOW (itype) = 0;
	}
    }

  /* Create and return the appropriate index type.  */
  itype = build_index_type (itype);

  /* If the index type were dependent, we would have returned early, so
     remember that it isn't.  */
  TYPE_DEPENDENT_P (itype) = 0;
  TYPE_DEPENDENT_P_VALID (itype) = 1;
  return itype;
}

tree
compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
{
  return compute_array_index_type_loc (input_location, name, size, complain);
}

/* Returns the scope (if any) in which the entity declared by
   DECLARATOR will be located.  If the entity was declared with an
   unqualified name, NULL_TREE is returned.  */

tree
get_scope_of_declarator (const cp_declarator *declarator)
{
  while (declarator && declarator->kind != cdk_id)
    declarator = declarator->declarator;

  /* If the declarator-id is a SCOPE_REF, the scope in which the
     declaration occurs is the first operand.  */
  if (declarator
      && declarator->u.id.qualifying_scope)
    return declarator->u.id.qualifying_scope;

  /* Otherwise, the declarator is not a qualified name; the entity will
     be declared in the current scope.  */
  return NULL_TREE;
}

/* Returns an ARRAY_TYPE for an array with SIZE elements of the
   indicated TYPE.  If non-NULL, NAME is the NAME of the declaration
   with this type.  */

static tree
create_array_type_for_decl (tree name, tree type, tree size, location_t loc)
{
  tree itype = NULL_TREE;

  /* If things have already gone awry, bail now.  */
  if (type == error_mark_node || size == error_mark_node)
    return error_mark_node;

  /* 8.3.4/1: If the type of the identifier of D contains the auto
     type-specifier, the program is ill-formed.  */
  if (type_uses_auto (type))
    {
      if (name)
	error_at (loc, "%qD declared as array of %qT", name, type);
      else
	error ("creating array of %qT", type);
      return error_mark_node;
    }

  /* If there are some types which cannot be array elements,
     issue an error-message and return.  */
  switch (TREE_CODE (type))
    {
    case VOID_TYPE:
      if (name)
	error_at (loc, "declaration of %qD as array of void", name);
      else
        error ("creating array of void");
      return error_mark_node;

    case FUNCTION_TYPE:
      if (name)
	error_at (loc, "declaration of %qD as array of functions", name);
      else
        error ("creating array of functions");
      return error_mark_node;

    case REFERENCE_TYPE:
      if (name)
	error_at (loc, "declaration of %qD as array of references", name);
      else
        error ("creating array of references");
      return error_mark_node;

    case METHOD_TYPE:
      if (name)
	error_at (loc, "declaration of %qD as array of function members",
		  name);
      else
        error ("creating array of function members");
      return error_mark_node;

    default:
      break;
    }

  /* [dcl.array]

     The constant expressions that specify the bounds of the arrays
     can be omitted only for the first member of the sequence.  */
  if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type))
    {
      if (name)
	error_at (loc, "declaration of %qD as multidimensional array must "
		  "have bounds for all dimensions except the first",
		  name);
      else
	error ("multidimensional array must have bounds for all "
	       "dimensions except the first");

      return error_mark_node;
    }

  /* Figure out the index type for the array.  */
  if (size)
    itype = compute_array_index_type_loc (loc, name, size,
					  tf_warning_or_error);

  /* [dcl.array]
     T is called the array element type; this type shall not be [...] an
     abstract class type.  */
  abstract_virtuals_error (name, type);

  return build_cplus_array_type (type, itype);
}

/* Returns the smallest location that is not UNKNOWN_LOCATION.  */

static location_t
min_location (location_t loca, location_t locb)
{
  if (loca == UNKNOWN_LOCATION
      || (locb != UNKNOWN_LOCATION
	  && linemap_location_before_p (line_table, locb, loca)))
    return locb;
  return loca;
}

/* Returns the smallest location != UNKNOWN_LOCATION among the
   three stored in LOCATIONS[ds_const], LOCATIONS[ds_volatile],
   and LOCATIONS[ds_restrict].  */

static location_t
smallest_type_quals_location (int type_quals, const location_t* locations)
{
  location_t loc = UNKNOWN_LOCATION;

  if (type_quals & TYPE_QUAL_CONST)
    loc = locations[ds_const];

  if (type_quals & TYPE_QUAL_VOLATILE)
    loc = min_location (loc, locations[ds_volatile]);

  if (type_quals & TYPE_QUAL_RESTRICT)
    loc = min_location (loc, locations[ds_restrict]);

  return loc;
}

/* Check that it's OK to declare a function with the indicated TYPE
   and TYPE_QUALS.  SFK indicates the kind of special function (if any)
   that this function is.  OPTYPE is the type given in a conversion
   operator declaration, or the class type for a constructor/destructor.
   Returns the actual return type of the function; that may be different
   than TYPE if an error occurs, or for certain special functions.  */

static tree
check_special_function_return_type (special_function_kind sfk,
				    tree type,
				    tree optype,
				    int type_quals,
				    const location_t* locations)
{
  switch (sfk)
    {
    case sfk_constructor:
      if (type)
	error ("return type specification for constructor invalid");
      else if (type_quals != TYPE_UNQUALIFIED)
	error_at (smallest_type_quals_location (type_quals, locations),
		  "qualifiers are not allowed on constructor declaration");

      if (targetm.cxx.cdtor_returns_this ())
	type = build_pointer_type (optype);
      else
	type = void_type_node;
      break;

    case sfk_destructor:
      if (type)
	error ("return type specification for destructor invalid");
      else if (type_quals != TYPE_UNQUALIFIED)
	error_at (smallest_type_quals_location (type_quals, locations),
		  "qualifiers are not allowed on destructor declaration");

      /* We can't use the proper return type here because we run into
	 problems with ambiguous bases and covariant returns.  */
      if (targetm.cxx.cdtor_returns_this ())
	type = build_pointer_type (void_type_node);
      else
	type = void_type_node;
      break;

    case sfk_conversion:
      if (type)
	error ("return type specified for %<operator %T%>", optype);
      else if (type_quals != TYPE_UNQUALIFIED)
	error_at (smallest_type_quals_location (type_quals, locations),
		  "qualifiers are not allowed on declaration of "
		  "%<operator %T%>", optype);

      type = optype;
      break;

    case sfk_deduction_guide:
      if (type)
	error ("return type specified for deduction guide");
      else if (type_quals != TYPE_UNQUALIFIED)
	error_at (smallest_type_quals_location (type_quals, locations),
		  "qualifiers are not allowed on declaration of "
		  "deduction guide");
      if (TREE_CODE (optype) == TEMPLATE_TEMPLATE_PARM)
	{
	  error ("template template parameter %qT in declaration of "
		 "deduction guide", optype);
	  type = error_mark_node;
	}
      else
	type = make_template_placeholder (CLASSTYPE_TI_TEMPLATE (optype));
      for (int i = 0; i < ds_last; ++i)
	if (i != ds_explicit && locations[i])
	  error_at (locations[i],
		    "decl-specifier in declaration of deduction guide");
      break;

    default:
      gcc_unreachable ();
    }

  return type;
}

/* A variable or data member (whose unqualified name is IDENTIFIER)
   has been declared with the indicated TYPE.  If the TYPE is not
   acceptable, issue an error message and return a type to use for
   error-recovery purposes.  */

tree
check_var_type (tree identifier, tree type)
{
  if (VOID_TYPE_P (type))
    {
      if (!identifier)
	error ("unnamed variable or field declared void");
      else if (identifier_p (identifier))
	{
	  gcc_assert (!IDENTIFIER_ANY_OP_P (identifier));
	  error ("variable or field %qE declared void", identifier);
	}
      else
	error ("variable or field declared void");
      type = error_mark_node;
    }

  return type;
}

/* Handle declaring DECL as an inline variable.  */

static void
mark_inline_variable (tree decl, location_t loc)
{
  bool inlinep = true;
  if (! toplevel_bindings_p ())
    {
      error_at (loc, "%<inline%> specifier invalid for variable "
		"%qD declared at block scope", decl);
      inlinep = false;
    }
  else if (cxx_dialect < cxx17)
    pedwarn (loc, 0, "inline variables are only available "
	     "with -std=c++17 or -std=gnu++17");
  if (inlinep)
    {
      retrofit_lang_decl (decl);
      SET_DECL_VAR_DECLARED_INLINE_P (decl);
    }
}


/* Assign a typedef-given name to a class or enumeration type declared
   as anonymous at first.  This was split out of grokdeclarator
   because it is also used in libcc1.  */

void
name_unnamed_type (tree type, tree decl)
{
  gcc_assert (TYPE_UNNAMED_P (type));

  /* Replace the anonymous name with the real name everywhere.  */
  for (tree t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
    {
      if (anon_aggrname_p (TYPE_IDENTIFIER (t)))
	/* We do not rename the debug info representing the
	   unnamed tagged type because the standard says in
	   [dcl.typedef] that the naming applies only for
	   linkage purposes.  */
	/*debug_hooks->set_name (t, decl);*/
	TYPE_NAME (t) = decl;
    }

  if (TYPE_LANG_SPECIFIC (type))
    TYPE_WAS_UNNAMED (type) = 1;

  /* If this is a typedef within a template class, the nested
     type is a (non-primary) template.  The name for the
     template needs updating as well.  */
  if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type))
    DECL_NAME (CLASSTYPE_TI_TEMPLATE (type))
      = TYPE_IDENTIFIER (type);

  /* Adjust linkage now that we aren't unnamed anymore.  */
  reset_type_linkage (type);

  /* FIXME remangle member functions; member functions of a
     type with external linkage have external linkage.  */

  /* Check that our job is done, and that it would fail if we
     attempted to do it again.  */
  gcc_assert (!TYPE_UNNAMED_P (type));
}

/* Given declspecs and a declarator (abstract or otherwise), determine
   the name and type of the object declared and construct a DECL node
   for it.

   DECLSPECS points to the representation of declaration-specifier
   sequence that precedes declarator.

   DECL_CONTEXT says which syntactic context this declaration is in:
     NORMAL for most contexts.  Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL.
     FUNCDEF for a function definition.  Like NORMAL but a few different
      error messages in each case.  Return value may be zero meaning
      this definition is too screwy to try to parse.
     MEMFUNCDEF for a function definition.  Like FUNCDEF but prepares to
      handle member functions (which have FIELD context).
      Return value may be zero meaning this definition is too screwy to
      try to parse.
     PARM for a parameter declaration (either within a function prototype
      or before a function body).  Make a PARM_DECL, or return void_type_node.
     TPARM for a template parameter declaration.
     CATCHPARM for a parameter declaration before a catch clause.
     TYPENAME if for a typename (in a cast or sizeof).
      Don't make a DECL node; just return the ..._TYPE node.
     FIELD for a struct or union field; make a FIELD_DECL.
     BITFIELD for a field with specified width.

   INITIALIZED is as for start_decl.

   ATTRLIST is a pointer to the list of attributes, which may be NULL
   if there are none; *ATTRLIST may be modified if attributes from inside
   the declarator should be applied to the declaration.

   When this function is called, scoping variables (such as
   CURRENT_CLASS_TYPE) should reflect the scope in which the
   declaration occurs, not the scope in which the new declaration will
   be placed.  For example, on:

     void S::f() { ... }

   when grokdeclarator is called for `S::f', the CURRENT_CLASS_TYPE
   should not be `S'.

   Returns a DECL (if a declarator is present), a TYPE (if there is no
   declarator, in cases like "struct S;"), or the ERROR_MARK_NODE if an
   error occurs. */

tree
grokdeclarator (const cp_declarator *declarator,
		cp_decl_specifier_seq *declspecs,
		enum decl_context decl_context,
		int initialized,
		tree* attrlist)
{
  tree type = NULL_TREE;
  int longlong = 0;
  int explicit_intN = 0;
  int virtualp, explicitp, friendp, inlinep, staticp;
  int explicit_int = 0;
  int explicit_char = 0;
  int defaulted_int = 0;

  tree typedef_decl = NULL_TREE;
  const char *name = NULL;
  tree typedef_type = NULL_TREE;
  /* True if this declarator is a function definition.  */
  bool funcdef_flag = false;
  cp_declarator_kind innermost_code = cdk_error;
  int bitfield = 0;
#if 0
  /* See the code below that used this.  */
  tree decl_attr = NULL_TREE;
#endif

  /* Keep track of what sort of function is being processed
     so that we can warn about default return values, or explicit
     return values which do not match prescribed defaults.  */
  special_function_kind sfk = sfk_none;

  tree dname = NULL_TREE;
  tree ctor_return_type = NULL_TREE;
  enum overload_flags flags = NO_SPECIAL;
  /* cv-qualifiers that apply to the declarator, for a declaration of
     a member function.  */
  cp_cv_quals memfn_quals = TYPE_UNQUALIFIED;
  /* virt-specifiers that apply to the declarator, for a declaration of
     a member function.  */
  cp_virt_specifiers virt_specifiers = VIRT_SPEC_UNSPECIFIED;
  /* ref-qualifier that applies to the declarator, for a declaration of
     a member function.  */
  cp_ref_qualifier rqual = REF_QUAL_NONE;
  /* cv-qualifiers that apply to the type specified by the DECLSPECS.  */
  int type_quals = TYPE_UNQUALIFIED;
  tree raises = NULL_TREE;
  int template_count = 0;
  tree returned_attrs = NULL_TREE;
  tree parms = NULL_TREE;
  const cp_declarator *id_declarator;
  /* The unqualified name of the declarator; either an
     IDENTIFIER_NODE, BIT_NOT_EXPR, or TEMPLATE_ID_EXPR.  */
  tree unqualified_id;
  /* The class type, if any, in which this entity is located,
     or NULL_TREE if none.  Note that this value may be different from
     the current class type; for example if an attempt is made to declare
     "A::f" inside "B", this value will be "A".  */
  tree ctype = current_class_type;
  /* The NAMESPACE_DECL for the namespace in which this entity is
     located.  If an unqualified name is used to declare the entity,
     this value will be NULL_TREE, even if the entity is located at
     namespace scope.  */
  tree in_namespace = NULL_TREE;
  cp_storage_class storage_class;
  bool unsigned_p, signed_p, short_p, long_p, thread_p;
  bool type_was_error_mark_node = false;
  bool parameter_pack_p = declarator ? declarator->parameter_pack_p : false;
  bool template_type_arg = false;
  bool template_parm_flag = false;
  bool typedef_p = decl_spec_seq_has_spec_p (declspecs, ds_typedef);
  bool constexpr_p = decl_spec_seq_has_spec_p (declspecs, ds_constexpr);
  bool late_return_type_p = false;
  bool array_parameter_p = false;
  location_t saved_loc = input_location;
  tree reqs = NULL_TREE;

  signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
  unsigned_p = decl_spec_seq_has_spec_p (declspecs, ds_unsigned);
  short_p = decl_spec_seq_has_spec_p (declspecs, ds_short);
  long_p = decl_spec_seq_has_spec_p (declspecs, ds_long);
  longlong = decl_spec_seq_has_spec_p (declspecs, ds_long_long);
  explicit_intN = declspecs->explicit_intN_p;
  thread_p = decl_spec_seq_has_spec_p (declspecs, ds_thread);

  // Was concept_p specified? Note that ds_concept
  // implies ds_constexpr!
  bool concept_p = decl_spec_seq_has_spec_p (declspecs, ds_concept);
  if (concept_p)
    constexpr_p = true;

  if (decl_spec_seq_has_spec_p (declspecs, ds_const))
    type_quals |= TYPE_QUAL_CONST;
  if (decl_spec_seq_has_spec_p (declspecs, ds_volatile))
    type_quals |= TYPE_QUAL_VOLATILE;
  if (decl_spec_seq_has_spec_p (declspecs, ds_restrict))
    type_quals |= TYPE_QUAL_RESTRICT;

  if (decl_context == FUNCDEF)
    funcdef_flag = true, decl_context = NORMAL;
  else if (decl_context == MEMFUNCDEF)
    funcdef_flag = true, decl_context = FIELD;
  else if (decl_context == BITFIELD)
    bitfield = 1, decl_context = FIELD;
  else if (decl_context == TEMPLATE_TYPE_ARG)
    template_type_arg = true, decl_context = TYPENAME;
  else if (decl_context == TPARM)
    template_parm_flag = true, decl_context = PARM;

  if (initialized > 1)
    funcdef_flag = true;

  location_t typespec_loc = smallest_type_quals_location (type_quals,
						      declspecs->locations);
  if (typespec_loc == UNKNOWN_LOCATION)
    typespec_loc = declspecs->locations[ds_type_spec];
  if (typespec_loc == UNKNOWN_LOCATION)
    typespec_loc = input_location;

  /* Look inside a declarator for the name being declared
     and get it as a string, for an error message.  */
  for (id_declarator = declarator;
       id_declarator;
       id_declarator = id_declarator->declarator)
    {
      if (id_declarator->kind != cdk_id)
	innermost_code = id_declarator->kind;

      switch (id_declarator->kind)
	{
	case cdk_function:
	  if (id_declarator->declarator
	      && id_declarator->declarator->kind == cdk_id)
	    {
	      sfk = id_declarator->declarator->u.id.sfk;
	      if (sfk == sfk_destructor)
		flags = DTOR_FLAG;
	    }
	  break;

	case cdk_id:
	  {
	    tree qualifying_scope = id_declarator->u.id.qualifying_scope;
	    tree decl = id_declarator->u.id.unqualified_name;
	    if (!decl)
	      break;
	    if (qualifying_scope)
	      {
		if (check_for_bare_parameter_packs (qualifying_scope,
						    id_declarator->id_loc))
		  return error_mark_node;
		if (at_function_scope_p ())
		  {
		    /* [dcl.meaning] 

		       A declarator-id shall not be qualified except
		       for ... 

		       None of the cases are permitted in block
		       scope.  */
		    if (qualifying_scope == global_namespace)
		      error ("invalid use of qualified-name %<::%D%>",
			     decl);
		    else if (TYPE_P (qualifying_scope))
		      error ("invalid use of qualified-name %<%T::%D%>",
			     qualifying_scope, decl);
		    else 
		      error ("invalid use of qualified-name %<%D::%D%>",
			     qualifying_scope, decl);
		    return error_mark_node;
		  }
		else if (TYPE_P (qualifying_scope))
		  {
		    ctype = qualifying_scope;
		    if (!MAYBE_CLASS_TYPE_P (ctype))
		      {
			error ("%q#T is not a class or a namespace", ctype);
			ctype = NULL_TREE;
		      }
		    else if (innermost_code != cdk_function
			     && current_class_type
			     && !uniquely_derived_from_p (ctype,
							  current_class_type))
		      {
			error ("invalid use of qualified-name %<%T::%D%>",
			       qualifying_scope, decl);
			return error_mark_node;
		      }
		  }
		else if (TREE_CODE (qualifying_scope) == NAMESPACE_DECL)
		  in_namespace = qualifying_scope;
	      }
	    switch (TREE_CODE (decl))
	      {
	      case BIT_NOT_EXPR:
		{
		  if (innermost_code != cdk_function)
		    {
		      error ("declaration of %qD as non-function", decl);
		      return error_mark_node;
		    }
		  else if (!qualifying_scope
			   && !(current_class_type && at_class_scope_p ()))
		    {
		      error ("declaration of %qD as non-member", decl);
		      return error_mark_node;
		    }

		  tree type = TREE_OPERAND (decl, 0);
		  if (TYPE_P (type))
		    type = constructor_name (type);
		  name = identifier_to_locale (IDENTIFIER_POINTER (type));
		  dname = decl;
		}
		break;

	      case TEMPLATE_ID_EXPR:
		{
		  tree fns = TREE_OPERAND (decl, 0);

		  dname = fns;
		  if (!identifier_p (dname))
		    dname = OVL_NAME (dname);
		}
		/* Fall through.  */

	      case IDENTIFIER_NODE:
		if (identifier_p (decl))
		  dname = decl;

		if (IDENTIFIER_KEYWORD_P (dname))
		  {
		    error ("declarator-id missing; using reserved word %qD",
			   dname);
		    name = identifier_to_locale (IDENTIFIER_POINTER (dname));
		  }
		else if (!IDENTIFIER_CONV_OP_P (dname))
		  name = identifier_to_locale (IDENTIFIER_POINTER (dname));
		else
		  {
		    gcc_assert (flags == NO_SPECIAL);
		    flags = TYPENAME_FLAG;
		    sfk = sfk_conversion;
		    tree glob = get_global_binding (dname);
		    if (glob && TREE_CODE (glob) == TYPE_DECL)
		      name = identifier_to_locale (IDENTIFIER_POINTER (dname));
		    else
		      name = "<invalid operator>";
		  }
		break;

	      default:
		gcc_unreachable ();
	      }
	    break;
	  }

	case cdk_array:
	case cdk_pointer:
	case cdk_reference:
	case cdk_ptrmem:
	  break;

	case cdk_decomp:
	  name = "structured binding";
	  break;

	case cdk_error:
	  return error_mark_node;

	default:
	  gcc_unreachable ();
	}
      if (id_declarator->kind == cdk_id)
	break;
    }

  /* [dcl.fct.edf]

     The declarator in a function-definition shall have the form
     D1 ( parameter-declaration-clause) ...  */
  if (funcdef_flag && innermost_code != cdk_function)
    {
      error ("function definition does not declare parameters");
      return error_mark_node;
    }

  if (flags == TYPENAME_FLAG
      && innermost_code != cdk_function
      && ! (ctype && !declspecs->any_specifiers_p))
    {
      error ("declaration of %qD as non-function", dname);
      return error_mark_node;
    }

  if (dname && identifier_p (dname))
    {
      if (UDLIT_OPER_P (dname)
	  && innermost_code != cdk_function)
	{
	  error ("declaration of %qD as non-function", dname);
	  return error_mark_node;
	}

      if (IDENTIFIER_ANY_OP_P (dname))
	{
	  if (typedef_p)
	    {
	      error ("declaration of %qD as %<typedef%>", dname);
	      return error_mark_node;
	    }
	  else if (decl_context == PARM || decl_context == CATCHPARM)
	    {
	      error ("declaration of %qD as parameter", dname);
	      return error_mark_node;
	    }
	}
    }

  /* Anything declared one level down from the top level
     must be one of the parameters of a function
     (because the body is at least two levels down).  */

  /* This heuristic cannot be applied to C++ nodes! Fixed, however,
     by not allowing C++ class definitions to specify their parameters
     with xdecls (must be spec.d in the parmlist).

     Since we now wait to push a class scope until we are sure that
     we are in a legitimate method context, we must set oldcname
     explicitly (since current_class_name is not yet alive).

     We also want to avoid calling this a PARM if it is in a namespace.  */

  if (decl_context == NORMAL && !toplevel_bindings_p ())
    {
      cp_binding_level *b = current_binding_level;
      current_binding_level = b->level_chain;
      if (current_binding_level != 0 && toplevel_bindings_p ())
	decl_context = PARM;
      current_binding_level = b;
    }

  if (name == NULL)
    name = decl_context == PARM ? "parameter" : "type name";

  if (concept_p && typedef_p)
    {
      error_at (declspecs->locations[ds_concept],
		"%<concept%> cannot appear in a typedef declaration");
      return error_mark_node;
    }

  if (constexpr_p && typedef_p)
    {
      error_at (declspecs->locations[ds_constexpr],
		"%<constexpr%> cannot appear in a typedef declaration");
      return error_mark_node;
    }

  /* If there were multiple types specified in the decl-specifier-seq,
     issue an error message.  */
  if (declspecs->multiple_types_p)
    {
      error ("two or more data types in declaration of %qs", name);
      return error_mark_node;
    }

  if (declspecs->conflicting_specifiers_p)
    {
      error ("conflicting specifiers in declaration of %qs", name);
      return error_mark_node;
    }

  /* Extract the basic type from the decl-specifier-seq.  */
  type = declspecs->type;
  if (type == error_mark_node)
    {
      type = NULL_TREE;
      type_was_error_mark_node = true;
    }
  cp_warn_deprecated_use (type);
  if (type && TREE_CODE (type) == TYPE_DECL)
    {
      typedef_decl = type;
      type = TREE_TYPE (typedef_decl);
      if (DECL_ARTIFICIAL (typedef_decl))
	cp_warn_deprecated_use (type);
    }
  /* No type at all: default to `int', and set DEFAULTED_INT
     because it was not a user-defined typedef.  */
  if (type == NULL_TREE)
    {
      if (signed_p || unsigned_p || long_p || short_p)
	{
	  /* These imply 'int'.  */
	  type = integer_type_node;
	  defaulted_int = 1;
	}
      /* If we just have "complex", it is equivalent to "complex double".  */
      else if (!longlong && !explicit_intN
	       && decl_spec_seq_has_spec_p (declspecs, ds_complex))
	{
	  type = double_type_node;
	  pedwarn (declspecs->locations[ds_complex], OPT_Wpedantic,
		   "ISO C++ does not support plain %<complex%> meaning "
		   "%<double complex%>");
	}
    }
  /* Gather flags.  */
  explicit_int = declspecs->explicit_int_p;
  explicit_char = declspecs->explicit_char_p;

#if 0
  /* See the code below that used this.  */
  if (typedef_decl)
    decl_attr = DECL_ATTRIBUTES (typedef_decl);
#endif
  typedef_type = type;

  if (sfk == sfk_conversion || sfk == sfk_deduction_guide)
    ctor_return_type = TREE_TYPE (dname);
  else
    ctor_return_type = ctype;

  if (sfk != sfk_none)
    {
      type = check_special_function_return_type (sfk, type,
						 ctor_return_type,
						 type_quals,
						 declspecs->locations);
      type_quals = TYPE_UNQUALIFIED;
    }
  else if (type == NULL_TREE)
    {
      int is_main;

      explicit_int = -1;

      /* We handle `main' specially here, because 'main () { }' is so
	 common.  With no options, it is allowed.  With -Wreturn-type,
	 it is a warning.  It is only an error with -pedantic-errors.  */
      is_main = (funcdef_flag
		 && dname && identifier_p (dname)
		 && MAIN_NAME_P (dname)
		 && ctype == NULL_TREE
		 && in_namespace == NULL_TREE
		 && current_namespace == global_namespace);

      if (type_was_error_mark_node)
	/* We've already issued an error, don't complain more.  */;
      else if (in_system_header_at (input_location) || flag_ms_extensions)
	/* Allow it, sigh.  */;
      else if (! is_main)
	permerror (input_location, "ISO C++ forbids declaration of %qs with no type", name);
      else if (pedantic)
	pedwarn (input_location, OPT_Wpedantic,
		 "ISO C++ forbids declaration of %qs with no type", name);
      else
	warning (OPT_Wreturn_type,
		 "ISO C++ forbids declaration of %qs with no type", name);

      if (type_was_error_mark_node && template_parm_flag)
	/* FIXME we should be able to propagate the error_mark_node as is
	   for other contexts too.  */
	type = error_mark_node;
      else
	type = integer_type_node;
    }

  ctype = NULL_TREE;

  if (explicit_intN)
    {
      if (! int_n_enabled_p[declspecs->int_n_idx])
	{
	  error ("%<__int%d%> is not supported by this target",
		 int_n_data[declspecs->int_n_idx].bitsize);
	  explicit_intN = false;
	}
      else if (pedantic && ! in_system_header_at (input_location))
	pedwarn (input_location, OPT_Wpedantic,
		 "ISO C++ does not support %<__int%d%> for %qs",
		 int_n_data[declspecs->int_n_idx].bitsize, name);
    }

  /* Now process the modifiers that were specified
     and check for invalid combinations.  */

  /* Long double is a special combination.  */
  if (long_p && !longlong && TYPE_MAIN_VARIANT (type) == double_type_node)
    {
      long_p = false;
      type = cp_build_qualified_type (long_double_type_node,
				      cp_type_quals (type));
    }

  /* Check all other uses of type modifiers.  */

  if (unsigned_p || signed_p || long_p || short_p)
    {
      location_t loc;
      const char *key;
      if (unsigned_p)
	{
	  key = "unsigned";
	  loc = declspecs->locations[ds_unsigned];
	}
      else if (signed_p)
	{
	  key = "signed";
	  loc = declspecs->locations[ds_signed];
	}
      else if (longlong)
	{
	  key = "long long";
	  loc = declspecs->locations[ds_long_long];
	}
      else if (long_p)
	{
	  key = "long";
	  loc = declspecs->locations[ds_long];
	}
      else /* if (short_p) */
	{
	  key = "short";
	  loc = declspecs->locations[ds_short];
	}

      int ok = 0;

      if (signed_p && unsigned_p)
	{
	  gcc_rich_location richloc (declspecs->locations[ds_signed]);
	  richloc.add_range (declspecs->locations[ds_unsigned]);
	  error_at (&richloc,
		    "%<signed%> and %<unsigned%> specified together");
	}
      else if (long_p && short_p)
	{
	  gcc_rich_location richloc (declspecs->locations[ds_long]);
	  richloc.add_range (declspecs->locations[ds_short]);
	  error_at (&richloc, "%<long%> and %<short%> specified together");
	}
      else if (TREE_CODE (type) != INTEGER_TYPE
	       || type == char16_type_node || type == char32_type_node
	       || ((long_p || short_p)
		   && (explicit_char || explicit_intN)))
	error_at (loc, "%qs specified with %qT", key, type);
      else if (!explicit_int && !defaulted_int
	       && !explicit_char && !explicit_intN)
	{
	  if (typedef_decl)
	    {
	      pedwarn (loc, OPT_Wpedantic, "%qs specified with %qT",
		       key, type);
	      ok = !flag_pedantic_errors;
	    }
	  else if (declspecs->decltype_p)
	    error_at (loc, "%qs specified with %<decltype%>", key);
	  else
	    error_at (loc, "%qs specified with %<typeof%>", key);
	}
      else
	ok = 1;

      /* Discard the type modifiers if they are invalid.  */
      if (! ok)
	{
	  unsigned_p = false;
	  signed_p = false;
	  long_p = false;
	  short_p = false;
	  longlong = 0;
	}
    }

  /* Decide whether an integer type is signed or not.
     Optionally treat bitfields as signed by default.  */
  if (unsigned_p
      /* [class.bit]

	 It is implementation-defined whether a plain (neither
	 explicitly signed or unsigned) char, short, int, or long
	 bit-field is signed or unsigned.

	 Naturally, we extend this to long long as well.  Note that
	 this does not include wchar_t.  */
      || (bitfield && !flag_signed_bitfields
	  && !signed_p
	  /* A typedef for plain `int' without `signed' can be
	     controlled just like plain `int', but a typedef for
	     `signed int' cannot be so controlled.  */
	  && !(typedef_decl
	       && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))
	  && TREE_CODE (type) == INTEGER_TYPE
	  && !same_type_p (TYPE_MAIN_VARIANT (type), wchar_type_node)))
    {
      if (explicit_intN)
	type = int_n_trees[declspecs->int_n_idx].unsigned_type;
      else if (longlong)
	type = long_long_unsigned_type_node;
      else if (long_p)
	type = long_unsigned_type_node;
      else if (short_p)
	type = short_unsigned_type_node;
      else if (type == char_type_node)
	type = unsigned_char_type_node;
      else if (typedef_decl)
	type = unsigned_type_for (type);
      else
	type = unsigned_type_node;
    }
  else if (signed_p && type == char_type_node)
    type = signed_char_type_node;
  else if (explicit_intN)
    type = int_n_trees[declspecs->int_n_idx].signed_type;
  else if (longlong)
    type = long_long_integer_type_node;
  else if (long_p)
    type = long_integer_type_node;
  else if (short_p)
    type = short_integer_type_node;

  if (decl_spec_seq_has_spec_p (declspecs, ds_complex))
    {
      if (TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE)
	error ("complex invalid for %qs", name);
      /* If a modifier is specified, the resulting complex is the complex
	 form of TYPE.  E.g, "complex short" is "complex short int".  */
      else if (type == integer_type_node)
	type = complex_integer_type_node;
      else if (type == float_type_node)
	type = complex_float_type_node;
      else if (type == double_type_node)
	type = complex_double_type_node;
      else if (type == long_double_type_node)
	type = complex_long_double_type_node;
      else
	type = build_complex_type (type);
    }

  /* If we're using the injected-class-name to form a compound type or a
     declaration, replace it with the underlying class so we don't get
     redundant typedefs in the debug output.  But if we are returning the
     type unchanged, leave it alone so that it's available to
     maybe_get_template_decl_from_type_decl.  */
  if (CLASS_TYPE_P (type)
      && DECL_SELF_REFERENCE_P (TYPE_NAME (type))
      && type == TREE_TYPE (TYPE_NAME (type))
      && (declarator || type_quals))
    type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));

  type_quals |= cp_type_quals (type);
  type = cp_build_qualified_type_real
    (type, type_quals, ((((typedef_decl && !DECL_ARTIFICIAL (typedef_decl))
			  || declspecs->decltype_p)
			 ? tf_ignore_bad_quals : 0) | tf_warning_or_error));
  /* We might have ignored or rejected some of the qualifiers.  */
  type_quals = cp_type_quals (type);

  if (cxx_dialect >= cxx17 && type && is_auto (type)
      && innermost_code != cdk_function
      && id_declarator && declarator != id_declarator)
    if (tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (type))
    {
      error_at (typespec_loc, "template placeholder type %qT must be followed "
		"by a simple declarator-id", type);
      inform (DECL_SOURCE_LOCATION (tmpl), "%qD declared here", tmpl);
    }

  staticp = 0;
  inlinep = decl_spec_seq_has_spec_p (declspecs, ds_inline);
  virtualp =  decl_spec_seq_has_spec_p (declspecs, ds_virtual);
  explicitp = decl_spec_seq_has_spec_p (declspecs, ds_explicit);

  storage_class = declspecs->storage_class;
  if (storage_class == sc_static)
    staticp = 1 + (decl_context == FIELD);

  if (virtualp)
    {
      if (staticp == 2)
	{
	  gcc_rich_location richloc (declspecs->locations[ds_virtual]);
	  richloc.add_range (declspecs->locations[ds_storage_class]);
	  error_at (&richloc, "member %qD cannot be declared both %<virtual%> "
		    "and %<static%>", dname);
	  storage_class = sc_none;
	  staticp = 0;
	}
      if (constexpr_p && cxx_dialect < cxx2a)
	{
	  gcc_rich_location richloc (declspecs->locations[ds_virtual]);
	  richloc.add_range (declspecs->locations[ds_constexpr]);
	  pedwarn (&richloc, OPT_Wpedantic, "member %qD can be declared both "
		   "%<virtual%> and %<constexpr%> only in -std=c++2a or "
		   "-std=gnu++2a", dname);
	}
    }
  friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);

  /* Issue errors about use of storage classes for parameters.  */
  if (decl_context == PARM)
    {
      if (typedef_p)
	{
	  error_at (declspecs->locations[ds_typedef],
		    "typedef declaration invalid in parameter declaration");
	  return error_mark_node;
	}
      else if (template_parm_flag && storage_class != sc_none)
	{
	  error_at (min_location (declspecs->locations[ds_thread],
				  declspecs->locations[ds_storage_class]),
		    "storage class specified for template parameter %qs",
		    name);
	  return error_mark_node;
	}
      else if (storage_class == sc_static
	       || storage_class == sc_extern
	       || thread_p)
	{
	  error_at (min_location (declspecs->locations[ds_thread],
				  declspecs->locations[ds_storage_class]),
		    "storage class specified for parameter %qs", name);
	  return error_mark_node;
	}

      /* Function parameters cannot be concept. */
      if (concept_p)
	error_at (declspecs->locations[ds_concept],
		  "a parameter cannot be declared %<concept%>");
      /* Function parameters cannot be constexpr.  If we saw one, moan
         and pretend it wasn't there.  */
      else if (constexpr_p)
        {
          error_at (declspecs->locations[ds_constexpr],
		    "a parameter cannot be declared %<constexpr%>");
          constexpr_p = 0;
        }
    }

  /* Give error if `virtual' is used outside of class declaration.  */
  if (virtualp
      && (current_class_name == NULL_TREE || decl_context != FIELD))
    {
      error_at (declspecs->locations[ds_virtual],
		"%<virtual%> outside class declaration");
      virtualp = 0;
    }

  if (innermost_code == cdk_decomp)
    {
      location_t loc = (declarator->kind == cdk_reference
			? declarator->declarator->id_loc : declarator->id_loc);
      if (inlinep)
	error_at (declspecs->locations[ds_inline],
		  "structured binding declaration cannot be %<inline%>");
      if (typedef_p)
	error_at (declspecs->locations[ds_typedef],
		  "structured binding declaration cannot be %<typedef%>");
      if (constexpr_p)
	error_at (declspecs->locations[ds_constexpr], "structured "
		  "binding declaration cannot be %<constexpr%>");
      if (thread_p)
	error_at (declspecs->locations[ds_thread],
		  "structured binding declaration cannot be %qs",
		  declspecs->gnu_thread_keyword_p
		  ? "__thread" : "thread_local");
      if (concept_p)
	error_at (declspecs->locations[ds_concept],
		  "structured binding declaration cannot be %<concept%>");
      switch (storage_class)
	{
	case sc_none:
	  break;
	case sc_register:
	  error_at (loc, "structured binding declaration cannot be "
		    "%<register%>");
	  break;
	case sc_static:
	  error_at (loc, "structured binding declaration cannot be "
		    "%<static%>");
	  break;
	case sc_extern:
	  error_at (loc, "structured binding declaration cannot be "
		    "%<extern%>");
	  break;
	case sc_mutable:
	  error_at (loc, "structured binding declaration cannot be "
		    "%<mutable%>");
	  break;
	case sc_auto:
	  error_at (loc, "structured binding declaration cannot be "
		    "C++98 %<auto%>");
	  break;
	default:
	  gcc_unreachable ();
	}
      if (TREE_CODE (type) != TEMPLATE_TYPE_PARM
	  || TYPE_IDENTIFIER (type) != auto_identifier)
	{
	  if (type != error_mark_node)
	    {
	      error_at (loc, "structured binding declaration cannot have "
			"type %qT", type);
	      inform (loc,
		      "type must be cv-qualified %<auto%> or reference to "
		      "cv-qualified %<auto%>");
	    }
	  type = build_qualified_type (make_auto (), type_quals);
	  declspecs->type = type;
	}
      inlinep = 0;
      typedef_p = 0;
      constexpr_p = 0;
      thread_p = 0;
      concept_p = 0;
      storage_class = sc_none;
      staticp = 0;
      declspecs->storage_class = sc_none;
      declspecs->locations[ds_thread] = UNKNOWN_LOCATION;
    }

  /* Static anonymous unions are dealt with here.  */
  if (staticp && decl_context == TYPENAME
      && declspecs->type
      && ANON_AGGR_TYPE_P (declspecs->type))
    decl_context = FIELD;

  /* Warn about storage classes that are invalid for certain
     kinds of declarations (parameters, typenames, etc.).  */
  if (thread_p
      && ((storage_class
	   && storage_class != sc_extern
	   && storage_class != sc_static)
	  || typedef_p))
    {
      error ("multiple storage classes in declaration of %qs", name);
      thread_p = false;
    }
  if (decl_context != NORMAL
      && ((storage_class != sc_none
	   && storage_class != sc_mutable)
	  || thread_p))
    {
      if ((decl_context == PARM || decl_context == CATCHPARM)
	  && (storage_class == sc_register
	      || storage_class == sc_auto))
	;
      else if (typedef_p)
	;
      else if (decl_context == FIELD
	       /* C++ allows static class elements.  */
	       && storage_class == sc_static)
	/* C++ also allows inlines and signed and unsigned elements,
	   but in those cases we don't come in here.  */
	;
      else
	{
	  location_t loc
	    = min_location (declspecs->locations[ds_thread],
			    declspecs->locations[ds_storage_class]);
	  if (decl_context == FIELD)
	    error_at (loc, "storage class specified for %qs", name);
	  else if (decl_context == PARM || decl_context == CATCHPARM)
	    error_at (loc, "storage class specified for parameter %qs", name);
	  else
	    error_at (loc, "storage class specified for typename");
	  if (storage_class == sc_register
	      || storage_class == sc_auto
	      || storage_class == sc_extern
	      || thread_p)
	    storage_class = sc_none;
	}
    }
  else if (storage_class == sc_extern && funcdef_flag
	   && ! toplevel_bindings_p ())
    error ("nested function %qs declared %<extern%>", name);
  else if (toplevel_bindings_p ())
    {
      if (storage_class == sc_auto)
	error ("top-level declaration of %qs specifies %<auto%>", name);
    }
  else if (thread_p
	   && storage_class != sc_extern
	   && storage_class != sc_static)
    {
      if (declspecs->gnu_thread_keyword_p)
	pedwarn (declspecs->locations[ds_thread],
		 0, "function-scope %qs implicitly auto and "
		 "declared %<__thread%>", name);

      /* When thread_local is applied to a variable of block scope the
	 storage-class-specifier static is implied if it does not appear
	 explicitly.  */
      storage_class = declspecs->storage_class = sc_static;
      staticp = 1;
    }

  if (storage_class && friendp)
    {
      error_at (min_location (declspecs->locations[ds_thread],
			      declspecs->locations[ds_storage_class]),
		"storage class specifiers invalid in friend function "
		"declarations");
      storage_class = sc_none;
      staticp = 0;
    }

  if (!id_declarator)
    unqualified_id = NULL_TREE;
  else
    {
      unqualified_id = id_declarator->u.id.unqualified_name;
      switch (TREE_CODE (unqualified_id))
	{
	case BIT_NOT_EXPR:
	  unqualified_id = TREE_OPERAND (unqualified_id, 0);
	  if (TYPE_P (unqualified_id))
	    unqualified_id = constructor_name (unqualified_id);
	  break;

	case IDENTIFIER_NODE:
	case TEMPLATE_ID_EXPR:
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  if (declspecs->std_attributes)
    {
      location_t attr_loc = declspecs->locations[ds_std_attribute];
      if (warning_at (attr_loc, OPT_Wattributes, "attribute ignored"))
	inform (attr_loc, "an attribute that appertains to a type-specifier "
		"is ignored");
    }

  /* Determine the type of the entity declared by recurring on the
     declarator.  */
  for (; declarator; declarator = declarator->declarator)
    {
      const cp_declarator *inner_declarator;
      tree attrs;

      if (type == error_mark_node)
	return error_mark_node;

      attrs = declarator->attributes;
      if (attrs)
	{
	  int attr_flags;

	  attr_flags = 0;
	  if (declarator == NULL || declarator->kind == cdk_id)
	    attr_flags |= (int) ATTR_FLAG_DECL_NEXT;
	  if (declarator->kind == cdk_function)
	    attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
	  if (declarator->kind == cdk_array)
	    attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
	  returned_attrs = decl_attributes (&type,
					    chainon (returned_attrs, attrs),
					    attr_flags);
	}

      inner_declarator = declarator->declarator;

      /* We don't want to warn in parameter context because we don't
	 yet know if the parse will succeed, and this might turn out
	 to be a constructor call.  */
      if (decl_context != PARM
	  && decl_context != TYPENAME
	  && !typedef_p
	  && declarator->parenthesized != UNKNOWN_LOCATION
	  /* If the type is class-like and the inner name used a
	     global namespace qualifier, we need the parens.
	     Unfortunately all we can tell is whether a qualified name
	     was used or not.  */
	  && !(inner_declarator
	       && inner_declarator->kind == cdk_id
	       && inner_declarator->u.id.qualifying_scope
	       && (MAYBE_CLASS_TYPE_P (type)
		   || TREE_CODE (type) == ENUMERAL_TYPE)))
	warning_at (declarator->parenthesized, OPT_Wparentheses,
		    "unnecessary parentheses in declaration of %qs", name);
      if (declarator->kind == cdk_id || declarator->kind == cdk_decomp)
	break;

      switch (declarator->kind)
	{
	case cdk_array:
	  type = create_array_type_for_decl (dname, type,
					     declarator->u.array.bounds,
					     declarator->id_loc);
	  if (!valid_array_size_p (input_location, type, dname))
	    type = error_mark_node;

	  if (declarator->std_attributes)
	    /* [dcl.array]/1:

	       The optional attribute-specifier-seq appertains to the
	       array.  */
	    returned_attrs = chainon (returned_attrs,
				      declarator->std_attributes);
	  break;

	case cdk_function:
	  {
	    tree arg_types;
	    int funcdecl_p;

	    /* Declaring a function type.  */

	    input_location = declspecs->locations[ds_type_spec];
	    abstract_virtuals_error (ACU_RETURN, type);
	    input_location = saved_loc;

	    /* Pick up type qualifiers which should be applied to `this'.  */
	    memfn_quals = declarator->u.function.qualifiers;
	    /* Pick up virt-specifiers.  */
            virt_specifiers = declarator->u.function.virt_specifiers;
	    /* And ref-qualifier, too */
	    rqual = declarator->u.function.ref_qualifier;
	    /* And tx-qualifier.  */
	    tree tx_qual = declarator->u.function.tx_qualifier;
	    /* Pick up the exception specifications.  */
	    raises = declarator->u.function.exception_specification;
	    /* If the exception-specification is ill-formed, let's pretend
	       there wasn't one.  */
	    if (raises == error_mark_node)
	      raises = NULL_TREE;

	    if (reqs)
	      error_at (location_of (reqs), "requires-clause on return type");
	    reqs = declarator->u.function.requires_clause;

	    /* Say it's a definition only for the CALL_EXPR
	       closest to the identifier.  */
	    funcdecl_p = inner_declarator && inner_declarator->kind == cdk_id;

	    /* Handle a late-specified return type.  */
	    tree late_return_type = declarator->u.function.late_return_type;
	    if (funcdecl_p
		/* This is the case e.g. for
		   using T = auto () -> int.  */
		|| inner_declarator == NULL)
	      {
		if (tree auto_node = type_uses_auto (type))
		  {
		    if (!late_return_type)
		      {
			if (current_class_type
			    && LAMBDA_TYPE_P (current_class_type))
			  /* OK for C++11 lambdas.  */;
			else if (cxx_dialect < cxx14)
			  {
			    error ("%qs function uses "
				   "%<auto%> type specifier without trailing "
				   "return type", name);
			    inform (input_location, "deduced return type "
				    "only available with -std=c++14 or "
				    "-std=gnu++14");
			  }
			else if (virtualp)
			  {
			    error ("virtual function cannot "
				   "have deduced return type");
			    virtualp = false;
			  }
		      }
		    else if (!is_auto (type) && sfk != sfk_conversion)
		      {
			error ("%qs function with trailing return type has"
			       " %qT as its type rather than plain %<auto%>",
			       name, type);
			return error_mark_node;
		      }
		    else if (is_auto (type) && AUTO_IS_DECLTYPE (type))
		      {
			if (funcdecl_p)
			  error ("%qs function with trailing return type has "
				 "%<decltype(auto)%> as its type rather than "
				 "plain %<auto%>", name);
			else
			  error ("invalid use of %<decltype(auto)%>");
			return error_mark_node;
		      }
		    tree tmpl = CLASS_PLACEHOLDER_TEMPLATE (auto_node);
		    if (!tmpl)
		      if (tree late_auto = type_uses_auto (late_return_type))
			tmpl = CLASS_PLACEHOLDER_TEMPLATE (late_auto);
		    if (tmpl && funcdecl_p)
		      {
			if (!dguide_name_p (unqualified_id))
			  {
			    error_at (declarator->id_loc, "deduced class "
				      "type %qD in function return type",
				      DECL_NAME (tmpl));
			    inform (DECL_SOURCE_LOCATION (tmpl),
				    "%qD declared here", tmpl);
			    return error_mark_node;
			  }
			else if (!late_return_type)
			  {
			    error_at (declarator->id_loc, "deduction guide "
				      "for %qT must have trailing return "
				      "type", TREE_TYPE (tmpl));
			    inform (DECL_SOURCE_LOCATION (tmpl),
				    "%qD declared here", tmpl);
			    return error_mark_node;
			  }
			else if (CLASS_TYPE_P (late_return_type)
				 && CLASSTYPE_TEMPLATE_INFO (late_return_type)
				 && (CLASSTYPE_TI_TEMPLATE (late_return_type)
				     == tmpl))
			  /* OK */;
			else
			  error ("trailing return type %qT of deduction guide "
				 "is not a specialization of %qT",
				 late_return_type, TREE_TYPE (tmpl));
		      }
		  }
		else if (late_return_type
			 && sfk != sfk_conversion)
		  {
		    if (cxx_dialect < cxx11)
		      /* Not using maybe_warn_cpp0x because this should
			 always be an error.  */
		      error ("trailing return type only available with "
			     "-std=c++11 or -std=gnu++11");
		    else
		      error ("%qs function with trailing return type not "
			     "declared with %<auto%> type specifier", name);
		    return error_mark_node;
		  }
	      }
	    type = splice_late_return_type (type, late_return_type);
	    if (type == error_mark_node)
	      return error_mark_node;

	    if (late_return_type)
	      {
		late_return_type_p = true;
		type_quals = cp_type_quals (type);
	      }

	    if (type_quals != TYPE_UNQUALIFIED)
	      {
		if (SCALAR_TYPE_P (type) || VOID_TYPE_P (type))
		  warning_at (typespec_loc, OPT_Wignored_qualifiers, "type "
			      "qualifiers ignored on function return type");
		/* We now know that the TYPE_QUALS don't apply to the
		   decl, but to its return type.  */
		type_quals = TYPE_UNQUALIFIED;
	      }

	    /* Error about some types functions can't return.  */

	    if (TREE_CODE (type) == FUNCTION_TYPE)
	      {
		error_at (typespec_loc, "%qs declared as function returning "
			  "a function", name);
		return error_mark_node;
	      }
	    if (TREE_CODE (type) == ARRAY_TYPE)
	      {
		error_at (typespec_loc, "%qs declared as function returning "
			  "an array", name);
		return error_mark_node;
	      }

	    if (ctype == NULL_TREE
		&& decl_context == FIELD
		&& funcdecl_p
		&& friendp == 0)
	      ctype = current_class_type;

	    if (ctype && (sfk == sfk_constructor
			  || sfk == sfk_destructor))
	      {
		/* We are within a class's scope. If our declarator name
		   is the same as the class name, and we are defining
		   a function, then it is a constructor/destructor, and
		   therefore returns a void type.  */

		/* ISO C++ 12.4/2.  A destructor may not be declared
		   const or volatile.  A destructor may not be static.
		   A destructor may not be declared with ref-qualifier.

		   ISO C++ 12.1.  A constructor may not be declared
		   const or volatile.  A constructor may not be
		   virtual.  A constructor may not be static.
		   A constructor may not be declared with ref-qualifier. */
		if (staticp == 2)
		  error ((flags == DTOR_FLAG)
			 ? G_("destructor cannot be static member function")
			 : G_("constructor cannot be static member function"));
		if (memfn_quals)
		  {
		    error ((flags == DTOR_FLAG)
			   ? G_("destructors may not be cv-qualified")
			   : G_("constructors may not be cv-qualified"));
		    memfn_quals = TYPE_UNQUALIFIED;
		  }

		if (rqual)
		  {
		    maybe_warn_cpp0x (CPP0X_REF_QUALIFIER);
		    error ((flags == DTOR_FLAG)
			   ? G_("destructors may not be ref-qualified")
			   : G_("constructors may not be ref-qualified"));
		    rqual = REF_QUAL_NONE;
		  }

		if (decl_context == FIELD
		    && !member_function_or_else (ctype,
						 current_class_type,
						 flags))
		  return error_mark_node;

		if (flags != DTOR_FLAG)
		  {
		    /* It's a constructor.  */
		    if (explicitp == 1)
		      explicitp = 2;
		    if (virtualp)
		      {
			permerror (declspecs->locations[ds_virtual],
				   "constructors cannot be declared %<virtual%>");
			virtualp = 0;
		      }
		    if (decl_context == FIELD
			&& sfk != sfk_constructor)
		      return error_mark_node;
		  }
		if (decl_context == FIELD)
		  staticp = 0;
	      }
	    else if (friendp)
	      {
		if (virtualp)
		  {
		    /* Cannot be both friend and virtual.  */
		    gcc_rich_location richloc (declspecs->locations[ds_virtual]);
		    richloc.add_range (declspecs->locations[ds_friend]);
		    error_at (&richloc, "virtual functions cannot be friends");
		    friendp = 0;
		  }
		if (decl_context == NORMAL)
		  error ("friend declaration not in class definition");
		if (current_function_decl && funcdef_flag)
		  {
		    error ("can%'t define friend function %qs in a local "
			   "class definition", name);
		    friendp = 0;
		  }
	      }
	    else if (ctype && sfk == sfk_conversion)
	      {
		if (explicitp == 1)
		  {
		    maybe_warn_cpp0x (CPP0X_EXPLICIT_CONVERSION);
		    explicitp = 2;
		  }
		if (late_return_type_p)
		  error ("a conversion function cannot have a trailing return type");
	      }
	    else if (sfk == sfk_deduction_guide)
	      {
		if (explicitp == 1)
		  explicitp = 2;
	      }

	    tree pushed_scope = NULL_TREE;
	    if (funcdecl_p
		&& decl_context != FIELD
		&& inner_declarator->u.id.qualifying_scope
		&& CLASS_TYPE_P (inner_declarator->u.id.qualifying_scope))
	      pushed_scope
		= push_scope (inner_declarator->u.id.qualifying_scope);

	    arg_types = grokparms (declarator->u.function.parameters, &parms);

	    if (pushed_scope)
	      pop_scope (pushed_scope);

	    if (inner_declarator
		&& inner_declarator->kind == cdk_id
		&& inner_declarator->u.id.sfk == sfk_destructor
		&& arg_types != void_list_node)
	      {
		error ("destructors may not have parameters");
		arg_types = void_list_node;
		parms = NULL_TREE;
	      }

	    type = build_function_type (type, arg_types);

	    tree attrs = declarator->std_attributes;
	    if (tx_qual)
	      {
		tree att = build_tree_list (tx_qual, NULL_TREE);
		/* transaction_safe applies to the type, but
		   transaction_safe_dynamic applies to the function.  */
		if (is_attribute_p ("transaction_safe", tx_qual))
		  attrs = chainon (attrs, att);
		else
		  returned_attrs = chainon (returned_attrs, att);
	      }
	    if (attrs)
	      /* [dcl.fct]/2:

		 The optional attribute-specifier-seq appertains to
		 the function type.  */
	      decl_attributes (&type, attrs, 0);

	    if (raises)
	      type = build_exception_variant (type, raises);
	  }
	  break;

	case cdk_pointer:
	case cdk_reference:
	case cdk_ptrmem:
	  /* Filter out pointers-to-references and references-to-references.
	     We can get these if a TYPE_DECL is used.  */

	  if (TYPE_REF_P (type))
	    {
	      if (declarator->kind != cdk_reference)
		{
		  error ("cannot declare pointer to %q#T", type);
		  type = TREE_TYPE (type);
		}

	      /* In C++0x, we allow reference to reference declarations
		 that occur indirectly through typedefs [7.1.3/8 dcl.typedef]
		 and template type arguments [14.3.1/4 temp.arg.type]. The
		 check for direct reference to reference declarations, which
		 are still forbidden, occurs below. Reasoning behind the change
		 can be found in DR106, DR540, and the rvalue reference
		 proposals. */
	      else if (cxx_dialect == cxx98)
		{
		  error ("cannot declare reference to %q#T", type);
		  type = TREE_TYPE (type);
		}
	    }
	  else if (VOID_TYPE_P (type))
	    {
	      if (declarator->kind == cdk_reference)
		error ("cannot declare reference to %q#T", type);
	      else if (declarator->kind == cdk_ptrmem)
		error ("cannot declare pointer to %q#T member", type);
	    }

	  /* We now know that the TYPE_QUALS don't apply to the decl,
	     but to the target of the pointer.  */
	  type_quals = TYPE_UNQUALIFIED;

	  /* This code used to handle METHOD_TYPE, but I don't think it's
	     possible to get it here anymore.  */
	  gcc_assert (TREE_CODE (type) != METHOD_TYPE);
	  if (declarator->kind == cdk_ptrmem
	      && TREE_CODE (type) == FUNCTION_TYPE)
	    {
	      memfn_quals |= type_memfn_quals (type);
	      type = build_memfn_type (type,
				       declarator->u.pointer.class_type,
				       memfn_quals,
				       rqual);
	      if (type == error_mark_node)
		return error_mark_node;

	      rqual = REF_QUAL_NONE;
	      memfn_quals = TYPE_UNQUALIFIED;
	    }

	  if (TREE_CODE (type) == FUNCTION_TYPE
	      && (type_memfn_quals (type) != TYPE_UNQUALIFIED
		  || type_memfn_rqual (type) != REF_QUAL_NONE))
            error (declarator->kind == cdk_reference
                   ? G_("cannot declare reference to qualified function type %qT")
                   : G_("cannot declare pointer to qualified function type %qT"),
		   type);

	  /* When the pointed-to type involves components of variable size,
	     care must be taken to ensure that the size evaluation code is
	     emitted early enough to dominate all the possible later uses
	     and late enough for the variables on which it depends to have
	     been assigned.

	     This is expected to happen automatically when the pointed-to
	     type has a name/declaration of it's own, but special attention
	     is required if the type is anonymous.

	     We handle the NORMAL and FIELD contexts here by inserting a
	     dummy statement that just evaluates the size at a safe point
	     and ensures it is not deferred until e.g. within a deeper
	     conditional context (c++/43555).

	     We expect nothing to be needed here for PARM or TYPENAME.
	     Evaluating the size at this point for TYPENAME would
	     actually be incorrect, as we might be in the middle of an
	     expression with side effects on the pointed-to type size
	     "arguments" prior to the pointer declaration point and the
	     size evaluation could end up prior to the side effects.  */

	  if (!TYPE_NAME (type)
	      && (decl_context == NORMAL || decl_context == FIELD)
	      && at_function_scope_p ()
	      && variably_modified_type_p (type, NULL_TREE))
	    {
	      TYPE_NAME (type) = build_decl (UNKNOWN_LOCATION, TYPE_DECL,
					     NULL_TREE, type);
	      add_decl_expr (TYPE_NAME (type));
	    }

	  if (declarator->kind == cdk_reference)
	    {
	      /* In C++0x, the type we are creating a reference to might be
		 a typedef which is itself a reference type. In that case,
		 we follow the reference collapsing rules in
		 [7.1.3/8 dcl.typedef] to create the final reference type:

		 "If a typedef TD names a type that is a reference to a type
		 T, an attempt to create the type 'lvalue reference to cv TD'
		 creates the type 'lvalue reference to T,' while an attempt
		 to create the type "rvalue reference to cv TD' creates the
		 type TD."
              */
	      if (VOID_TYPE_P (type))
		/* We already gave an error.  */;
	      else if (TYPE_REF_P (type))
		{
		  if (declarator->u.reference.rvalue_ref)
		    /* Leave type alone.  */;
		  else
		    type = cp_build_reference_type (TREE_TYPE (type), false);
		}
	      else
		type = cp_build_reference_type
		  (type, declarator->u.reference.rvalue_ref);

	      /* In C++0x, we need this check for direct reference to
		 reference declarations, which are forbidden by
		 [8.3.2/5 dcl.ref]. Reference to reference declarations
		 are only allowed indirectly through typedefs and template
		 type arguments. Example:

		   void foo(int & &);      // invalid ref-to-ref decl

		   typedef int & int_ref;
		   void foo(int_ref &);    // valid ref-to-ref decl
	      */
	      if (inner_declarator && inner_declarator->kind == cdk_reference)
		error ("cannot declare reference to %q#T, which is not "
		       "a typedef or a template type argument", type);
	    }
	  else if (TREE_CODE (type) == METHOD_TYPE)
	    type = build_ptrmemfunc_type (build_pointer_type (type));
	  else if (declarator->kind == cdk_ptrmem)
	    {
	      gcc_assert (TREE_CODE (declarator->u.pointer.class_type)
			  != NAMESPACE_DECL);
	      if (declarator->u.pointer.class_type == error_mark_node)
		/* We will already have complained.  */
		type = error_mark_node;
	      else
		type = build_ptrmem_type (declarator->u.pointer.class_type,
					  type);
	    }
	  else
	    type = build_pointer_type (type);

	  /* Process a list of type modifier keywords (such as
	     const or volatile) that were given inside the `*' or `&'.  */

	  if (declarator->u.pointer.qualifiers)
	    {
	      type
		= cp_build_qualified_type (type,
					   declarator->u.pointer.qualifiers);
	      type_quals = cp_type_quals (type);
	    }

	  /* Apply C++11 attributes to the pointer, and not to the
	     type pointed to.  This is unlike what is done for GNU
	     attributes above.  It is to comply with [dcl.ptr]/1:

		 [the optional attribute-specifier-seq (7.6.1) appertains
		  to the pointer and not to the object pointed to].  */
	  if (declarator->std_attributes)
	    decl_attributes (&type, declarator->std_attributes,
			     0);

	  ctype = NULL_TREE;
	  break;

	case cdk_error:
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  /* A `constexpr' specifier used in an object declaration declares
     the object as `const'.  */
  if (constexpr_p && innermost_code != cdk_function)
    {
      /* DR1688 says that a `constexpr' specifier in combination with
	 `volatile' is valid.  */

      if (!TYPE_REF_P (type))
	{
	  type_quals |= TYPE_QUAL_CONST;
	  type = cp_build_qualified_type (type, type_quals);
	}
    }

  if (unqualified_id && TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR
      && TREE_CODE (type) != FUNCTION_TYPE
      && TREE_CODE (type) != METHOD_TYPE
      && !variable_template_p (TREE_OPERAND (unqualified_id, 0)))
    {
      error ("template-id %qD used as a declarator",
	     unqualified_id);
      unqualified_id = dname;
    }

  /* If TYPE is a FUNCTION_TYPE, but the function name was explicitly
     qualified with a class-name, turn it into a METHOD_TYPE, unless
     we know that the function is static.  We take advantage of this
     opportunity to do other processing that pertains to entities
     explicitly declared to be class members.  Note that if DECLARATOR
     is non-NULL, we know it is a cdk_id declarator; otherwise, we
     would not have exited the loop above.  */
  if (declarator
      && declarator->kind == cdk_id
      && declarator->u.id.qualifying_scope
      && MAYBE_CLASS_TYPE_P (declarator->u.id.qualifying_scope))
    {
      ctype = declarator->u.id.qualifying_scope;
      ctype = TYPE_MAIN_VARIANT (ctype);
      template_count = num_template_headers_for_class (ctype);

      if (ctype == current_class_type)
	{
	  if (friendp)
	    {
	      permerror (input_location, "member functions are implicitly "
					 "friends of their class");
	      friendp = 0;
	    }
	  else
	    permerror (declarator->id_loc, 
		       "extra qualification %<%T::%> on member %qs",
		       ctype, name);
	}
      else if (/* If the qualifying type is already complete, then we
		  can skip the following checks.  */
	       !COMPLETE_TYPE_P (ctype)
	       && (/* If the function is being defined, then
		      qualifying type must certainly be complete.  */
		   funcdef_flag
		   /* A friend declaration of "T::f" is OK, even if
		      "T" is a template parameter.  But, if this
		      function is not a friend, the qualifying type
		      must be a class.  */
		   || (!friendp && !CLASS_TYPE_P (ctype))
		   /* For a declaration, the type need not be
		      complete, if either it is dependent (since there
		      is no meaningful definition of complete in that
		      case) or the qualifying class is currently being
		      defined.  */
		   || !(dependent_type_p (ctype)
			|| currently_open_class (ctype)))
	       /* Check that the qualifying type is complete.  */
	       && !complete_type_or_else (ctype, NULL_TREE))
	return error_mark_node;
      else if (TREE_CODE (type) == FUNCTION_TYPE)
	{
	  if (current_class_type
	      && (!friendp || funcdef_flag || initialized))
	    {
	      error (funcdef_flag || initialized
		     ? G_("cannot define member function %<%T::%s%> "
			  "within %qT")
		     : G_("cannot declare member function %<%T::%s%> "
			  "within %qT"),
		     ctype, name, current_class_type);
	      return error_mark_node;
	    }
	}
      else if (typedef_p && current_class_type)
	{
	  error ("cannot declare member %<%T::%s%> within %qT",
		 ctype, name, current_class_type);
	  return error_mark_node;
	}
    }

  if (ctype == NULL_TREE && decl_context == FIELD && friendp == 0)
    ctype = current_class_type;

  /* Now TYPE has the actual type.  */

  if (returned_attrs)
    {
      if (attrlist)
	*attrlist = chainon (returned_attrs, *attrlist);
      else
	attrlist = &returned_attrs;
    }

  if (declarator
      && declarator->kind == cdk_id
      && declarator->std_attributes
      && attrlist != NULL)
    {
      /* [dcl.meaning]/1: The optional attribute-specifier-seq following
	 a declarator-id appertains to the entity that is declared.  */
      if (declarator->std_attributes != error_mark_node)
	*attrlist = chainon (*attrlist, declarator->std_attributes);
      else
	/* We should have already diagnosed the issue (c++/78344).  */
	gcc_assert (seen_error ());
    }

  /* Handle parameter packs. */
  if (parameter_pack_p)
    {
      if (decl_context == PARM)
        /* Turn the type into a pack expansion.*/
        type = make_pack_expansion (type);
      else
        error ("non-parameter %qs cannot be a parameter pack", name);
    }

  if ((decl_context == FIELD || decl_context == PARM)
      && !processing_template_decl
      && variably_modified_type_p (type, NULL_TREE))
    {
      if (decl_context == FIELD)
	error ("data member may not have variably modified type %qT", type);
      else
	error ("parameter may not have variably modified type %qT", type);
      type = error_mark_node;
    }

  if (explicitp == 1 || (explicitp && friendp))
    {
      /* [dcl.fct.spec] (C++11) The explicit specifier shall be used only
	 in the declaration of a constructor or conversion function within
	 a class definition.  */
      if (!current_class_type)
	error_at (declspecs->locations[ds_explicit],
		  "%<explicit%> outside class declaration");
      else if (friendp)
	error_at (declspecs->locations[ds_explicit],
		  "%<explicit%> in friend declaration");
      else
	error_at (declspecs->locations[ds_explicit],
		  "only declarations of constructors and conversion operators "
		  "can be %<explicit%>");
      explicitp = 0;
    }

  if (storage_class == sc_mutable)
    {
      if (decl_context != FIELD || friendp)
	{
	  error ("non-member %qs cannot be declared %<mutable%>", name);
	  storage_class = sc_none;
	}
      else if (decl_context == TYPENAME || typedef_p)
	{
	  error ("non-object member %qs cannot be declared %<mutable%>", name);
	  storage_class = sc_none;
	}
      else if (TREE_CODE (type) == FUNCTION_TYPE
	       || TREE_CODE (type) == METHOD_TYPE)
	{
	  error ("function %qs cannot be declared %<mutable%>", name);
	  storage_class = sc_none;
	}
      else if (staticp)
	{
	  error ("static %qs cannot be declared %<mutable%>", name);
	  storage_class = sc_none;
	}
      else if (type_quals & TYPE_QUAL_CONST)
	{
	  error ("const %qs cannot be declared %<mutable%>", name);
	  storage_class = sc_none;
	}
      else if (TYPE_REF_P (type))
	{
	  permerror (input_location, "reference %qs cannot be declared "
	             "%<mutable%>", name);
	  storage_class = sc_none;
	}
    }

  /* If this is declaring a typedef name, return a TYPE_DECL.  */
  if (typedef_p && decl_context != TYPENAME)
    {
      bool alias_p = decl_spec_seq_has_spec_p (declspecs, ds_alias);
      tree decl;

      /* This declaration:

	   typedef void f(int) const;

	 declares a function type which is not a member of any
	 particular class, but which is cv-qualified; for
	 example "f S::*" declares a pointer to a const-qualified
	 member function of S.  We record the cv-qualification in the
	 function type.  */
      if ((rqual || memfn_quals) && TREE_CODE (type) == FUNCTION_TYPE)
        {
          type = apply_memfn_quals (type, memfn_quals, rqual);
          
          /* We have now dealt with these qualifiers.  */
          memfn_quals = TYPE_UNQUALIFIED;
	  rqual = REF_QUAL_NONE;
        }

      if (type_uses_auto (type))
	{
	  if (alias_p)
	    error_at (declspecs->locations[ds_type_spec],
		      "%<auto%> not allowed in alias declaration");
	  else
	    error_at (declspecs->locations[ds_type_spec],
		      "typedef declared %<auto%>");
	  type = error_mark_node;
	}

      if (reqs)
	error_at (location_of (reqs), "requires-clause on typedef");

      if (id_declarator && declarator->u.id.qualifying_scope)
	{
	  error ("typedef name may not be a nested-name-specifier");
	  type = error_mark_node;
	}

      if (decl_context == FIELD)
	decl = build_lang_decl (TYPE_DECL, unqualified_id, type);
      else
	decl = build_decl (input_location, TYPE_DECL, unqualified_id, type);

      if (decl_context != FIELD)
	{
	  if (!current_function_decl)
	    DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace);
	  else if (DECL_MAYBE_IN_CHARGE_CDTOR_P (current_function_decl))
	    /* The TYPE_DECL is "abstract" because there will be
	       clones of this constructor/destructor, and there will
	       be copies of this TYPE_DECL generated in those
	       clones.  The decloning optimization (for space) may
               revert this subsequently if it determines that
               the clones should share a common implementation.  */
	    DECL_ABSTRACT_P (decl) = true;
	}
      else if (current_class_type
	       && constructor_name_p (unqualified_id, current_class_type))
	permerror (input_location, "ISO C++ forbids nested type %qD with same name "
		   "as enclosing class",
		   unqualified_id);

      /* If the user declares "typedef struct {...} foo" then the
	 struct will have an anonymous name.  Fill that name in now.
	 Nothing can refer to it, so nothing needs know about the name
	 change.  */
      if (type != error_mark_node
	  && unqualified_id
	  && TYPE_NAME (type)
	  && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
	  && TYPE_UNNAMED_P (type)
	  && declspecs->type_definition_p
	  && attributes_naming_typedef_ok (*attrlist)
	  && cp_type_quals (type) == TYPE_UNQUALIFIED)
	name_unnamed_type (type, decl);

      if (signed_p
	  || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl)))
	C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1;

      bad_specifiers (decl, BSP_TYPE, virtualp,
		      memfn_quals != TYPE_UNQUALIFIED,
		      inlinep, friendp, raises != NULL_TREE,
		      declspecs->locations);

      if (alias_p)
	/* Acknowledge that this was written:
	     `using analias = atype;'.  */
	TYPE_DECL_ALIAS_P (decl) = 1;

      return decl;
    }

  /* Detect the case of an array type of unspecified size
     which came, as such, direct from a typedef name.
     We must copy the type, so that the array's domain can be
     individually set by the object's initializer.  */

  if (type && typedef_type
      && TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)
      && TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (typedef_type))
    type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);

  /* Detect where we're using a typedef of function type to declare a
     function. PARMS will not be set, so we must create it now.  */

  if (type == typedef_type && TREE_CODE (type) == FUNCTION_TYPE)
    {
      tree decls = NULL_TREE;
      tree args;

      for (args = TYPE_ARG_TYPES (type);
	   args && args != void_list_node;
	   args = TREE_CHAIN (args))
	{
	  tree decl = cp_build_parm_decl (NULL_TREE, NULL_TREE,
					  TREE_VALUE (args));

	  DECL_CHAIN (decl) = decls;
	  decls = decl;
	}

      parms = nreverse (decls);

      if (decl_context != TYPENAME)
	{
	  /* The qualifiers on the function type become the qualifiers on
	     the non-static member function. */
	  memfn_quals |= type_memfn_quals (type);
	  rqual = type_memfn_rqual (type);
	  type_quals = TYPE_UNQUALIFIED;
	}
    }

  /* If this is a type name (such as, in a cast or sizeof),
     compute the type and return it now.  */

  if (decl_context == TYPENAME)
    {
      /* Note that here we don't care about type_quals.  */

      /* Special case: "friend class foo" looks like a TYPENAME context.  */
      if (friendp)
	{
	  if (inlinep)
	    {
	      error ("%<inline%> specified for friend class declaration");
	      inlinep = 0;
	    }

	  if (!current_aggr)
	    {
	      /* Don't allow friend declaration without a class-key.  */
	      if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
		permerror (input_location, "template parameters cannot be friends");
	      else if (TREE_CODE (type) == TYPENAME_TYPE)
		permerror (input_location, "friend declaration requires class-key, "
			   "i.e. %<friend class %T::%D%>",
			   TYPE_CONTEXT (type), TYPENAME_TYPE_FULLNAME (type));
	      else
		permerror (input_location, "friend declaration requires class-key, "
			   "i.e. %<friend %#T%>",
			   type);
	    }

	  /* Only try to do this stuff if we didn't already give up.  */
	  if (type != integer_type_node)
	    {
	      /* A friendly class?  */
	      if (current_class_type)
		make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type),
				   /*complain=*/true);
	      else
		error ("trying to make class %qT a friend of global scope",
		       type);

	      type = void_type_node;
	    }
	}
      else if (memfn_quals || rqual)
	{
	  if (ctype == NULL_TREE
	      && TREE_CODE (type) == METHOD_TYPE)
	    ctype = TYPE_METHOD_BASETYPE (type);

	  if (ctype)
	    type = build_memfn_type (type, ctype, memfn_quals, rqual);
	  /* Core issue #547: need to allow this in template type args.
	     Allow it in general in C++11 for alias-declarations.  */
	  else if ((template_type_arg || cxx_dialect >= cxx11)
		   && TREE_CODE (type) == FUNCTION_TYPE)
	    type = apply_memfn_quals (type, memfn_quals, rqual);
	  else
	    error ("invalid qualifiers on non-member function type");
	}

      if (reqs)
	error_at (location_of (reqs), "requires-clause on type-id");

      return type;
    }
  else if (unqualified_id == NULL_TREE && decl_context != PARM
	   && decl_context != CATCHPARM
	   && TREE_CODE (type) != UNION_TYPE
	   && ! bitfield
	   && innermost_code != cdk_decomp)
    {
      error ("abstract declarator %qT used as declaration", type);
      return error_mark_node;
    }

  if (!FUNC_OR_METHOD_TYPE_P (type))
    {
      /* Only functions may be declared using an operator-function-id.  */
      if (dname && IDENTIFIER_ANY_OP_P (dname))
	{
	  error ("declaration of %qD as non-function", dname);
	  return error_mark_node;
	}

      if (reqs)
	error_at (location_of (reqs),
		  "requires-clause on declaration of non-function type %qT",
		  type);
    }

  /* We don't check parameter types here because we can emit a better
     error message later.  */
  if (decl_context != PARM)
    {
      type = check_var_type (unqualified_id, type);
      if (type == error_mark_node)
        return error_mark_node;
    }

  /* Now create the decl, which may be a VAR_DECL, a PARM_DECL
     or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE.  */

  if (decl_context == PARM || decl_context == CATCHPARM)
    {
      if (ctype || in_namespace)
	error ("cannot use %<::%> in parameter declaration");

      if (type_uses_auto (type)
	  && !(cxx_dialect >= cxx17 && template_parm_flag))
	{
	  if (cxx_dialect >= cxx14)
	    error ("%<auto%> parameter not permitted in this context");
	  else
	    error ("parameter declared %<auto%>");
	  type = error_mark_node;
	}

      /* A parameter declared as an array of T is really a pointer to T.
	 One declared as a function is really a pointer to a function.
	 One declared as a member is really a pointer to member.  */

      if (TREE_CODE (type) == ARRAY_TYPE)
	{
	  /* Transfer const-ness of array into that of type pointed to.  */
	  type = build_pointer_type (TREE_TYPE (type));
	  type_quals = TYPE_UNQUALIFIED;
	  array_parameter_p = true;
	}
      else if (TREE_CODE (type) == FUNCTION_TYPE)
	type = build_pointer_type (type);
    }

  if (ctype && TREE_CODE (type) == FUNCTION_TYPE && staticp < 2
      && !(unqualified_id
	   && identifier_p (unqualified_id)
	   && IDENTIFIER_NEWDEL_OP_P (unqualified_id)))
    {
      cp_cv_quals real_quals = memfn_quals;
      if (cxx_dialect < cxx14 && constexpr_p
	  && sfk != sfk_constructor && sfk != sfk_destructor)
	real_quals |= TYPE_QUAL_CONST;
      type = build_memfn_type (type, ctype, real_quals, rqual);
    }

  {
    tree decl = NULL_TREE;

    if (decl_context == PARM)
      {
	decl = cp_build_parm_decl (NULL_TREE, unqualified_id, type);
	DECL_ARRAY_PARAMETER_P (decl) = array_parameter_p;

	bad_specifiers (decl, BSP_PARM, virtualp,
			memfn_quals != TYPE_UNQUALIFIED,
			inlinep, friendp, raises != NULL_TREE,
			declspecs->locations);
      }
    else if (decl_context == FIELD)
      {
	if (!staticp && !friendp && TREE_CODE (type) != METHOD_TYPE)
	  if (tree auto_node = type_uses_auto (type))
	    {
	      location_t loc = declspecs->locations[ds_type_spec];
	      if (CLASS_PLACEHOLDER_TEMPLATE (auto_node))
		error_at (loc, "invalid use of template-name %qE without an "
			  "argument list",
			  CLASS_PLACEHOLDER_TEMPLATE (auto_node));
	      else
		error_at (loc, "non-static data member declared with "
			  "placeholder %qT", auto_node);
	      type = error_mark_node;
	    }

	/* The C99 flexible array extension.  */
	if (!staticp && TREE_CODE (type) == ARRAY_TYPE
	    && TYPE_DOMAIN (type) == NULL_TREE)
	  {
	    if (ctype
		&& (TREE_CODE (ctype) == UNION_TYPE
		    || TREE_CODE (ctype) == QUAL_UNION_TYPE))
	      {
		error ("flexible array member in union");
		type = error_mark_node;
	      }
	    else
	      {
		/* Array is a flexible member.  */
		if (in_system_header_at (input_location))
		  /* Do not warn on flexible array members in system
		     headers because glibc uses them.  */;
		else if (name && declarator)
		  pedwarn (declarator->id_loc, OPT_Wpedantic,
			   "ISO C++ forbids flexible array member %qs", name);
		else
		  pedwarn (input_location, OPT_Wpedantic,
			   "ISO C++ forbids flexible array members");

		/* Flexible array member has a null domain.  */
		type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
	      }
	  }

	if (type == error_mark_node)
	  {
	    /* Happens when declaring arrays of sizes which
	       are error_mark_node, for example.  */
	    decl = NULL_TREE;
	  }
	else if (in_namespace && !friendp)
	  {
	    /* Something like struct S { int N::j; };  */
	    error ("invalid use of %<::%>");
	    return error_mark_node;
	  }
	else if (FUNC_OR_METHOD_TYPE_P (type) && unqualified_id)
	  {
	    int publicp = 0;
	    tree function_context;

	    if (friendp == 0)
	      {
		/* This should never happen in pure C++ (the check
		   could be an assert).  It could happen in
		   Objective-C++ if someone writes invalid code that
		   uses a function declaration for an instance
		   variable or property (instance variables and
		   properties are parsed as FIELD_DECLs, but they are
		   part of an Objective-C class, not a C++ class).
		   That code is invalid and is caught by this
		   check.  */
		if (!ctype)
		  {
		    error ("declaration of function %qD in invalid context",
			   unqualified_id);
		    return error_mark_node;
		  }

		/* ``A union may [ ... ] not [ have ] virtual functions.''
		   ARM 9.5 */
		if (virtualp && TREE_CODE (ctype) == UNION_TYPE)
		  {
		    error_at (declspecs->locations[ds_virtual],
			      "function %qD declared %<virtual%> inside a union",
			      unqualified_id);
		    return error_mark_node;
		  }

		if (virtualp
		    && identifier_p (unqualified_id)
		    && IDENTIFIER_NEWDEL_OP_P (unqualified_id))
		  {
		    error_at (declspecs->locations[ds_virtual],
			      "%qD cannot be declared %<virtual%>, since it "
			      "is always static", unqualified_id);
		    virtualp = 0;
		  }
	      }

	    /* Check that the name used for a destructor makes sense.  */
	    if (sfk == sfk_destructor)
	      {
		tree uqname = id_declarator->u.id.unqualified_name;

		if (!ctype)
		  {
		    gcc_assert (friendp);
		    error ("expected qualified name in friend declaration "
			   "for destructor %qD", uqname);
		    return error_mark_node;
		  }

		if (!check_dtor_name (ctype, TREE_OPERAND (uqname, 0)))
		  {
		    error ("declaration of %qD as member of %qT",
			   uqname, ctype);
		    return error_mark_node;
		  }
                if (concept_p)
                  {
                    error_at (declspecs->locations[ds_concept],
			      "a destructor cannot be %<concept%>");
                    return error_mark_node;
                  }
                if (constexpr_p)
                  {
                    error_at (declspecs->locations[ds_constexpr],
			      "a destructor cannot be %<constexpr%>");
                    return error_mark_node;
                  }
	      }
	    else if (sfk == sfk_constructor && friendp && !ctype)
	      {
		error ("expected qualified name in friend declaration "
		       "for constructor %qD",
		       id_declarator->u.id.unqualified_name);
		return error_mark_node;
	      }
	    if (sfk == sfk_constructor)
	      if (concept_p)
		{
		  error_at (declspecs->locations[ds_concept],
			    "a constructor cannot be %<concept%>");
		  return error_mark_node;
		}
	    if (concept_p)
	      {
		error_at (declspecs->locations[ds_concept],
			  "a concept cannot be a member function");
		concept_p = false;
	      }

	    if (TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR)
	      {
		tree tmpl = TREE_OPERAND (unqualified_id, 0);
		if (variable_template_p (tmpl))
		  {
		    error ("specialization of variable template %qD "
			   "declared as function", tmpl);
		    inform (DECL_SOURCE_LOCATION (tmpl),
			    "variable template declared here");
		    return error_mark_node;
		  }
	      }

	    /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node.  */
	    function_context = (ctype != NULL_TREE) ?
	      decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE;
	    publicp = (! friendp || ! staticp)
	      && function_context == NULL_TREE;

	    decl = grokfndecl (ctype, type,
			       TREE_CODE (unqualified_id) != TEMPLATE_ID_EXPR
			       ? unqualified_id : dname,
			       parms,
			       unqualified_id,
			       declspecs,
			       reqs,
			       virtualp, flags, memfn_quals, rqual, raises,
			       friendp ? -1 : 0, friendp, publicp,
                               inlinep | (2 * constexpr_p) | (4 * concept_p),
			       initialized == SD_DELETED, sfk,
			       funcdef_flag, late_return_type_p,
			       template_count, in_namespace,
			       attrlist, declarator->id_loc);
            decl = set_virt_specifiers (decl, virt_specifiers);
	    if (decl == NULL_TREE)
	      return error_mark_node;
#if 0
	    /* This clobbers the attrs stored in `decl' from `attrlist'.  */
	    /* The decl and setting of decl_attr is also turned off.  */
	    decl = build_decl_attribute_variant (decl, decl_attr);
#endif

	    /* [class.conv.ctor]

	       A constructor declared without the function-specifier
	       explicit that can be called with a single parameter
	       specifies a conversion from the type of its first
	       parameter to the type of its class.  Such a constructor
	       is called a converting constructor.  */
	    if (explicitp == 2)
	      DECL_NONCONVERTING_P (decl) = 1;

	    if (declspecs->explicit_specifier)
	      store_explicit_specifier (decl, declspecs->explicit_specifier);
	  }
	else if (!staticp && !dependent_type_p (type)
		 && !COMPLETE_TYPE_P (complete_type (type))
		 && (!complete_or_array_type_p (type)
		     || initialized == 0))
	  {
	    if (TREE_CODE (type) != ARRAY_TYPE
		|| !COMPLETE_TYPE_P (TREE_TYPE (type)))
	      {
		if (unqualified_id)
		  {
		    error_at (declarator->id_loc,
			      "field %qD has incomplete type %qT",
			      unqualified_id, type);
		    cxx_incomplete_type_inform (strip_array_types (type));
		  }
		else
		  error ("name %qT has incomplete type", type);

		type = error_mark_node;
		decl = NULL_TREE;
	      }
	  }
	else
	  {
	    if (friendp)
	      {
		if (unqualified_id && declarator)
		  error_at (declarator->id_loc,
			    "%qE is neither function nor member function; "
			    "cannot be declared friend", unqualified_id);
		else
		  error ("unnamed field is neither function nor member "
			 "function; cannot be declared friend");
		return error_mark_node;
	      }
	    decl = NULL_TREE;
	  }

	if (friendp)
	  {
	    /* Friends are treated specially.  */
	    if (ctype == current_class_type)
	      ;  /* We already issued a permerror.  */
	    else if (decl && DECL_NAME (decl))
	      {
		if (template_class_depth (current_class_type) == 0)
		  {
		    decl = check_explicit_specialization
		      (unqualified_id, decl, template_count,
		       2 * funcdef_flag + 4);
		    if (decl == error_mark_node)
		      return error_mark_node;
		  }

		decl = do_friend (ctype, unqualified_id, decl,
				  *attrlist, flags,
				  funcdef_flag);
		return decl;
	      }
	    else
	      return error_mark_node;
	  }

	/* Structure field.  It may not be a function, except for C++.  */

	if (decl == NULL_TREE)
	  {
	    location_t loc = declarator ? declarator->id_loc : input_location;
	    if (staticp)
	      {
		/* C++ allows static class members.  All other work
		   for this is done by grokfield.  */
		decl = build_lang_decl_loc (loc, VAR_DECL,
					    unqualified_id, type);
		set_linkage_for_static_data_member (decl);
		if (concept_p)
		  error_at (declspecs->locations[ds_concept],
			    "static data member %qE declared %<concept%>",
			    unqualified_id);
		else if (constexpr_p && !initialized)
		  {
		    error ("%<constexpr%> static data member %qD must have an "
			   "initializer", decl);
		    constexpr_p = false;
		  }

		if (inlinep)
		  mark_inline_variable (decl, declspecs->locations[ds_inline]);

		if (!DECL_VAR_DECLARED_INLINE_P (decl)
		    && !(cxx_dialect >= cxx17 && constexpr_p))
		  /* Even if there is an in-class initialization, DECL
		     is considered undefined until an out-of-class
		     definition is provided, unless this is an inline
		     variable.  */
		  DECL_EXTERNAL (decl) = 1;

		if (thread_p)
		  {
		    CP_DECL_THREAD_LOCAL_P (decl) = true;
		    if (!processing_template_decl)
		      set_decl_tls_model (decl, decl_default_tls_model (decl));
		    if (declspecs->gnu_thread_keyword_p)
		      SET_DECL_GNU_TLS_P (decl);
		  }
	      }
	    else
	      {
		if (concept_p)
		  error_at (declspecs->locations[ds_concept],
			    "non-static data member %qE declared %<concept%>",
			    unqualified_id);
                else if (constexpr_p)
		  {
		    error_at (declspecs->locations[ds_constexpr],
			      "non-static data member %qE declared %<constexpr%>",
			      unqualified_id);
		    constexpr_p = false;
		  }
		decl = build_decl (loc, FIELD_DECL, unqualified_id, type);
		DECL_NONADDRESSABLE_P (decl) = bitfield;
		if (bitfield && !unqualified_id)
		  {
		    TREE_NO_WARNING (decl) = 1;
		    DECL_PADDING_P (decl) = 1;
		  }

		if (storage_class == sc_mutable)
		  {
		    DECL_MUTABLE_P (decl) = 1;
		    storage_class = sc_none;
		  }

		if (initialized)
		  {
		    /* An attempt is being made to initialize a non-static
		       member.  This is new in C++11.  */
		    maybe_warn_cpp0x (CPP0X_NSDMI);

		    /* If this has been parsed with static storage class, but
		       errors forced staticp to be cleared, ensure NSDMI is
		       not present.  */
		    if (declspecs->storage_class == sc_static)
		      DECL_INITIAL (decl) = error_mark_node;
		  }
	      }

	    bad_specifiers (decl, BSP_FIELD, virtualp,
			    memfn_quals != TYPE_UNQUALIFIED,
			    staticp ? false : inlinep, friendp,
			    raises != NULL_TREE,
			    declspecs->locations);
	  }
      }
    else if (TREE_CODE (type) == FUNCTION_TYPE
	     || TREE_CODE (type) == METHOD_TYPE)
      {
	tree original_name;
	int publicp = 0;

	if (!unqualified_id)
	  return error_mark_node;

	if (TREE_CODE (unqualified_id) == TEMPLATE_ID_EXPR)
	  original_name = dname;
	else
	  original_name = unqualified_id;
	// FIXME:gcc_assert (original_name == dname);

	if (storage_class == sc_auto)
	  error ("storage class %<auto%> invalid for function %qs", name);
	else if (storage_class == sc_register)
	  error ("storage class %<register%> invalid for function %qs", name);
	else if (thread_p)
	  {
	    if (declspecs->gnu_thread_keyword_p)
	      error_at (declspecs->locations[ds_thread],
			"storage class %<__thread%> invalid for function %qs",
			name);
	    else
	      error_at (declspecs->locations[ds_thread],
			"storage class %<thread_local%> invalid for "
			"function %qs", name);
	  }

        if (virt_specifiers)
          error ("virt-specifiers in %qs not allowed outside a class "
		 "definition", name);
	/* Function declaration not at top level.
	   Storage classes other than `extern' are not allowed
	   and `extern' makes no difference.  */
	if (! toplevel_bindings_p ()
	    && (storage_class == sc_static
		|| decl_spec_seq_has_spec_p (declspecs, ds_inline))
	    && pedantic)
	  {
	    if (storage_class == sc_static)
	      pedwarn (declspecs->locations[ds_storage_class], OPT_Wpedantic, 
		       "%<static%> specifier invalid for function %qs "
		       "declared out of global scope", name);
	    else
	      pedwarn (declspecs->locations[ds_inline], OPT_Wpedantic, 
		       "%<inline%> specifier invalid for function %qs "
		       "declared out of global scope", name);
	  }

	if (ctype == NULL_TREE)
	  {
	    if (virtualp)
	      {
		error ("virtual non-class function %qs", name);
		virtualp = 0;
	      }
	    else if (sfk == sfk_constructor
		     || sfk == sfk_destructor)
	      {
		error (funcdef_flag
		       ? G_("%qs defined in a non-class scope")
		       : G_("%qs declared in a non-class scope"), name);
		sfk = sfk_none;
	      }
	  }

	/* Record whether the function is public.  */
	publicp = (ctype != NULL_TREE
		   || storage_class != sc_static);

	decl = grokfndecl (ctype, type, original_name, parms, unqualified_id,
			   declspecs,
                           reqs, virtualp, flags, memfn_quals, rqual, raises,
			   1, friendp,
			   publicp,
                           inlinep | (2 * constexpr_p) | (4 * concept_p),
			   initialized == SD_DELETED,
                           sfk,
                           funcdef_flag,
			   late_return_type_p,
			   template_count, in_namespace, attrlist,
			   declarator->id_loc);
	if (decl == NULL_TREE)
	  return error_mark_node;

	if (explicitp == 2)
	  DECL_NONCONVERTING_P (decl) = 1;
	if (staticp == 1)
	  {
	    int invalid_static = 0;

	    /* Don't allow a static member function in a class, and forbid
	       declaring main to be static.  */
	    if (TREE_CODE (type) == METHOD_TYPE)
	      {
		permerror (input_location, "cannot declare member function %qD to have "
			   "static linkage", decl);
		invalid_static = 1;
	      }
	    else if (current_function_decl)
	      {
		/* 7.1.1: There can be no static function declarations within a
		   block.  */
		error_at (declspecs->locations[ds_storage_class],
			  "cannot declare static function inside another function");
		invalid_static = 1;
	      }

	    if (invalid_static)
	      {
		staticp = 0;
		storage_class = sc_none;
	      }
	  }
      }
    else
      {
	/* It's a variable.  */

	/* An uninitialized decl with `extern' is a reference.  */
	decl = grokvardecl (type, dname, unqualified_id,
			    declspecs,
			    initialized,
			    type_quals,
			    inlinep,
			    concept_p,
			    template_count,
			    ctype ? ctype : in_namespace);
	if (decl == NULL_TREE)
	  return error_mark_node;

	bad_specifiers (decl, BSP_VAR, virtualp,
			memfn_quals != TYPE_UNQUALIFIED,
			inlinep, friendp, raises != NULL_TREE,
			declspecs->locations);

	if (ctype)
	  {
	    DECL_CONTEXT (decl) = ctype;
	    if (staticp == 1)
	      {
		permerror (input_location, "%<static%> may not be used when defining "
			   "(as opposed to declaring) a static data member");
		staticp = 0;
		storage_class = sc_none;
	      }
	    if (storage_class == sc_register && TREE_STATIC (decl))
	      {
		error ("static member %qD declared %<register%>", decl);
		storage_class = sc_none;
	      }
	    if (storage_class == sc_extern && pedantic)
	      {
		pedwarn (input_location, OPT_Wpedantic, 
			 "cannot explicitly declare member %q#D to have "
			 "extern linkage", decl);
		storage_class = sc_none;
	      }
	  }
	else if (constexpr_p && DECL_EXTERNAL (decl))
	  {
	    error ("declaration of %<constexpr%> variable %qD "
		   "is not a definition", decl);
	    constexpr_p = false;
	  }

	if (inlinep)
	  mark_inline_variable (decl, declspecs->locations[ds_inline]);
	if (innermost_code == cdk_decomp)
	  {
	    gcc_assert (declarator && declarator->kind == cdk_decomp);
	    DECL_SOURCE_LOCATION (decl) = declarator->id_loc;
	    DECL_ARTIFICIAL (decl) = 1;
	    fit_decomposition_lang_decl (decl, NULL_TREE);
	  }
      }

    if (VAR_P (decl) && !initialized)
      if (tree auto_node = type_uses_auto (type))
	if (!CLASS_PLACEHOLDER_TEMPLATE (auto_node))
	  {
	    location_t loc = declspecs->locations[ds_type_spec];
	    error_at (loc, "declaration of %q#D has no initializer", decl);
	    TREE_TYPE (decl) = error_mark_node;
	  }

    if (storage_class == sc_extern && initialized && !funcdef_flag)
      {
	if (toplevel_bindings_p ())
	  {
	    /* It's common practice (and completely valid) to have a const
	       be initialized and declared extern.  */
	    if (!(type_quals & TYPE_QUAL_CONST))
	      warning (0, "%qs initialized and declared %<extern%>", name);
	  }
	else
	  {
	    error ("%qs has both %<extern%> and initializer", name);
	    return error_mark_node;
	  }
      }

    /* Record `register' declaration for warnings on &
       and in case doing stupid register allocation.  */

    if (storage_class == sc_register)
      {
	DECL_REGISTER (decl) = 1;
	/* Warn about register storage specifiers on PARM_DECLs.  */
	if (TREE_CODE (decl) == PARM_DECL)
	  {
	    if (cxx_dialect >= cxx17)
	      pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
		       "ISO C++17 does not allow %<register%> storage "
		       "class specifier");
	    else
	      warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wregister,
			  "%<register%> storage class specifier used");
	  }
      }
    else if (storage_class == sc_extern)
      DECL_THIS_EXTERN (decl) = 1;
    else if (storage_class == sc_static)
      DECL_THIS_STATIC (decl) = 1;

    /* Set constexpr flag on vars (functions got it in grokfndecl).  */
    if (constexpr_p && VAR_P (decl))
      DECL_DECLARED_CONSTEXPR_P (decl) = true;

    /* Record constancy and volatility on the DECL itself .  There's
       no need to do this when processing a template; we'll do this
       for the instantiated declaration based on the type of DECL.  */
    if (!processing_template_decl)
      cp_apply_type_quals_to_decl (type_quals, decl);

    return decl;
  }
}

/* Subroutine of start_function.  Ensure that each of the parameter
   types (as listed in PARMS) is complete, as is required for a
   function definition.  */

static void
require_complete_types_for_parms (tree parms)
{
  for (; parms; parms = DECL_CHAIN (parms))
    {
      if (dependent_type_p (TREE_TYPE (parms)))
	continue;
      if (!VOID_TYPE_P (TREE_TYPE (parms))
	  && complete_type_or_else (TREE_TYPE (parms), parms))
	{
	  relayout_decl (parms);
	  DECL_ARG_TYPE (parms) = type_passed_as (TREE_TYPE (parms));

	  maybe_warn_parm_abi (TREE_TYPE (parms),
			       DECL_SOURCE_LOCATION (parms));
	}
      else
	/* grokparms or complete_type_or_else will have already issued
	   an error.  */
	TREE_TYPE (parms) = error_mark_node;
    }
}

/* Returns nonzero if T is a local variable.  */

int
local_variable_p (const_tree t)
{
  if ((VAR_P (t)
       /* A VAR_DECL with a context that is a _TYPE is a static data
	  member.  */
       && !TYPE_P (CP_DECL_CONTEXT (t))
       /* Any other non-local variable must be at namespace scope.  */
       && !DECL_NAMESPACE_SCOPE_P (t))
      || (TREE_CODE (t) == PARM_DECL))
    return 1;

  return 0;
}

/* Like local_variable_p, but suitable for use as a tree-walking
   function.  */

static tree
local_variable_p_walkfn (tree *tp, int *walk_subtrees,
			 void * /*data*/)
{
  if (local_variable_p (*tp)
      && (!DECL_ARTIFICIAL (*tp) || DECL_NAME (*tp) == this_identifier))
    return *tp;
  else if (TYPE_P (*tp))
    *walk_subtrees = 0;

  return NULL_TREE;
}

/* Check that ARG, which is a default-argument expression for a
   parameter DECL, is valid.  Returns ARG, or ERROR_MARK_NODE, if
   something goes wrong.  DECL may also be a _TYPE node, rather than a
   DECL, if there is no DECL available.  */

tree
check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
{
  tree var;
  tree decl_type;

  if (TREE_CODE (arg) == DEFAULT_ARG)
    /* We get a DEFAULT_ARG when looking at an in-class declaration
       with a default argument.  Ignore the argument for now; we'll
       deal with it after the class is complete.  */
    return arg;

  if (TYPE_P (decl))
    {
      decl_type = decl;
      decl = NULL_TREE;
    }
  else
    decl_type = TREE_TYPE (decl);

  if (arg == error_mark_node
      || decl == error_mark_node
      || TREE_TYPE (arg) == error_mark_node
      || decl_type == error_mark_node)
    /* Something already went wrong.  There's no need to check
       further.  */
    return error_mark_node;

  /* [dcl.fct.default]

     A default argument expression is implicitly converted to the
     parameter type.  */
  ++cp_unevaluated_operand;
  /* Avoid digest_init clobbering the initializer.  */
  tree carg = BRACE_ENCLOSED_INITIALIZER_P (arg) ? unshare_expr (arg): arg;
  perform_implicit_conversion_flags (decl_type, carg, complain,
				     LOOKUP_IMPLICIT);
  --cp_unevaluated_operand;

  /* Avoid redundant -Wzero-as-null-pointer-constant warnings at
     the call sites.  */
  if (TYPE_PTR_OR_PTRMEM_P (decl_type)
      && null_ptr_cst_p (arg))
    return nullptr_node;

  /* [dcl.fct.default]

     Local variables shall not be used in default argument
     expressions.

     The keyword `this' shall not be used in a default argument of a
     member function.  */
  var = cp_walk_tree_without_duplicates (&arg, local_variable_p_walkfn, NULL);
  if (var)
    {
      if (complain & tf_warning_or_error)
	{
	  if (DECL_NAME (var) == this_identifier)
	    permerror (input_location, "default argument %qE uses %qD",
		       arg, var);
	  else
	    error ("default argument %qE uses local variable %qD", arg, var);
	}
      return error_mark_node;
    }

  /* All is well.  */
  return arg;
}

/* Returns a deprecated type used within TYPE, or NULL_TREE if none.  */

static tree
type_is_deprecated (tree type)
{
  enum tree_code code;
  if (TREE_DEPRECATED (type))
    return type;
  if (TYPE_NAME (type))
    {
      if (TREE_DEPRECATED (TYPE_NAME (type)))
	return type;
      else
	return NULL_TREE;
    }

  /* Do warn about using typedefs to a deprecated class.  */
  if (OVERLOAD_TYPE_P (type) && type != TYPE_MAIN_VARIANT (type))
    return type_is_deprecated (TYPE_MAIN_VARIANT (type));

  code = TREE_CODE (type);

  if (code == POINTER_TYPE || code == REFERENCE_TYPE
      || code == OFFSET_TYPE || code == FUNCTION_TYPE
      || code == METHOD_TYPE || code == ARRAY_TYPE)
    return type_is_deprecated (TREE_TYPE (type));

  if (TYPE_PTRMEMFUNC_P (type))
    return type_is_deprecated
      (TREE_TYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type))));

  return NULL_TREE;
}

/* Decode the list of parameter types for a function type.
   Given the list of things declared inside the parens,
   return a list of types.

   If this parameter does not end with an ellipsis, we append
   void_list_node.

   *PARMS is set to the chain of PARM_DECLs created.  */

tree
grokparms (tree parmlist, tree *parms)
{
  tree result = NULL_TREE;
  tree decls = NULL_TREE;
  tree parm;
  int any_error = 0;

  for (parm = parmlist; parm != NULL_TREE; parm = TREE_CHAIN (parm))
    {
      tree type = NULL_TREE;
      tree init = TREE_PURPOSE (parm);
      tree decl = TREE_VALUE (parm);

      if (parm == void_list_node)
	break;

      if (! decl || TREE_TYPE (decl) == error_mark_node)
	continue;

      type = TREE_TYPE (decl);
      if (VOID_TYPE_P (type))
	{
	  if (same_type_p (type, void_type_node)
	      && !init
	      && !DECL_NAME (decl) && !result
	      && TREE_CHAIN (parm) == void_list_node)
	    /* DR 577: A parameter list consisting of a single
	       unnamed parameter of non-dependent type 'void'.  */
	    break;
	  else if (cv_qualified_p (type))
	    error_at (DECL_SOURCE_LOCATION (decl),
		      "invalid use of cv-qualified type %qT in "
		      "parameter declaration", type);
	  else
	    error_at (DECL_SOURCE_LOCATION (decl),
		      "invalid use of type %<void%> in parameter "
		      "declaration");
	  /* It's not a good idea to actually create parameters of
	     type `void'; other parts of the compiler assume that a
	     void type terminates the parameter list.  */
	  type = error_mark_node;
	  TREE_TYPE (decl) = error_mark_node;
	}

      if (type != error_mark_node)
	{
	  if (deprecated_state != DEPRECATED_SUPPRESS)
	    {
	      tree deptype = type_is_deprecated (type);
	      if (deptype)
		cp_warn_deprecated_use (deptype);
	    }

	  /* Top-level qualifiers on the parameters are
	     ignored for function types.  */
	  type = cp_build_qualified_type (type, 0);
	  if (TREE_CODE (type) == METHOD_TYPE)
	    {
	      error ("parameter %qD invalidly declared method type", decl);
	      type = build_pointer_type (type);
	      TREE_TYPE (decl) = type;
	    }
	  else if (abstract_virtuals_error (decl, type))
	    any_error = 1;  /* Seems like a good idea.  */
	  else if (cxx_dialect < cxx17 && INDIRECT_TYPE_P (type))
	    {
	      /* Before C++17 DR 393:
		 [dcl.fct]/6, parameter types cannot contain pointers
		 (references) to arrays of unknown bound.  */
	      tree t = TREE_TYPE (type);
	      int ptr = TYPE_PTR_P (type);

	      while (1)
		{
		  if (TYPE_PTR_P (t))
		    ptr = 1;
		  else if (TREE_CODE (t) != ARRAY_TYPE)
		    break;
		  else if (!TYPE_DOMAIN (t))
		    break;
		  t = TREE_TYPE (t);
		}
	      if (TREE_CODE (t) == ARRAY_TYPE)
		pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wpedantic,
			 ptr
			 ? G_("parameter %qD includes pointer to array of "
			      "unknown bound %qT")
			 : G_("parameter %qD includes reference to array of "
			      "unknown bound %qT"),
			 decl, t);
	    }

	  if (any_error)
	    init = NULL_TREE;
	  else if (init && !processing_template_decl)
	    init = check_default_argument (decl, init, tf_warning_or_error);
	}

      DECL_CHAIN (decl) = decls;
      decls = decl;
      result = tree_cons (init, type, result);
    }
  decls = nreverse (decls);
  result = nreverse (result);
  if (parm)
    result = chainon (result, void_list_node);
  *parms = decls;

  return result;
}


/* D is a constructor or overloaded `operator='.

   Let T be the class in which D is declared. Then, this function
   returns:

   -1 if D's is an ill-formed constructor or copy assignment operator
      whose first parameter is of type `T'.
   0  if D is not a copy constructor or copy assignment
      operator.
   1  if D is a copy constructor or copy assignment operator whose
      first parameter is a reference to non-const qualified T.
   2  if D is a copy constructor or copy assignment operator whose
      first parameter is a reference to const qualified T.

   This function can be used as a predicate. Positive values indicate
   a copy constructor and nonzero values indicate a copy assignment
   operator.  */

int
copy_fn_p (const_tree d)
{
  tree args;
  tree arg_type;
  int result = 1;

  gcc_assert (DECL_FUNCTION_MEMBER_P (d));

  if (TREE_CODE (d) == TEMPLATE_DECL
      || (DECL_TEMPLATE_INFO (d)
	  && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
    /* Instantiations of template member functions are never copy
       functions.  Note that member functions of templated classes are
       represented as template functions internally, and we must
       accept those as copy functions.  */
    return 0;

  args = FUNCTION_FIRST_USER_PARMTYPE (d);
  if (!args)
    return 0;

  arg_type = TREE_VALUE (args);
  if (arg_type == error_mark_node)
    return 0;

  if (TYPE_MAIN_VARIANT (arg_type) == DECL_CONTEXT (d))
    {
      /* Pass by value copy assignment operator.  */
      result = -1;
    }
  else if (TYPE_REF_P (arg_type)
	   && !TYPE_REF_IS_RVALUE (arg_type)
	   && TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)) == DECL_CONTEXT (d))
    {
      if (CP_TYPE_CONST_P (TREE_TYPE (arg_type)))
	result = 2;
    }
  else
    return 0;

  args = TREE_CHAIN (args);

  if (args && args != void_list_node && !TREE_PURPOSE (args))
    /* There are more non-optional args.  */
    return 0;

  return result;
}

/* D is a constructor or overloaded `operator='.

   Let T be the class in which D is declared. Then, this function
   returns true when D is a move constructor or move assignment
   operator, false otherwise.  */

bool
move_fn_p (const_tree d)
{
  gcc_assert (DECL_FUNCTION_MEMBER_P (d));

  if (cxx_dialect == cxx98)
    /* There are no move constructors if we are in C++98 mode.  */
    return false;

  if (TREE_CODE (d) == TEMPLATE_DECL
      || (DECL_TEMPLATE_INFO (d)
         && DECL_MEMBER_TEMPLATE_P (DECL_TI_TEMPLATE (d))))
    /* Instantiations of template member functions are never move
       functions.  Note that member functions of templated classes are
       represented as template functions internally, and we must
       accept those as move functions.  */
    return 0;

  return move_signature_fn_p (d);
}

/* D is a constructor or overloaded `operator='.

   Then, this function returns true when D has the same signature as a move
   constructor or move assignment operator (because either it is such a
   ctor/op= or it is a template specialization with the same signature),
   false otherwise.  */

bool
move_signature_fn_p (const_tree d)
{
  tree args;
  tree arg_type;
  bool result = false;

  args = FUNCTION_FIRST_USER_PARMTYPE (d);
  if (!args)
    return 0;

  arg_type = TREE_VALUE (args);
  if (arg_type == error_mark_node)
    return 0;

  if (TYPE_REF_P (arg_type)
      && TYPE_REF_IS_RVALUE (arg_type)
      && same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (arg_type)),
                      DECL_CONTEXT (d)))
    result = true;

  args = TREE_CHAIN (args);

  if (args && args != void_list_node && !TREE_PURPOSE (args))
    /* There are more non-optional args.  */
    return false;

  return result;
}

/* Remember any special properties of member function DECL.  */

void
grok_special_member_properties (tree decl)
{
  tree class_type;

  if (!DECL_NONSTATIC_MEMBER_FUNCTION_P (decl))
    return;

  class_type = DECL_CONTEXT (decl);
  if (IDENTIFIER_CTOR_P (DECL_NAME (decl)))
    {
      int ctor = copy_fn_p (decl);

      if (!DECL_ARTIFICIAL (decl))
	TYPE_HAS_USER_CONSTRUCTOR (class_type) = 1;

      if (ctor > 0)
	{
	  /* [class.copy]

	     A non-template constructor for class X is a copy
	     constructor if its first parameter is of type X&, const
	     X&, volatile X& or const volatile X&, and either there
	     are no other parameters or else all other parameters have
	     default arguments.  */
	  TYPE_HAS_COPY_CTOR (class_type) = 1;
	  if (user_provided_p (decl))
	    TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1;
	  if (ctor > 1)
	    TYPE_HAS_CONST_COPY_CTOR (class_type) = 1;
	}
      else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
	TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
      else if (move_fn_p (decl) && user_provided_p (decl))
	TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
      else if (is_list_ctor (decl))
	TYPE_HAS_LIST_CTOR (class_type) = 1;

      if (DECL_DECLARED_CONSTEXPR_P (decl)
	  && !ctor && !move_fn_p (decl))
	TYPE_HAS_CONSTEXPR_CTOR (class_type) = 1;
    }
  else if (DECL_NAME (decl) == assign_op_identifier)
    {
      /* [class.copy]

	 A non-template assignment operator for class X is a copy
	 assignment operator if its parameter is of type X, X&, const
	 X&, volatile X& or const volatile X&.  */

      int assop = copy_fn_p (decl);

      if (assop)
	{
	  TYPE_HAS_COPY_ASSIGN (class_type) = 1;
	  if (user_provided_p (decl))
	    TYPE_HAS_COMPLEX_COPY_ASSIGN (class_type) = 1;
	  if (assop != 1)
	    TYPE_HAS_CONST_COPY_ASSIGN (class_type) = 1;
	}
      else if (move_fn_p (decl) && user_provided_p (decl))
	TYPE_HAS_COMPLEX_MOVE_ASSIGN (class_type) = 1;
    }
  else if (IDENTIFIER_CONV_OP_P (DECL_NAME (decl)))
    TYPE_HAS_CONVERSION (class_type) = true;
  
  /* Destructors are handled in check_methods.  */
}

/* Check a constructor DECL has the correct form.  Complains
   if the class has a constructor of the form X(X).  */

bool
grok_ctor_properties (const_tree ctype, const_tree decl)
{
  int ctor_parm = copy_fn_p (decl);

  if (ctor_parm < 0)
    {
      /* [class.copy]

	 A declaration of a constructor for a class X is ill-formed if
	 its first parameter is of type (optionally cv-qualified) X
	 and either there are no other parameters or else all other
	 parameters have default arguments.

	 We *don't* complain about member template instantiations that
	 have this form, though; they can occur as we try to decide
	 what constructor to use during overload resolution.  Since
	 overload resolution will never prefer such a constructor to
	 the non-template copy constructor (which is either explicitly
	 or implicitly defined), there's no need to worry about their
	 existence.  Theoretically, they should never even be
	 instantiated, but that's hard to forestall.  */
      error ("invalid constructor; you probably meant %<%T (const %T&)%>",
		ctype, ctype);
      return false;
    }

  return true;
}

/* DECL is a declaration for an overloaded or conversion operator.  If
   COMPLAIN is true, errors are issued for invalid declarations.  */

bool
grok_op_properties (tree decl, bool complain)
{
  tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl));
  bool methodp = TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE;
  tree name = DECL_NAME (decl);
  location_t loc = DECL_SOURCE_LOCATION (decl);

  tree class_type = DECL_CONTEXT (decl);
  if (class_type && !CLASS_TYPE_P (class_type))
    class_type = NULL_TREE;

  tree_code operator_code;
  unsigned op_flags;
  if (IDENTIFIER_CONV_OP_P (name))
    {
      /* Conversion operators are TYPE_EXPR for the purposes of this
	 function.  */
      operator_code = TYPE_EXPR;
      op_flags = OVL_OP_FLAG_UNARY;
    }
  else
    {
      const ovl_op_info_t *ovl_op = IDENTIFIER_OVL_OP_INFO (name);

      operator_code = ovl_op->tree_code;
      op_flags = ovl_op->flags;
      gcc_checking_assert (operator_code != ERROR_MARK);
      DECL_OVERLOADED_OPERATOR_CODE_RAW (decl) = ovl_op->ovl_op_code;
    }

  if (op_flags & OVL_OP_FLAG_ALLOC)
    {
      /* operator new and operator delete are quite special.  */
      if (class_type)
	switch (op_flags)
	  {
	  case OVL_OP_FLAG_ALLOC:
	    TYPE_HAS_NEW_OPERATOR (class_type) = 1;
	    break;

	  case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE:
	    TYPE_GETS_DELETE (class_type) |= 1;
	    break;

	  case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_VEC:
	    TYPE_HAS_ARRAY_NEW_OPERATOR (class_type) = 1;
	    break;

	  case OVL_OP_FLAG_ALLOC | OVL_OP_FLAG_DELETE | OVL_OP_FLAG_VEC:
	    TYPE_GETS_DELETE (class_type) |= 2;
	    break;

	  default:
	    gcc_unreachable ();
	  }

      /* [basic.std.dynamic.allocation]/1:

	 A program is ill-formed if an allocation function is declared
	 in a namespace scope other than global scope or declared
	 static in global scope.

	 The same also holds true for deallocation functions.  */
      if (DECL_NAMESPACE_SCOPE_P (decl))
	{
	  if (CP_DECL_CONTEXT (decl) != global_namespace)
	    {
	      error_at (loc, "%qD may not be declared within a namespace",
			decl);
	      return false;
	    }

	  if (!TREE_PUBLIC (decl))
	    {
	      error_at (loc, "%qD may not be declared as static", decl);
	      return false;
	    }
	}

      if (op_flags & OVL_OP_FLAG_DELETE)
	coerce_delete_type (decl, loc);
      else
	{
	  DECL_IS_OPERATOR_NEW (decl) = 1;
	  TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl), loc);
	}

      return true;
    }

  /* An operator function must either be a non-static member function
     or have at least one parameter of a class, a reference to a class,
     an enumeration, or a reference to an enumeration.  13.4.0.6 */
  if (! methodp || DECL_STATIC_FUNCTION_P (decl))
    {
      if (operator_code == TYPE_EXPR
	  || operator_code == CALL_EXPR
	  || operator_code == COMPONENT_REF
	  || operator_code == ARRAY_REF
	  || operator_code == NOP_EXPR)
	{
	  error_at (loc, "%qD must be a nonstatic member function", decl);
	  return false;
	}

      if (DECL_STATIC_FUNCTION_P (decl))
	{
	  error_at (loc, "%qD must be either a non-static member "
		    "function or a non-member function", decl);
	  return false;
	}

      for (tree arg = argtypes; ; arg = TREE_CHAIN (arg))
	{
	  if (!arg || arg == void_list_node)
	    {
	      if (complain)
		error_at(loc, "%qD must have an argument of class or "
			 "enumerated type", decl);
	      return false;
	    }
      
	  tree type = non_reference (TREE_VALUE (arg));
	  if (type == error_mark_node)
	    return false;
	  
	  /* MAYBE_CLASS_TYPE_P, rather than CLASS_TYPE_P, is used
	     because these checks are performed even on template
	     functions.  */
	  if (MAYBE_CLASS_TYPE_P (type)
	      || TREE_CODE (type) == ENUMERAL_TYPE)
	    break;
	}
    }

  if (operator_code == CALL_EXPR)
    /* There are no further restrictions on the arguments to an overloaded
       "operator ()".  */
    return true;

  if (operator_code == COND_EXPR)
    {
      /* 13.4.0.3 */
      error_at (loc, "ISO C++ prohibits overloading operator ?:");
      return false;
    }

  /* Count the number of arguments and check for ellipsis.  */
  int arity = 0;
  for (tree arg = argtypes; arg != void_list_node; arg = TREE_CHAIN (arg))
    {
      if (!arg)
	{
	  /* Variadic.  */
	  error_at (loc, "%qD must not have variable number of arguments",
		    decl);
	  return false;
	}
      ++arity;
    }

  /* Verify correct number of arguments.  */
  switch (op_flags)
    {
    case OVL_OP_FLAG_AMBIARY:
      if (arity == 1)
	{
	  /* We have a unary instance of an ambi-ary op.  Remap to the
	     unary one.  */
	  unsigned alt = ovl_op_alternate[ovl_op_mapping [operator_code]];
	  const ovl_op_info_t *ovl_op = &ovl_op_info[false][alt];
	  gcc_checking_assert (ovl_op->flags == OVL_OP_FLAG_UNARY);
	  operator_code = ovl_op->tree_code;
	  DECL_OVERLOADED_OPERATOR_CODE_RAW (decl) = ovl_op->ovl_op_code;
	}
      else if (arity != 2)
	{
	  /* This was an ambiguous operator but is invalid. */
	  error_at (loc,
		    methodp
		    ? G_("%qD must have either zero or one argument")
		    : G_("%qD must have either one or two arguments"), decl);
	  return false;
	}
      else if ((operator_code == POSTINCREMENT_EXPR
		|| operator_code == POSTDECREMENT_EXPR)
	       && ! processing_template_decl
	       /* x++ and x--'s second argument must be an int.  */
	       && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)),
				 integer_type_node))
	{
	  error_at (loc,
		    methodp
		    ? G_("postfix %qD must have %<int%> as its argument")
		    : G_("postfix %qD must have %<int%> as its second argument"),
		    decl);
	  return false;
	}
      break;

    case OVL_OP_FLAG_UNARY:
      if (arity != 1)
	{
	  error_at (loc,
		    methodp
		    ? G_("%qD must have no arguments")
		    : G_("%qD must have exactly one argument"), decl);
	  return false;
	}
      break;

    case OVL_OP_FLAG_BINARY:
      if (arity != 2)
	{
	  error_at (loc,
		    methodp
		    ? G_("%qD must have exactly one argument")
		    : G_("%qD must have exactly two arguments"), decl);
	  return false;
	}
      break;

    default:
      gcc_unreachable ();
    }

  /* There can be no default arguments.  */
  for (tree arg = argtypes; arg != void_list_node; arg = TREE_CHAIN (arg))
    if (TREE_PURPOSE (arg))
      {
	TREE_PURPOSE (arg) = NULL_TREE;
	error_at (loc, "%qD cannot have default arguments", decl);
	return false;
      }

  /* At this point the declaration is well-formed.  It may not be
     sensible though.  */

  /* Check member function warnings only on the in-class declaration.
     There's no point warning on an out-of-class definition.  */
  if (class_type && class_type != current_class_type)
    return true;

  /* Warn about conversion operators that will never be used.  */
  if (IDENTIFIER_CONV_OP_P (name)
      && ! DECL_TEMPLATE_INFO (decl)
      && warn_class_conversion)
    {
      tree t = TREE_TYPE (name);
      int ref = TYPE_REF_P (t);

      if (ref)
	t = TYPE_MAIN_VARIANT (TREE_TYPE (t));

      if (VOID_TYPE_P (t))
	warning_at (loc, OPT_Wclass_conversion, "converting %qT to %<void%> "
		    "will never use a type conversion operator", class_type);
      else if (class_type)
	{
	  if (same_type_ignoring_top_level_qualifiers_p (t, class_type))
	    warning_at (loc, OPT_Wclass_conversion,
			ref
			? G_("converting %qT to a reference to the same type "
			     "will never use a type conversion operator")
			: G_("converting %qT to the same type "
			     "will never use a type conversion operator"),
			class_type);
	  /* Don't force t to be complete here.  */
	  else if (MAYBE_CLASS_TYPE_P (t)
		   && COMPLETE_TYPE_P (t)
		   && DERIVED_FROM_P (t, class_type))
	    warning_at (loc, OPT_Wclass_conversion,
			ref
			? G_("converting %qT to a reference to a base class "
			     "%qT will never use a type conversion operator")
			: G_("converting %qT to a base class %qT "
			     "will never use a type conversion operator"),
			class_type, t);
	}
    }

  if (!warn_ecpp)
    return true;

  /* Effective C++ rules below.  */

  /* More Effective C++ rule 7.  */
  if (operator_code == TRUTH_ANDIF_EXPR
      || operator_code == TRUTH_ORIF_EXPR
      || operator_code == COMPOUND_EXPR)
    warning_at (loc, OPT_Weffc__,
		"user-defined %qD always evaluates both arguments", decl);
  
  /* More Effective C++ rule 6.  */
  if (operator_code == POSTINCREMENT_EXPR
      || operator_code == POSTDECREMENT_EXPR
      || operator_code == PREINCREMENT_EXPR
      || operator_code == PREDECREMENT_EXPR)
    {
      tree arg = TREE_VALUE (argtypes);
      tree ret = TREE_TYPE (TREE_TYPE (decl));
      if (methodp || TYPE_REF_P (arg))
	arg = TREE_TYPE (arg);
      arg = TYPE_MAIN_VARIANT (arg);

      if (operator_code == PREINCREMENT_EXPR
	  || operator_code == PREDECREMENT_EXPR)
	{
	  if (!TYPE_REF_P (ret)
	      || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), arg))
	    warning_at (loc, OPT_Weffc__, "prefix %qD should return %qT", decl,
			build_reference_type (arg));
	}
      else
	{
	  if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg))
	    warning_at (loc, OPT_Weffc__,
			"postfix %qD should return %qT", decl, arg);
	}
    }

  /* Effective C++ rule 23.  */
  if (!DECL_ASSIGNMENT_OPERATOR_P (decl)
      && (operator_code == PLUS_EXPR
	  || operator_code == MINUS_EXPR
	  || operator_code == TRUNC_DIV_EXPR
	  || operator_code == MULT_EXPR
	  || operator_code == TRUNC_MOD_EXPR)
      && TYPE_REF_P (TREE_TYPE (TREE_TYPE (decl))))
    warning_at (loc, OPT_Weffc__, "%qD should return by value", decl);

  return true;
}

/* Return a string giving the keyword associate with CODE.  */

static const char *
tag_name (enum tag_types code)
{
  switch (code)
    {
    case record_type:
      return "struct";
    case class_type:
      return "class";
    case union_type:
      return "union";
    case enum_type:
      return "enum";
    case typename_type:
      return "typename";
    default:
      gcc_unreachable ();
    }
}

/* Name lookup in an elaborated-type-specifier (after the keyword
   indicated by TAG_CODE) has found the TYPE_DECL DECL.  If the
   elaborated-type-specifier is invalid, issue a diagnostic and return
   error_mark_node; otherwise, return the *_TYPE to which it referred.
   If ALLOW_TEMPLATE_P is true, TYPE may be a class template.  */

tree
check_elaborated_type_specifier (enum tag_types tag_code,
				 tree decl,
				 bool allow_template_p)
{
  tree type;

  /* In the case of:

       struct S { struct S *p; };

     name lookup will find the TYPE_DECL for the implicit "S::S"
     typedef.  Adjust for that here.  */
  if (DECL_SELF_REFERENCE_P (decl))
    decl = TYPE_NAME (TREE_TYPE (decl));

  type = TREE_TYPE (decl);

  /* Check TEMPLATE_TYPE_PARM first because DECL_IMPLICIT_TYPEDEF_P
     is false for this case as well.  */
  if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
    {
      error ("using template type parameter %qT after %qs",
	     type, tag_name (tag_code));
      return error_mark_node;
    }
  /* Accept template template parameters.  */
  else if (allow_template_p
	   && (TREE_CODE (type) == BOUND_TEMPLATE_TEMPLATE_PARM
	       || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM))
    ;
  /*   [dcl.type.elab]

       If the identifier resolves to a typedef-name or the
       simple-template-id resolves to an alias template
       specialization, the elaborated-type-specifier is ill-formed.

     In other words, the only legitimate declaration to use in the
     elaborated type specifier is the implicit typedef created when
     the type is declared.  */
  else if (!DECL_IMPLICIT_TYPEDEF_P (decl)
	   && !DECL_SELF_REFERENCE_P (decl)
	   && tag_code != typename_type)
    {
      if (alias_template_specialization_p (type))
	error ("using alias template specialization %qT after %qs",
	       type, tag_name (tag_code));
      else
	error ("using typedef-name %qD after %qs", decl, tag_name (tag_code));
      inform (DECL_SOURCE_LOCATION (decl),
	      "%qD has a previous declaration here", decl);
      return error_mark_node;
    }
  else if (TREE_CODE (type) != RECORD_TYPE
	   && TREE_CODE (type) != UNION_TYPE
	   && tag_code != enum_type
	   && tag_code != typename_type)
    {
      error ("%qT referred to as %qs", type, tag_name (tag_code));
      inform (location_of (type), "%qT has a previous declaration here", type);
      return error_mark_node;
    }
  else if (TREE_CODE (type) != ENUMERAL_TYPE
	   && tag_code == enum_type)
    {
      error ("%qT referred to as enum", type);
      inform (location_of (type), "%qT has a previous declaration here", type);
      return error_mark_node;
    }
  else if (!allow_template_p
	   && TREE_CODE (type) == RECORD_TYPE
	   && CLASSTYPE_IS_TEMPLATE (type))
    {
      /* If a class template appears as elaborated type specifier
	 without a template header such as:

	   template <class T> class C {};
	   void f(class C);		// No template header here

	 then the required template argument is missing.  */
      error ("template argument required for %<%s %T%>",
	     tag_name (tag_code),
	     DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)));
      return error_mark_node;
    }

  return type;
}

/* Lookup NAME in elaborate type specifier in scope according to
   SCOPE and issue diagnostics if necessary.
   Return *_TYPE node upon success, NULL_TREE when the NAME is not
   found, and ERROR_MARK_NODE for type error.  */

static tree
lookup_and_check_tag (enum tag_types tag_code, tree name,
		      tag_scope scope, bool template_header_p)
{
  tree t;
  tree decl;
  if (scope == ts_global)
    {
      /* First try ordinary name lookup, ignoring hidden class name
	 injected via friend declaration.  */
      decl = lookup_name_prefer_type (name, 2);
      decl = strip_using_decl (decl);
      /* If that fails, the name will be placed in the smallest
	 non-class, non-function-prototype scope according to 3.3.1/5.
	 We may already have a hidden name declared as friend in this
	 scope.  So lookup again but not ignoring hidden names.
	 If we find one, that name will be made visible rather than
	 creating a new tag.  */
      if (!decl)
	decl = lookup_type_scope (name, ts_within_enclosing_non_class);
    }
  else
    decl = lookup_type_scope (name, scope);

  if (decl
      && (DECL_CLASS_TEMPLATE_P (decl)
	  /* If scope is ts_current we're defining a class, so ignore a
	     template template parameter.  */
	  || (scope != ts_current
	      && DECL_TEMPLATE_TEMPLATE_PARM_P (decl))))
    decl = DECL_TEMPLATE_RESULT (decl);

  if (decl && TREE_CODE (decl) == TYPE_DECL)
    {
      /* Look for invalid nested type:
	   class C {
	     class C {};
	   };  */
      if (scope == ts_current && DECL_SELF_REFERENCE_P (decl))
	{
	  error ("%qD has the same name as the class in which it is "
		 "declared",
		 decl);
	  return error_mark_node;
	}

      /* Two cases we need to consider when deciding if a class
	 template is allowed as an elaborated type specifier:
	 1. It is a self reference to its own class.
	 2. It comes with a template header.

	 For example:

	   template <class T> class C {
	     class C *c1;		// DECL_SELF_REFERENCE_P is true
	     class D;
	   };
	   template <class U> class C; // template_header_p is true
	   template <class T> class C<T>::D {
	     class C *c2;		// DECL_SELF_REFERENCE_P is true
	   };  */

      t = check_elaborated_type_specifier (tag_code,
					   decl,
					   template_header_p
					   | DECL_SELF_REFERENCE_P (decl));
      if (template_header_p && t && CLASS_TYPE_P (t)
	  && (!CLASSTYPE_TEMPLATE_INFO (t)
	      || (!PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)))))
	{
	  error ("%qT is not a template", t);
	  inform (location_of (t), "previous declaration here");
	  if (TYPE_CLASS_SCOPE_P (t)
	      && CLASSTYPE_TEMPLATE_INFO (TYPE_CONTEXT (t)))
	    inform (input_location,
		    "perhaps you want to explicitly add %<%T::%>",
		    TYPE_CONTEXT (t));
	  t = error_mark_node;
	}

      return t;
    }
  else if (decl && TREE_CODE (decl) == TREE_LIST)
    {
      error ("reference to %qD is ambiguous", name);
      print_candidates (decl);
      return error_mark_node;
    }
  else
    return NULL_TREE;
}

/* Get the struct, enum or union (TAG_CODE says which) with tag NAME.
   Define the tag as a forward-reference if it is not defined.

   If a declaration is given, process it here, and report an error if
   multiple declarations are not identical.

   SCOPE is TS_CURRENT when this is also a definition.  Only look in
   the current frame for the name (since C++ allows new names in any
   scope.)  It is TS_WITHIN_ENCLOSING_NON_CLASS if this is a friend
   declaration.  Only look beginning from the current scope outward up
   till the nearest non-class scope.  Otherwise it is TS_GLOBAL.

   TEMPLATE_HEADER_P is true when this declaration is preceded by
   a set of template parameters.  */

static tree
xref_tag_1 (enum tag_types tag_code, tree name,
            tag_scope scope, bool template_header_p)
{
  enum tree_code code;
  tree context = NULL_TREE;

  gcc_assert (identifier_p (name));

  switch (tag_code)
    {
    case record_type:
    case class_type:
      code = RECORD_TYPE;
      break;
    case union_type:
      code = UNION_TYPE;
      break;
    case enum_type:
      code = ENUMERAL_TYPE;
      break;
    default:
      gcc_unreachable ();
    }

  /* In case of anonymous name, xref_tag is only called to
     make type node and push name.  Name lookup is not required.  */
  tree t = NULL_TREE;
  if (scope != ts_lambda && !anon_aggrname_p (name))
    t = lookup_and_check_tag  (tag_code, name, scope, template_header_p);
  
  if (t == error_mark_node)
    return error_mark_node;

  if (scope != ts_current && t && current_class_type
      && template_class_depth (current_class_type)
      && template_header_p)
    {
      if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM)
	return t;

      /* Since SCOPE is not TS_CURRENT, we are not looking at a
	 definition of this tag.  Since, in addition, we are currently
	 processing a (member) template declaration of a template
	 class, we must be very careful; consider:

	   template <class X> struct S1

	   template <class U> struct S2
	   {
	     template <class V> friend struct S1;
	   };

	 Here, the S2::S1 declaration should not be confused with the
	 outer declaration.  In particular, the inner version should
	 have a template parameter of level 2, not level 1.

	 On the other hand, when presented with:

	   template <class T> struct S1
	   {
	     template <class U> struct S2 {};
	     template <class U> friend struct S2;
	   };

	 the friend must find S1::S2 eventually.  We accomplish this
	 by making sure that the new type we create to represent this
	 declaration has the right TYPE_CONTEXT.  */
      context = TYPE_CONTEXT (t);
      t = NULL_TREE;
    }

  if (! t)
    {
      /* If no such tag is yet defined, create a forward-reference node
	 and record it as the "definition".
	 When a real declaration of this type is found,
	 the forward-reference will be altered into a real type.  */
      if (code == ENUMERAL_TYPE)
	{
	  error ("use of enum %q#D without previous declaration", name);
	  return error_mark_node;
	}
      else
	{
	  t = make_class_type (code);
	  TYPE_CONTEXT (t) = context;
	  if (scope == ts_lambda)
	    {
	      /* Mark it as a lambda type.  */
	      CLASSTYPE_LAMBDA_EXPR (t) = error_mark_node;
	      /* And push it into current scope.  */
	      scope = ts_current;
	    }
	  t = pushtag (name, t, scope);
	}
    }
  else
    {
      if (template_header_p && MAYBE_CLASS_TYPE_P (t))
        {
          /* Check that we aren't trying to overload a class with different
             constraints.  */
          tree constr = NULL_TREE;
          if (current_template_parms)
            {
              tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
              constr = build_constraints (reqs, NULL_TREE);
            }
	  if (!redeclare_class_template (t, current_template_parms, constr))
	    return error_mark_node;
        }
      else if (!processing_template_decl
	       && CLASS_TYPE_P (t)
	       && CLASSTYPE_IS_TEMPLATE (t))
	{
	  error ("redeclaration of %qT as a non-template", t);
	  inform (location_of (t), "previous declaration %qD", t);
	  return error_mark_node;
	}

      if (scope != ts_within_enclosing_non_class && TYPE_HIDDEN_P (t))
	{
	  /* This is no longer an invisible friend.  Make it
	     visible.  */
	  tree decl = TYPE_NAME (t);

	  DECL_ANTICIPATED (decl) = false;
	  DECL_FRIEND_P (decl) = false;

	  if (TYPE_TEMPLATE_INFO (t))
	    {
	      tree tmpl = TYPE_TI_TEMPLATE (t);
	      DECL_ANTICIPATED (tmpl) = false;
	      DECL_FRIEND_P (tmpl) = false;
	    }
	}
    }

  return t;
}

/* Wrapper for xref_tag_1.  */

tree
xref_tag (enum tag_types tag_code, tree name,
          tag_scope scope, bool template_header_p)
{
  tree ret;
  bool subtime;
  subtime = timevar_cond_start (TV_NAME_LOOKUP);
  ret = xref_tag_1 (tag_code, name, scope, template_header_p);
  timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  return ret;
}


tree
xref_tag_from_type (tree old, tree id, tag_scope scope)
{
  enum tag_types tag_kind;

  if (TREE_CODE (old) == RECORD_TYPE)
    tag_kind = (CLASSTYPE_DECLARED_CLASS (old) ? class_type : record_type);
  else
    tag_kind  = union_type;

  if (id == NULL_TREE)
    id = TYPE_IDENTIFIER (old);

  return xref_tag (tag_kind, id, scope, false);
}

/* Create the binfo hierarchy for REF with (possibly NULL) base list
   BASE_LIST.  For each element on BASE_LIST the TREE_PURPOSE is an
   access_* node, and the TREE_VALUE is the type of the base-class.
   Non-NULL TREE_TYPE indicates virtual inheritance.  */

void
xref_basetypes (tree ref, tree base_list)
{
  tree *basep;
  tree binfo, base_binfo;
  unsigned max_vbases = 0; /* Maximum direct & indirect virtual bases.  */
  unsigned max_bases = 0;  /* Maximum direct bases.  */
  unsigned max_dvbases = 0; /* Maximum direct virtual bases.  */
  int i;
  tree default_access;
  tree igo_prev; /* Track Inheritance Graph Order.  */

  if (ref == error_mark_node)
    return;

  /* The base of a derived class is private by default, all others are
     public.  */
  default_access = (TREE_CODE (ref) == RECORD_TYPE
		    && CLASSTYPE_DECLARED_CLASS (ref)
		    ? access_private_node : access_public_node);

  /* First, make sure that any templates in base-classes are
     instantiated.  This ensures that if we call ourselves recursively
     we do not get confused about which classes are marked and which
     are not.  */
  basep = &base_list;
  while (*basep)
    {
      tree basetype = TREE_VALUE (*basep);

      /* The dependent_type_p call below should really be dependent_scope_p
	 so that we give a hard error about using an incomplete type as a
	 base, but we allow it with a pedwarn for backward
	 compatibility.  */
      if (processing_template_decl
	  && CLASS_TYPE_P (basetype) && TYPE_BEING_DEFINED (basetype))
	cxx_incomplete_type_diagnostic (NULL_TREE, basetype, DK_PEDWARN);
      if (!dependent_type_p (basetype)
	  && !complete_type_or_else (basetype, NULL))
	/* An incomplete type.  Remove it from the list.  */
	*basep = TREE_CHAIN (*basep);
      else
	{
	  max_bases++;
	  if (TREE_TYPE (*basep))
	    max_dvbases++;
	  if (CLASS_TYPE_P (basetype))
	    max_vbases += vec_safe_length (CLASSTYPE_VBASECLASSES (basetype));
	  basep = &TREE_CHAIN (*basep);
	}
    }
  max_vbases += max_dvbases;

  TYPE_MARKED_P (ref) = 1;

  /* The binfo slot should be empty, unless this is an (ill-formed)
     redefinition.  */
  gcc_assert (!TYPE_BINFO (ref) || TYPE_SIZE (ref));

  gcc_assert (TYPE_MAIN_VARIANT (ref) == ref);

  binfo = make_tree_binfo (max_bases);

  TYPE_BINFO (ref) = binfo;
  BINFO_OFFSET (binfo) = size_zero_node;
  BINFO_TYPE (binfo) = ref;

  /* Apply base-class info set up to the variants of this type.  */
  fixup_type_variants (ref);

  if (max_bases)
    {
      vec_alloc (BINFO_BASE_ACCESSES (binfo), max_bases);
      /* A C++98 POD cannot have base classes.  */
      CLASSTYPE_NON_LAYOUT_POD_P (ref) = true;

      if (TREE_CODE (ref) == UNION_TYPE)
	{
	  error ("derived union %qT invalid", ref);
	  return;
	}
    }

  if (max_bases > 1)
    warning (OPT_Wmultiple_inheritance,
	     "%qT defined with multiple direct bases", ref);

  if (max_vbases)
    {
      /* An aggregate can't have virtual base classes.  */
      CLASSTYPE_NON_AGGREGATE (ref) = true;

      vec_alloc (CLASSTYPE_VBASECLASSES (ref), max_vbases);

      if (max_dvbases)
	warning (OPT_Wvirtual_inheritance,
		 "%qT defined with direct virtual base", ref);
    }

  for (igo_prev = binfo; base_list; base_list = TREE_CHAIN (base_list))
    {
      tree access = TREE_PURPOSE (base_list);
      int via_virtual = TREE_TYPE (base_list) != NULL_TREE;
      tree basetype = TREE_VALUE (base_list);

      if (access == access_default_node)
	access = default_access;

      /* Before C++17, an aggregate cannot have base classes.  In C++17, an
	 aggregate can't have virtual, private, or protected base classes.  */
      if (cxx_dialect < cxx17
	  || access != access_public_node
	  || via_virtual)
	CLASSTYPE_NON_AGGREGATE (ref) = true;

      if (PACK_EXPANSION_P (basetype))
        basetype = PACK_EXPANSION_PATTERN (basetype);
      if (TREE_CODE (basetype) == TYPE_DECL)
	basetype = TREE_TYPE (basetype);
      if (!MAYBE_CLASS_TYPE_P (basetype) || TREE_CODE (basetype) == UNION_TYPE)
	{
	  error ("base type %qT fails to be a struct or class type",
		 basetype);
	  goto dropped_base;
	}

      base_binfo = NULL_TREE;
      if (CLASS_TYPE_P (basetype) && !dependent_scope_p (basetype))
	{
	  base_binfo = TYPE_BINFO (basetype);
	  /* The original basetype could have been a typedef'd type.  */
	  basetype = BINFO_TYPE (base_binfo);

	  /* Inherit flags from the base.  */
	  TYPE_HAS_NEW_OPERATOR (ref)
	    |= TYPE_HAS_NEW_OPERATOR (basetype);
	  TYPE_HAS_ARRAY_NEW_OPERATOR (ref)
	    |= TYPE_HAS_ARRAY_NEW_OPERATOR (basetype);
	  TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype);
	  TYPE_HAS_CONVERSION (ref) |= TYPE_HAS_CONVERSION (basetype);
	  CLASSTYPE_DIAMOND_SHAPED_P (ref)
	    |= CLASSTYPE_DIAMOND_SHAPED_P (basetype);
	  CLASSTYPE_REPEATED_BASE_P (ref)
	    |= CLASSTYPE_REPEATED_BASE_P (basetype);
	}

      /* We must do this test after we've seen through a typedef
	 type.  */
      if (TYPE_MARKED_P (basetype))
	{
	  if (basetype == ref)
	    error ("recursive type %qT undefined", basetype);
	  else
	    error ("duplicate base type %qT invalid", basetype);
	  goto dropped_base;
	}

      if (PACK_EXPANSION_P (TREE_VALUE (base_list)))
        /* Regenerate the pack expansion for the bases. */
        basetype = make_pack_expansion (basetype);

      TYPE_MARKED_P (basetype) = 1;

      base_binfo = copy_binfo (base_binfo, basetype, ref,
			       &igo_prev, via_virtual);
      if (!BINFO_INHERITANCE_CHAIN (base_binfo))
	BINFO_INHERITANCE_CHAIN (base_binfo) = binfo;

      BINFO_BASE_APPEND (binfo, base_binfo);
      BINFO_BASE_ACCESS_APPEND (binfo, access);
      continue;

    dropped_base:
      /* Update max_vbases to reflect the reality that we are dropping
	 this base:  if it reaches zero we want to undo the vec_alloc
	 above to avoid inconsistencies during error-recovery: eg, in
	 build_special_member_call, CLASSTYPE_VBASECLASSES non null
	 and vtt null (c++/27952).  */
      if (via_virtual)
	max_vbases--;
      if (CLASS_TYPE_P (basetype))
	max_vbases
	  -= vec_safe_length (CLASSTYPE_VBASECLASSES (basetype));
    }

  if (CLASSTYPE_VBASECLASSES (ref)
      && max_vbases == 0)
    vec_free (CLASSTYPE_VBASECLASSES (ref));

  if (vec_safe_length (CLASSTYPE_VBASECLASSES (ref)) < max_vbases)
    /* If we didn't get max_vbases vbases, we must have shared at
       least one of them, and are therefore diamond shaped.  */
    CLASSTYPE_DIAMOND_SHAPED_P (ref) = 1;

  /* Unmark all the types.  */
  for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
    TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
  TYPE_MARKED_P (ref) = 0;

  /* Now see if we have a repeated base type.  */
  if (!CLASSTYPE_REPEATED_BASE_P (ref))
    {
      for (base_binfo = binfo; base_binfo;
	   base_binfo = TREE_CHAIN (base_binfo))
	{
	  if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
	    {
	      CLASSTYPE_REPEATED_BASE_P (ref) = 1;
	      break;
	    }
	  TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 1;
	}
      for (base_binfo = binfo; base_binfo;
	   base_binfo = TREE_CHAIN (base_binfo))
	if (TYPE_MARKED_P (BINFO_TYPE (base_binfo)))
	  TYPE_MARKED_P (BINFO_TYPE (base_binfo)) = 0;
	else
	  break;
    }
}


/* Copies the enum-related properties from type SRC to type DST.
   Used with the underlying type of an enum and the enum itself.  */
static void
copy_type_enum (tree dst, tree src)
{
  tree t;
  for (t = dst; t; t = TYPE_NEXT_VARIANT (t))
    {
      TYPE_MIN_VALUE (t) = TYPE_MIN_VALUE (src);
      TYPE_MAX_VALUE (t) = TYPE_MAX_VALUE (src);
      TYPE_SIZE (t) = TYPE_SIZE (src);
      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (src);
      SET_TYPE_MODE (dst, TYPE_MODE (src));
      TYPE_PRECISION (t) = TYPE_PRECISION (src);
      unsigned valign = TYPE_ALIGN (src);
      if (TYPE_USER_ALIGN (t))
	valign = MAX (valign, TYPE_ALIGN (t));
      else
	TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (src);
      SET_TYPE_ALIGN (t, valign);
      TYPE_UNSIGNED (t) = TYPE_UNSIGNED (src);
    }
}

/* Begin compiling the definition of an enumeration type.
   NAME is its name, 

   if ENUMTYPE is not NULL_TREE then the type has alredy been found.

   UNDERLYING_TYPE is the type that will be used as the storage for
   the enumeration type. This should be NULL_TREE if no storage type
   was specified.

   ATTRIBUTES are any attributes specified after the enum-key.

   SCOPED_ENUM_P is true if this is a scoped enumeration type.

   if IS_NEW is not NULL, gets TRUE iff a new type is created.

   Returns the type object, as yet incomplete.
   Also records info about it so that build_enumerator
   may be used to declare the individual values as they are read.  */

tree
start_enum (tree name, tree enumtype, tree underlying_type,
	    tree attributes, bool scoped_enum_p, bool *is_new)
{
  tree prevtype = NULL_TREE;
  gcc_assert (identifier_p (name));

  if (is_new)
    *is_new = false;
  /* [C++0x dcl.enum]p5:

    If not explicitly specified, the underlying type of a scoped
    enumeration type is int.  */
  if (!underlying_type && scoped_enum_p)
    underlying_type = integer_type_node;

  if (underlying_type)
    underlying_type = cv_unqualified (underlying_type);

  /* If this is the real definition for a previous forward reference,
     fill in the contents in the same object that used to be the
     forward reference.  */
  if (!enumtype)
    enumtype = lookup_and_check_tag (enum_type, name,
				     /*tag_scope=*/ts_current,
				     /*template_header_p=*/false);

  /* In case of a template_decl, the only check that should be deferred
     to instantiation time is the comparison of underlying types.  */
  if (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE)
    {
      if (scoped_enum_p != SCOPED_ENUM_P (enumtype))
	{
	  error_at (input_location, "scoped/unscoped mismatch "
		    "in enum %q#T", enumtype);
	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
		  "previous definition here");
	  enumtype = error_mark_node;
	}
      else if (ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) != !! underlying_type)
	{
	  error_at (input_location, "underlying type mismatch "
		    "in enum %q#T", enumtype);
	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
		  "previous definition here");
	  enumtype = error_mark_node;
	}
      else if (underlying_type && ENUM_UNDERLYING_TYPE (enumtype)
	       && !same_type_p (underlying_type,
				ENUM_UNDERLYING_TYPE (enumtype)))
	{
	  error_at (input_location, "different underlying type "
		    "in enum %q#T", enumtype);
	  inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (enumtype)),
		  "previous definition here");
	  underlying_type = NULL_TREE;
	}
    }

  if (!enumtype || TREE_CODE (enumtype) != ENUMERAL_TYPE
      || processing_template_decl)
    {
      /* In case of error, make a dummy enum to allow parsing to
	 continue.  */
      if (enumtype == error_mark_node)
	{
	  name = make_anon_name ();
	  enumtype = NULL_TREE;
	}

      /* enumtype may be an ENUMERAL_TYPE if this is a redefinition
         of an opaque enum, or an opaque enum of an already defined
	 enumeration (C++11).
	 In any other case, it'll be NULL_TREE. */
      if (!enumtype)
	{
	  if (is_new)
	    *is_new = true;
	}
      prevtype = enumtype;

      /* Do not push the decl more than once.  */
      if (!enumtype
	  || TREE_CODE (enumtype) != ENUMERAL_TYPE)
	{
	  enumtype = cxx_make_type (ENUMERAL_TYPE);
	  enumtype = pushtag (name, enumtype, /*tag_scope=*/ts_current);

	  /* std::byte aliases anything.  */
	  if (enumtype != error_mark_node
	      && TYPE_CONTEXT (enumtype) == std_node
	      && !strcmp ("byte", TYPE_NAME_STRING (enumtype)))
	    TYPE_ALIAS_SET (enumtype) = 0;
	}
      else
	  enumtype = xref_tag (enum_type, name, /*tag_scope=*/ts_current,
			       false);

      if (enumtype == error_mark_node)
	return error_mark_node;

      /* The enum is considered opaque until the opening '{' of the
	 enumerator list.  */
      SET_OPAQUE_ENUM_P (enumtype, true);
      ENUM_FIXED_UNDERLYING_TYPE_P (enumtype) = !! underlying_type;
    }

  SET_SCOPED_ENUM_P (enumtype, scoped_enum_p);

  cplus_decl_attributes (&enumtype, attributes, (int)ATTR_FLAG_TYPE_IN_PLACE);

  if (underlying_type)
    {
      if (ENUM_UNDERLYING_TYPE (enumtype))
	/* We already checked that it matches, don't change it to a different
	   typedef variant.  */;
      else if (CP_INTEGRAL_TYPE_P (underlying_type))
        {
	  copy_type_enum (enumtype, underlying_type);
          ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
        }
      else if (dependent_type_p (underlying_type))
	ENUM_UNDERLYING_TYPE (enumtype) = underlying_type;
      else
        error ("underlying type %qT of %qT must be an integral type", 
               underlying_type, enumtype);
    }

  /* If into a template class, the returned enum is always the first
     declaration (opaque or not) seen. This way all the references to
     this type will be to the same declaration. The following ones are used
     only to check for definition errors.  */
  if (prevtype && processing_template_decl)
    return prevtype;
  else
    return enumtype;
}

/* After processing and defining all the values of an enumeration type,
   install their decls in the enumeration type.
   ENUMTYPE is the type object.  */

void
finish_enum_value_list (tree enumtype)
{
  tree values;
  tree underlying_type;
  tree decl;
  tree value;
  tree minnode, maxnode;
  tree t;

  bool fixed_underlying_type_p 
    = ENUM_UNDERLYING_TYPE (enumtype) != NULL_TREE;

  /* We built up the VALUES in reverse order.  */
  TYPE_VALUES (enumtype) = nreverse (TYPE_VALUES (enumtype));

  /* For an enum defined in a template, just set the type of the values;
     all further processing is postponed until the template is
     instantiated.  We need to set the type so that tsubst of a CONST_DECL
     works.  */
  if (processing_template_decl)
    {
      for (values = TYPE_VALUES (enumtype);
	   values;
	   values = TREE_CHAIN (values))
	TREE_TYPE (TREE_VALUE (values)) = enumtype;
      return;
    }

  /* Determine the minimum and maximum values of the enumerators.  */
  if (TYPE_VALUES (enumtype))
    {
      minnode = maxnode = NULL_TREE;

      for (values = TYPE_VALUES (enumtype);
	   values;
	   values = TREE_CHAIN (values))
	{
	  decl = TREE_VALUE (values);

	  /* [dcl.enum]: Following the closing brace of an enum-specifier,
	     each enumerator has the type of its enumeration.  Prior to the
	     closing brace, the type of each enumerator is the type of its
	     initializing value.  */
	  TREE_TYPE (decl) = enumtype;

	  /* Update the minimum and maximum values, if appropriate.  */
	  value = DECL_INITIAL (decl);
	  if (value == error_mark_node)
	    value = integer_zero_node;
	  /* Figure out what the minimum and maximum values of the
	     enumerators are.  */
	  if (!minnode)
	    minnode = maxnode = value;
	  else if (tree_int_cst_lt (maxnode, value))
	    maxnode = value;
	  else if (tree_int_cst_lt (value, minnode))
	    minnode = value;
	}
    }
  else
    /* [dcl.enum]

       If the enumerator-list is empty, the underlying type is as if
       the enumeration had a single enumerator with value 0.  */
    minnode = maxnode = integer_zero_node;

  if (!fixed_underlying_type_p)
    {
      /* Compute the number of bits require to represent all values of the
	 enumeration.  We must do this before the type of MINNODE and
	 MAXNODE are transformed, since tree_int_cst_min_precision relies
	 on the TREE_TYPE of the value it is passed.  */
      signop sgn = tree_int_cst_sgn (minnode) >= 0 ? UNSIGNED : SIGNED;
      int lowprec = tree_int_cst_min_precision (minnode, sgn);
      int highprec = tree_int_cst_min_precision (maxnode, sgn);
      int precision = MAX (lowprec, highprec);
      unsigned int itk;
      bool use_short_enum;

      /* Determine the underlying type of the enumeration.

         [dcl.enum]

         The underlying type of an enumeration is an integral type that
         can represent all the enumerator values defined in the
         enumeration.  It is implementation-defined which integral type is
         used as the underlying type for an enumeration except that the
         underlying type shall not be larger than int unless the value of
         an enumerator cannot fit in an int or unsigned int.

         We use "int" or an "unsigned int" as the underlying type, even if
         a smaller integral type would work, unless the user has
         explicitly requested that we use the smallest possible type.  The
         user can request that for all enumerations with a command line
         flag, or for just one enumeration with an attribute.  */

      use_short_enum = flag_short_enums
        || lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));

      /* If the precision of the type was specified with an attribute and it
	 was too small, give an error.  Otherwise, use it.  */
      if (TYPE_PRECISION (enumtype))
	{
	  if (precision > TYPE_PRECISION (enumtype))
	    error ("specified mode too small for enumeral values");
	  else
	    {
	      use_short_enum = true;
	      precision = TYPE_PRECISION (enumtype);
	    }
	}

      for (itk = (use_short_enum ? itk_char : itk_int);
           itk != itk_none;
           itk++)
        {
          underlying_type = integer_types[itk];
          if (underlying_type != NULL_TREE
	      && TYPE_PRECISION (underlying_type) >= precision
              && TYPE_SIGN (underlying_type) == sgn)
            break;
        }
      if (itk == itk_none)
        {
          /* DR 377

             IF no integral type can represent all the enumerator values, the
             enumeration is ill-formed.  */
          error ("no integral type can represent all of the enumerator values "
                 "for %qT", enumtype);
          precision = TYPE_PRECISION (long_long_integer_type_node);
          underlying_type = integer_types[itk_unsigned_long_long];
        }

      /* [dcl.enum]

         The value of sizeof() applied to an enumeration type, an object
         of an enumeration type, or an enumerator, is the value of sizeof()
         applied to the underlying type.  */
      copy_type_enum (enumtype, underlying_type);

      /* Compute the minimum and maximum values for the type.

	 [dcl.enum]

	 For an enumeration where emin is the smallest enumerator and emax
	 is the largest, the values of the enumeration are the values of the
	 underlying type in the range bmin to bmax, where bmin and bmax are,
	 respectively, the smallest and largest values of the smallest bit-
	 field that can store emin and emax.  */

      /* The middle-end currently assumes that types with TYPE_PRECISION
	 narrower than their underlying type are suitably zero or sign
	 extended to fill their mode.  Similarly, it assumes that the front
	 end assures that a value of a particular type must be within
	 TYPE_MIN_VALUE and TYPE_MAX_VALUE.

	 We used to set these fields based on bmin and bmax, but that led
	 to invalid assumptions like optimizing away bounds checking.  So
	 now we just set the TYPE_PRECISION, TYPE_MIN_VALUE, and
	 TYPE_MAX_VALUE to the values for the mode above and only restrict
	 the ENUM_UNDERLYING_TYPE for the benefit of diagnostics.  */
      ENUM_UNDERLYING_TYPE (enumtype)
	= build_distinct_type_copy (underlying_type);
      TYPE_PRECISION (ENUM_UNDERLYING_TYPE (enumtype)) = precision;
      set_min_and_max_values_for_integral_type
        (ENUM_UNDERLYING_TYPE (enumtype), precision, sgn);

      /* If -fstrict-enums, still constrain TYPE_MIN/MAX_VALUE.  */
      if (flag_strict_enums)
	set_min_and_max_values_for_integral_type (enumtype, precision, sgn);
    }
  else
    underlying_type = ENUM_UNDERLYING_TYPE (enumtype);

  /* Convert each of the enumerators to the type of the underlying
     type of the enumeration.  */
  for (values = TYPE_VALUES (enumtype); values; values = TREE_CHAIN (values))
    {
      location_t saved_location;

      decl = TREE_VALUE (values);
      saved_location = input_location;
      input_location = DECL_SOURCE_LOCATION (decl);
      if (fixed_underlying_type_p)
        /* If the enumeration type has a fixed underlying type, we
           already checked all of the enumerator values.  */
        value = DECL_INITIAL (decl);
      else
        value = perform_implicit_conversion (underlying_type,
                                             DECL_INITIAL (decl),
                                             tf_warning_or_error);
      input_location = saved_location;

      /* Do not clobber shared ints.  */
      if (value != error_mark_node)
	{
	  value = copy_node (value);

	  TREE_TYPE (value) = enumtype;
	}
      DECL_INITIAL (decl) = value;
    }

  /* Fix up all variant types of this enum type.  */
  for (t = TYPE_MAIN_VARIANT (enumtype); t; t = TYPE_NEXT_VARIANT (t))
    TYPE_VALUES (t) = TYPE_VALUES (enumtype);

  if (at_class_scope_p ()
      && COMPLETE_TYPE_P (current_class_type)
      && UNSCOPED_ENUM_P (enumtype))
    {
      insert_late_enum_def_bindings (current_class_type, enumtype);
      /* TYPE_FIELDS needs fixup.  */
      fixup_type_variants (current_class_type);
    }

  /* Finish debugging output for this type.  */
  rest_of_type_compilation (enumtype, namespace_bindings_p ());

  /* Each enumerator now has the type of its enumeration.  Clear the cache
     so that this change in types doesn't confuse us later on.  */
  clear_cv_and_fold_caches ();
}

/* Finishes the enum type. This is called only the first time an
   enumeration is seen, be it opaque or odinary.
   ENUMTYPE is the type object.  */

void
finish_enum (tree enumtype)
{
  if (processing_template_decl)
    {
      if (at_function_scope_p ())
	add_stmt (build_min (TAG_DEFN, enumtype));
      return;
    }

  /* If this is a forward declaration, there should not be any variants,
     though we can get a variant in the middle of an enum-specifier with
     wacky code like 'enum E { e = sizeof(const E*) };'  */
  gcc_assert (enumtype == TYPE_MAIN_VARIANT (enumtype)
	      && (TYPE_VALUES (enumtype)
		  || !TYPE_NEXT_VARIANT (enumtype)));
}

/* Build and install a CONST_DECL for an enumeration constant of the
   enumeration type ENUMTYPE whose NAME and VALUE (if any) are provided.
   Apply ATTRIBUTES if available.  LOC is the location of NAME.
   Assignment of sequential values by default is handled here.  */

void
build_enumerator (tree name, tree value, tree enumtype, tree attributes,
		  location_t loc)
{
  tree decl;
  tree context;
  tree type;

  /* scalar_constant_value will pull out this expression, so make sure
     it's folded as appropriate.  */
  if (processing_template_decl)
    value = fold_non_dependent_expr (value);

  /* If the VALUE was erroneous, pretend it wasn't there; that will
     result in the enum being assigned the next value in sequence.  */
  if (value == error_mark_node)
    value = NULL_TREE;

  /* Remove no-op casts from the value.  */
  if (value)
    STRIP_TYPE_NOPS (value);

  if (! processing_template_decl)
    {
      /* Validate and default VALUE.  */
      if (value != NULL_TREE)
	{
	  if (!ENUM_UNDERLYING_TYPE (enumtype))
	    {
	      tree tmp_value = build_expr_type_conversion (WANT_INT | WANT_ENUM,
							   value, true);
	      if (tmp_value)
		value = tmp_value;
	    }
	  else if (! INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P
		   (TREE_TYPE (value)))
	    value = perform_implicit_conversion_flags
	      (ENUM_UNDERLYING_TYPE (enumtype), value, tf_warning_or_error,
	       LOOKUP_IMPLICIT | LOOKUP_NO_NARROWING);

	  if (value == error_mark_node)
	    value = NULL_TREE;

	  if (value != NULL_TREE)
	    {
	      if (! INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P
		  (TREE_TYPE (value)))
		{
		  error ("enumerator value for %qD must have integral or "
			 "unscoped enumeration type", name);
		  value = NULL_TREE;
		}
	      else
		{
		  value = cxx_constant_value (value);

		  if (TREE_CODE (value) != INTEGER_CST)
		    {
		      error ("enumerator value for %qD is not an integer "
			     "constant", name);
		      value = NULL_TREE;
		    }
		}
	    }
	}

      /* Default based on previous value.  */
      if (value == NULL_TREE)
	{
	  if (TYPE_VALUES (enumtype))
	    {
	      tree prev_value;

	      /* C++03 7.2/4: If no initializer is specified for the first
		 enumerator, the type is an unspecified integral
		 type. Otherwise the type is the same as the type of the
		 initializing value of the preceding enumerator unless the
		 incremented value is not representable in that type, in
		 which case the type is an unspecified integral type
		 sufficient to contain the incremented value.  */
	      prev_value = DECL_INITIAL (TREE_VALUE (TYPE_VALUES (enumtype)));
	      if (error_operand_p (prev_value))
		value = error_mark_node;
	      else
		{
		  wi::overflow_type overflowed;
		  tree type = TREE_TYPE (prev_value);
		  signop sgn = TYPE_SIGN (type);
		  widest_int wi = wi::add (wi::to_widest (prev_value), 1, sgn,
					   &overflowed);
		  if (!overflowed)
		    {
		      bool pos = !wi::neg_p (wi, sgn);
		      if (!wi::fits_to_tree_p (wi, type))
			{
			  unsigned int itk;
			  for (itk = itk_int; itk != itk_none; itk++)
			    {
			      type = integer_types[itk];
			      if (type != NULL_TREE
				  && (pos || !TYPE_UNSIGNED (type))
				  && wi::fits_to_tree_p (wi, type))
				break;
			    }
			  if (type && cxx_dialect < cxx11
			      && itk > itk_unsigned_long)
			    pedwarn (input_location, OPT_Wlong_long,
				     pos ? G_("\
incremented enumerator value is too large for %<unsigned long%>") : G_("\
incremented enumerator value is too large for %<long%>"));
			}
		      if (type == NULL_TREE)
		        overflowed = wi::OVF_UNKNOWN;
		      else
			value = wide_int_to_tree (type, wi);
		    }

		  if (overflowed)
		    {
		      error ("overflow in enumeration values at %qD", name);
		      value = error_mark_node;
		    }
		}
	    }
	  else
	    value = integer_zero_node;
	}

      /* Remove no-op casts from the value.  */
      STRIP_TYPE_NOPS (value);

      /* If the underlying type of the enum is fixed, check whether
         the enumerator values fits in the underlying type.  If it
         does not fit, the program is ill-formed [C++0x dcl.enum].  */
      if (ENUM_UNDERLYING_TYPE (enumtype)
          && value
          && TREE_CODE (value) == INTEGER_CST)
        {
	  if (!int_fits_type_p (value, ENUM_UNDERLYING_TYPE (enumtype)))
	    error ("enumerator value %qE is outside the range of underlying "
		   "type %qT", value, ENUM_UNDERLYING_TYPE (enumtype));

          /* Convert the value to the appropriate type.  */
          value = fold_convert (ENUM_UNDERLYING_TYPE (enumtype), value);
        }
    }

  /* C++ associates enums with global, function, or class declarations.  */
  context = current_scope ();

  /* Build the actual enumeration constant.  Note that the enumeration
     constants have the underlying type of the enum (if it is fixed)
     or the type of their initializer (if the underlying type of the
     enum is not fixed):

      [ C++0x dcl.enum ]

        If the underlying type is fixed, the type of each enumerator
        prior to the closing brace is the underlying type; if the
        initializing value of an enumerator cannot be represented by
        the underlying type, the program is ill-formed. If the
        underlying type is not fixed, the type of each enumerator is
        the type of its initializing value.

    If the underlying type is not fixed, it will be computed by
    finish_enum and we will reset the type of this enumerator.  Of
    course, if we're processing a template, there may be no value.  */
  type = value ? TREE_TYPE (value) : NULL_TREE;

  decl = build_decl (loc, CONST_DECL, name, type);
  
  DECL_CONTEXT (decl) = enumtype;
  TREE_CONSTANT (decl) = 1;
  TREE_READONLY (decl) = 1;
  DECL_INITIAL (decl) = value;

  if (attributes)
    cplus_decl_attributes (&decl, attributes, 0);

  if (context && context == current_class_type && !SCOPED_ENUM_P (enumtype))
    {
      /* In something like `struct S { enum E { i = 7 }; };' we put `i'
	 on the TYPE_FIELDS list for `S'.  (That's so that you can say
	 things like `S::i' later.)  */

      /* The enumerator may be getting declared outside of its enclosing
	 class, like so:

	   class S { public: enum E : int; }; enum S::E : int { i = 7; };

	 For which case we need to make sure that the access of `S::i'
	 matches the access of `S::E'.  */
      tree saved_cas = current_access_specifier;
      if (TREE_PRIVATE (TYPE_NAME (enumtype)))
	current_access_specifier = access_private_node;
      else if (TREE_PROTECTED (TYPE_NAME (enumtype)))
	current_access_specifier = access_protected_node;
      else
	current_access_specifier = access_public_node;

      finish_member_declaration (decl);

      current_access_specifier = saved_cas;
    }
  else
    pushdecl (decl);

  /* Add this enumeration constant to the list for this type.  */
  TYPE_VALUES (enumtype) = tree_cons (name, decl, TYPE_VALUES (enumtype));
}

/* Look for an enumerator with the given NAME within the enumeration
   type ENUMTYPE.  This routine is used primarily for qualified name
   lookup into an enumerator in C++0x, e.g.,

     enum class Color { Red, Green, Blue };

     Color color = Color::Red;

   Returns the value corresponding to the enumerator, or
   NULL_TREE if no such enumerator was found.  */
tree
lookup_enumerator (tree enumtype, tree name)
{
  tree e;
  gcc_assert (enumtype && TREE_CODE (enumtype) == ENUMERAL_TYPE);

  e = purpose_member (name, TYPE_VALUES (enumtype));
  return e? TREE_VALUE (e) : NULL_TREE;
}


/* We're defining DECL.  Make sure that its type is OK.  */

static void
check_function_type (tree decl, tree current_function_parms)
{
  tree fntype = TREE_TYPE (decl);
  tree return_type = complete_type (TREE_TYPE (fntype));

  /* In a function definition, arg types must be complete.  */
  require_complete_types_for_parms (current_function_parms);

  if (dependent_type_p (return_type)
      || type_uses_auto (return_type))
    return;
  if (!COMPLETE_OR_VOID_TYPE_P (return_type))
    {
      tree args = TYPE_ARG_TYPES (fntype);

      error ("return type %q#T is incomplete", return_type);

      /* Make it return void instead.  */
      if (TREE_CODE (fntype) == METHOD_TYPE)
	fntype = build_method_type_directly (TREE_TYPE (TREE_VALUE (args)),
					     void_type_node,
					     TREE_CHAIN (args));
      else
	fntype = build_function_type (void_type_node, args);
      fntype = (cp_build_type_attribute_variant
		(fntype, TYPE_ATTRIBUTES (TREE_TYPE (decl))));
      fntype = cxx_copy_lang_qualifiers (fntype, TREE_TYPE (decl));
      TREE_TYPE (decl) = fntype;
    }
  else
    {
      abstract_virtuals_error (decl, TREE_TYPE (fntype));
      maybe_warn_parm_abi (TREE_TYPE (fntype),
			   DECL_SOURCE_LOCATION (decl));
    }
}

/* True iff FN is an implicitly-defined default constructor.  */

static bool
implicit_default_ctor_p (tree fn)
{
  return (DECL_CONSTRUCTOR_P (fn)
	  && !user_provided_p (fn)
	  && sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
}

/* Clobber the contents of *this to let the back end know that the object
   storage is dead when we enter the constructor or leave the destructor.  */

static tree
build_clobber_this ()
{
  /* Clobbering an empty base is pointless, and harmful if its one byte
     TYPE_SIZE overlays real data.  */
  if (is_empty_class (current_class_type))
    return void_node;

  /* If we have virtual bases, clobber the whole object, but only if we're in
     charge.  If we don't have virtual bases, clobber the as-base type so we
     don't mess with tail padding.  */
  bool vbases = CLASSTYPE_VBASECLASSES (current_class_type);

  tree ctype = current_class_type;
  if (!vbases)
    ctype = CLASSTYPE_AS_BASE (ctype);

  tree clobber = build_clobber (ctype);

  tree thisref = current_class_ref;
  if (ctype != current_class_type)
    {
      thisref = build_nop (build_reference_type (ctype), current_class_ptr);
      thisref = convert_from_reference (thisref);
    }

  tree exprstmt = build2 (MODIFY_EXPR, void_type_node, thisref, clobber);
  if (vbases)
    exprstmt = build_if_in_charge (exprstmt);

  return exprstmt;
}

/* Create the FUNCTION_DECL for a function definition.
   DECLSPECS and DECLARATOR are the parts of the declaration;
   they describe the function's name and the type it returns,
   but twisted together in a fashion that parallels the syntax of C.

   FLAGS is a bitwise or of SF_PRE_PARSED (indicating that the
   DECLARATOR is really the DECL for the function we are about to
   process and that DECLSPECS should be ignored), SF_INCLASS_INLINE
   indicating that the function is an inline defined in-class.

   This function creates a binding context for the function body
   as well as setting up the FUNCTION_DECL in current_function_decl.

   For C++, we must first check whether that datum makes any sense.
   For example, "class A local_a(1,2);" means that variable local_a
   is an aggregate of type A, which should have a constructor
   applied to it with the argument list [1, 2].

   On entry, DECL_INITIAL (decl1) should be NULL_TREE or error_mark_node,
   or may be a BLOCK if the function has been defined previously
   in this translation unit.  On exit, DECL_INITIAL (decl1) will be
   error_mark_node if the function has never been defined, or
   a BLOCK if the function has been defined somewhere.  */

bool
start_preparsed_function (tree decl1, tree attrs, int flags)
{
  tree ctype = NULL_TREE;
  tree fntype;
  tree restype;
  int doing_friend = 0;
  cp_binding_level *bl;
  tree current_function_parms;
  struct c_fileinfo *finfo
    = get_fileinfo (LOCATION_FILE (DECL_SOURCE_LOCATION (decl1)));
  bool honor_interface;

  /* Sanity check.  */
  gcc_assert (VOID_TYPE_P (TREE_VALUE (void_list_node)));
  gcc_assert (TREE_CHAIN (void_list_node) == NULL_TREE);

  fntype = TREE_TYPE (decl1);
  if (TREE_CODE (fntype) == METHOD_TYPE)
    ctype = TYPE_METHOD_BASETYPE (fntype);

  /* ISO C++ 11.4/5.  A friend function defined in a class is in
     the (lexical) scope of the class in which it is defined.  */
  if (!ctype && DECL_FRIEND_P (decl1))
    {
      ctype = DECL_FRIEND_CONTEXT (decl1);

      /* CTYPE could be null here if we're dealing with a template;
	 for example, `inline friend float foo()' inside a template
	 will have no CTYPE set.  */
      if (ctype && TREE_CODE (ctype) != RECORD_TYPE)
	ctype = NULL_TREE;
      else
	doing_friend = 1;
    }

  if (DECL_DECLARED_INLINE_P (decl1)
      && lookup_attribute ("noinline", attrs))
    warning_at (DECL_SOURCE_LOCATION (decl1), 0,
		"inline function %qD given attribute noinline", decl1);

  /* Handle gnu_inline attribute.  */
  if (GNU_INLINE_P (decl1))
    {
      DECL_EXTERNAL (decl1) = 1;
      DECL_NOT_REALLY_EXTERN (decl1) = 0;
      DECL_INTERFACE_KNOWN (decl1) = 1;
      DECL_DISREGARD_INLINE_LIMITS (decl1) = 1;
    }

  if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
    /* This is a constructor, we must ensure that any default args
       introduced by this definition are propagated to the clones
       now. The clones are used directly in overload resolution.  */
    adjust_clone_args (decl1);

  /* Sometimes we don't notice that a function is a static member, and
     build a METHOD_TYPE for it.  Fix that up now.  */
  gcc_assert (!(ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
		&& TREE_CODE (TREE_TYPE (decl1)) == METHOD_TYPE));

  /* Set up current_class_type, and enter the scope of the class, if
     appropriate.  */
  if (ctype)
    push_nested_class (ctype);
  else if (DECL_STATIC_FUNCTION_P (decl1))
    push_nested_class (DECL_CONTEXT (decl1));

  /* Now that we have entered the scope of the class, we must restore
     the bindings for any template parameters surrounding DECL1, if it
     is an inline member template.  (Order is important; consider the
     case where a template parameter has the same name as a field of
     the class.)  It is not until after this point that
     PROCESSING_TEMPLATE_DECL is guaranteed to be set up correctly.  */
  if (flags & SF_INCLASS_INLINE)
    maybe_begin_member_template_processing (decl1);

  /* Effective C++ rule 15.  */
  if (warn_ecpp
      && DECL_ASSIGNMENT_OPERATOR_P (decl1)
      && DECL_OVERLOADED_OPERATOR_IS (decl1, NOP_EXPR)
      && VOID_TYPE_P (TREE_TYPE (fntype)))
    warning (OPT_Weffc__,
	     "%<operator=%> should return a reference to %<*this%>");

  /* Make the init_value nonzero so pushdecl knows this is not tentative.
     error_mark_node is replaced below (in poplevel) with the BLOCK.  */
  if (!DECL_INITIAL (decl1))
    DECL_INITIAL (decl1) = error_mark_node;

  /* This function exists in static storage.
     (This does not mean `static' in the C sense!)  */
  TREE_STATIC (decl1) = 1;

  /* We must call push_template_decl after current_class_type is set
     up.  (If we are processing inline definitions after exiting a
     class scope, current_class_type will be NULL_TREE until set above
     by push_nested_class.)  */
  if (processing_template_decl)
    {
      tree newdecl1 = push_template_decl (decl1);
      if (newdecl1 == error_mark_node)
	{
	  if (ctype || DECL_STATIC_FUNCTION_P (decl1))
	    pop_nested_class ();
	  return false;
	}
      decl1 = newdecl1;
    }

  /* Make sure the parameter and return types are reasonable.  When
     you declare a function, these types can be incomplete, but they
     must be complete when you define the function.  */
  check_function_type (decl1, DECL_ARGUMENTS (decl1));

  /* Build the return declaration for the function.  */
  restype = TREE_TYPE (fntype);

  if (DECL_RESULT (decl1) == NULL_TREE)
    {
      tree resdecl;

      resdecl = build_decl (input_location, RESULT_DECL, 0, restype);
      DECL_ARTIFICIAL (resdecl) = 1;
      DECL_IGNORED_P (resdecl) = 1;
      DECL_RESULT (decl1) = resdecl;

      cp_apply_type_quals_to_decl (cp_type_quals (restype), resdecl);
    }

  /* Record the decl so that the function name is defined.
     If we already have a decl for this name, and it is a FUNCTION_DECL,
     use the old decl.  */
  if (!processing_template_decl && !(flags & SF_PRE_PARSED))
    {
      /* A specialization is not used to guide overload resolution.  */
      if (!DECL_FUNCTION_MEMBER_P (decl1)
	  && !(DECL_USE_TEMPLATE (decl1) &&
	       PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl1))))
	{
	  tree olddecl = pushdecl (decl1);

	  if (olddecl == error_mark_node)
	    /* If something went wrong when registering the declaration,
	       use DECL1; we have to have a FUNCTION_DECL to use when
	       parsing the body of the function.  */
	    ;
	  else
	    {
	      /* Otherwise, OLDDECL is either a previous declaration
		 of the same function or DECL1 itself.  */

	      if (warn_missing_declarations
		  && olddecl == decl1
		  && !DECL_MAIN_P (decl1)
		  && TREE_PUBLIC (decl1)
		  && !DECL_DECLARED_INLINE_P (decl1))
		{
		  tree context;

		  /* Check whether DECL1 is in an anonymous
		     namespace.  */
		  for (context = DECL_CONTEXT (decl1);
		       context;
		       context = DECL_CONTEXT (context))
		    {
		      if (TREE_CODE (context) == NAMESPACE_DECL
			  && DECL_NAME (context) == NULL_TREE)
			break;
		    }

		  if (context == NULL)
		    warning_at (DECL_SOURCE_LOCATION (decl1),
				OPT_Wmissing_declarations,
				"no previous declaration for %qD", decl1);
		}

	      decl1 = olddecl;
	    }
	}
      else
	{
	  /* We need to set the DECL_CONTEXT.  */
	  if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1))
	    DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1));
	}
      fntype = TREE_TYPE (decl1);
      restype = TREE_TYPE (fntype);

      /* If #pragma weak applies, mark the decl appropriately now.
	 The pragma only applies to global functions.  Because
	 determining whether or not the #pragma applies involves
	 computing the mangled name for the declaration, we cannot
	 apply the pragma until after we have merged this declaration
	 with any previous declarations; if the original declaration
	 has a linkage specification, that specification applies to
	 the definition as well, and may affect the mangled name.  */
      if (DECL_FILE_SCOPE_P (decl1))
	maybe_apply_pragma_weak (decl1);
    }

  /* We are now in the scope of the function being defined.  */
  current_function_decl = decl1;

  /* Save the parm names or decls from this function's declarator
     where store_parm_decls will find them.  */
  current_function_parms = DECL_ARGUMENTS (decl1);

  /* Let the user know we're compiling this function.  */
  announce_function (decl1);

  gcc_assert (DECL_INITIAL (decl1));

  /* This function may already have been parsed, in which case just
     return; our caller will skip over the body without parsing.  */
  if (DECL_INITIAL (decl1) != error_mark_node)
    return true;

  /* Initialize RTL machinery.  We cannot do this until
     CURRENT_FUNCTION_DECL and DECL_RESULT are set up.  We do this
     even when processing a template; this is how we get
     CFUN set up, and our per-function variables initialized.
     FIXME factor out the non-RTL stuff.  */
  bl = current_binding_level;
  allocate_struct_function (decl1, processing_template_decl);

  /* Initialize the language data structures.  Whenever we start
     a new function, we destroy temporaries in the usual way.  */
  cfun->language = ggc_cleared_alloc<language_function> ();
  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
  current_binding_level = bl;

  if (!processing_template_decl && type_uses_auto (restype))
    {
      FNDECL_USED_AUTO (decl1) = true;
      current_function_auto_return_pattern = restype;
    }

  /* Start the statement-tree, start the tree now.  */
  DECL_SAVED_TREE (decl1) = push_stmt_list ();

  /* If we are (erroneously) defining a function that we have already
     defined before, wipe out what we knew before.  */
  if (!DECL_PENDING_INLINE_P (decl1))
    DECL_SAVED_FUNCTION_DATA (decl1) = NULL;

  if (ctype && !doing_friend && !DECL_STATIC_FUNCTION_P (decl1))
    {
      /* We know that this was set up by `grokclassfn'.  We do not
	 wait until `store_parm_decls', since evil parse errors may
	 never get us to that point.  Here we keep the consistency
	 between `current_class_type' and `current_class_ptr'.  */
      tree t = DECL_ARGUMENTS (decl1);

      gcc_assert (t != NULL_TREE && TREE_CODE (t) == PARM_DECL);
      gcc_assert (TYPE_PTR_P (TREE_TYPE (t)));

      cp_function_chain->x_current_class_ref
	= cp_build_fold_indirect_ref (t);
      /* Set this second to avoid shortcut in cp_build_indirect_ref.  */
      cp_function_chain->x_current_class_ptr = t;

      /* Constructors and destructors need to know whether they're "in
	 charge" of initializing virtual base classes.  */
      t = DECL_CHAIN (t);
      if (DECL_HAS_IN_CHARGE_PARM_P (decl1))
	{
	  current_in_charge_parm = t;
	  t = DECL_CHAIN (t);
	}
      if (DECL_HAS_VTT_PARM_P (decl1))
	{
	  gcc_assert (DECL_NAME (t) == vtt_parm_identifier);
	  current_vtt_parm = t;
	}
    }

  honor_interface = (!DECL_TEMPLATE_INSTANTIATION (decl1)
		     /* Implicitly-defined methods (like the
			destructor for a class in which no destructor
			is explicitly declared) must not be defined
			until their definition is needed.  So, we
			ignore interface specifications for
			compiler-generated functions.  */
		     && !DECL_ARTIFICIAL (decl1));

  if (processing_template_decl)
    /* Don't mess with interface flags.  */;
  else if (DECL_INTERFACE_KNOWN (decl1))
    {
      tree ctx = decl_function_context (decl1);

      if (DECL_NOT_REALLY_EXTERN (decl1))
	DECL_EXTERNAL (decl1) = 0;

      if (ctx != NULL_TREE && vague_linkage_p (ctx))
	/* This is a function in a local class in an extern inline
	   or template function.  */
	comdat_linkage (decl1);
    }
  /* If this function belongs to an interface, it is public.
     If it belongs to someone else's interface, it is also external.
     This only affects inlines and template instantiations.  */
  else if (!finfo->interface_unknown && honor_interface)
    {
      if (DECL_DECLARED_INLINE_P (decl1)
	  || DECL_TEMPLATE_INSTANTIATION (decl1))
	{
	  DECL_EXTERNAL (decl1)
	    = (finfo->interface_only
	       || (DECL_DECLARED_INLINE_P (decl1)
		   && ! flag_implement_inlines
		   && !DECL_VINDEX (decl1)));

	  /* For WIN32 we also want to put these in linkonce sections.  */
	  maybe_make_one_only (decl1);
	}
      else
	DECL_EXTERNAL (decl1) = 0;
      DECL_INTERFACE_KNOWN (decl1) = 1;
      /* If this function is in an interface implemented in this file,
	 make sure that the back end knows to emit this function
	 here.  */
      if (!DECL_EXTERNAL (decl1))
	mark_needed (decl1);
    }
  else if (finfo->interface_unknown && finfo->interface_only
	   && honor_interface)
    {
      /* If MULTIPLE_SYMBOL_SPACES is defined and we saw a #pragma
	 interface, we will have both finfo->interface_unknown and
	 finfo->interface_only set.  In that case, we don't want to
	 use the normal heuristics because someone will supply a
	 #pragma implementation elsewhere, and deducing it here would
	 produce a conflict.  */
      comdat_linkage (decl1);
      DECL_EXTERNAL (decl1) = 0;
      DECL_INTERFACE_KNOWN (decl1) = 1;
      DECL_DEFER_OUTPUT (decl1) = 1;
    }
  else
    {
      /* This is a definition, not a reference.
	 So clear DECL_EXTERNAL, unless this is a GNU extern inline.  */
      if (!GNU_INLINE_P (decl1))
	DECL_EXTERNAL (decl1) = 0;

      if ((DECL_DECLARED_INLINE_P (decl1)
	   || DECL_TEMPLATE_INSTANTIATION (decl1))
	  && ! DECL_INTERFACE_KNOWN (decl1))
	DECL_DEFER_OUTPUT (decl1) = 1;
      else
	DECL_INTERFACE_KNOWN (decl1) = 1;
    }

  /* Determine the ELF visibility attribute for the function.  We must not
     do this before calling "pushdecl", as we must allow "duplicate_decls"
     to merge any attributes appropriately.  We also need to wait until
     linkage is set.  */
  if (!DECL_CLONED_FUNCTION_P (decl1))
    determine_visibility (decl1);

  if (!processing_template_decl)
    maybe_instantiate_noexcept (decl1);

  begin_scope (sk_function_parms, decl1);

  ++function_depth;

  if (DECL_DESTRUCTOR_P (decl1)
      || (DECL_CONSTRUCTOR_P (decl1)
	  && targetm.cxx.cdtor_returns_this ()))
    {
      cdtor_label = create_artificial_label (input_location);
      LABEL_DECL_CDTOR (cdtor_label) = true;
    }

  start_fname_decls ();

  store_parm_decls (current_function_parms);

  if (!processing_template_decl
      && (flag_lifetime_dse > 1)
      && DECL_CONSTRUCTOR_P (decl1)
      && !DECL_CLONED_FUNCTION_P (decl1)
      /* Clobbering an empty base is harmful if it overlays real data.  */
      && !is_empty_class (current_class_type)
      /* We can't clobber safely for an implicitly-defined default constructor
	 because part of the initialization might happen before we enter the
	 constructor, via AGGR_INIT_ZERO_FIRST (c++/68006).  */
      && !implicit_default_ctor_p (decl1))
    finish_expr_stmt (build_clobber_this ());

  if (!processing_template_decl
      && DECL_CONSTRUCTOR_P (decl1)
      && sanitize_flags_p (SANITIZE_VPTR)
      && !DECL_CLONED_FUNCTION_P (decl1)
      && !implicit_default_ctor_p (decl1))
    cp_ubsan_maybe_initialize_vtbl_ptrs (current_class_ptr);

  start_lambda_scope (decl1);

  return true;
}


/* Like start_preparsed_function, except that instead of a
   FUNCTION_DECL, this function takes DECLSPECS and DECLARATOR.

   Returns true on success.  If the DECLARATOR is not suitable
   for a function, we return false, which tells the parser to
   skip the entire function.  */

bool
start_function (cp_decl_specifier_seq *declspecs,
		const cp_declarator *declarator,
		tree attrs)
{
  tree decl1;

  decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, &attrs);
  invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
  if (decl1 == error_mark_node)
    return false;
  /* If the declarator is not suitable for a function definition,
     cause a syntax error.  */
  if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
    {
      error ("invalid function declaration");
      return false;
    }

  if (DECL_MAIN_P (decl1))
    /* main must return int.  grokfndecl should have corrected it
       (and issued a diagnostic) if the user got it wrong.  */
    gcc_assert (same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
			     integer_type_node));

  return start_preparsed_function (decl1, attrs, /*flags=*/SF_DEFAULT);
}

/* Returns true iff an EH_SPEC_BLOCK should be created in the body of
   FN.  */

static bool
use_eh_spec_block (tree fn)
{
  return (flag_exceptions && flag_enforce_eh_specs
	  && !processing_template_decl
	  && !type_throw_all_p (TREE_TYPE (fn))
	  /* We insert the EH_SPEC_BLOCK only in the original
	     function; then, it is copied automatically to the
	     clones.  */
	  && !DECL_CLONED_FUNCTION_P (fn)
	  /* Implicitly-generated constructors and destructors have
	     exception specifications.  However, those specifications
	     are the union of the possible exceptions specified by the
	     constructors/destructors for bases and members, so no
	     unallowed exception will ever reach this function.  By
	     not creating the EH_SPEC_BLOCK we save a little memory,
	     and we avoid spurious warnings about unreachable
	     code.  */
	  && !DECL_DEFAULTED_FN (fn));
}

/* Store the parameter declarations into the current function declaration.
   This is called after parsing the parameter declarations, before
   digesting the body of the function.

   Also install to binding contour return value identifier, if any.  */

static void
store_parm_decls (tree current_function_parms)
{
  tree fndecl = current_function_decl;
  tree parm;

  /* This is a chain of any other decls that came in among the parm
     declarations.  If a parm is declared with  enum {foo, bar} x;
     then CONST_DECLs for foo and bar are put here.  */
  tree nonparms = NULL_TREE;

  if (current_function_parms)
    {
      /* This case is when the function was defined with an ANSI prototype.
	 The parms already have decls, so we need not do anything here
	 except record them as in effect
	 and complain if any redundant old-style parm decls were written.  */

      tree specparms = current_function_parms;
      tree next;

      /* Must clear this because it might contain TYPE_DECLs declared
	     at class level.  */
      current_binding_level->names = NULL;

      /* If we're doing semantic analysis, then we'll call pushdecl
	     for each of these.  We must do them in reverse order so that
	     they end in the correct forward order.  */
      specparms = nreverse (specparms);

      for (parm = specparms; parm; parm = next)
	{
	  next = DECL_CHAIN (parm);
	  if (TREE_CODE (parm) == PARM_DECL)
	    pushdecl (parm);
	  else
	    {
	      /* If we find an enum constant or a type tag,
		 put it aside for the moment.  */
	      TREE_CHAIN (parm) = NULL_TREE;
	      nonparms = chainon (nonparms, parm);
	    }
	}

      /* Get the decls in their original chain order and record in the
	 function.  This is all and only the PARM_DECLs that were
	 pushed into scope by the loop above.  */
      DECL_ARGUMENTS (fndecl) = get_local_decls ();
    }
  else
    DECL_ARGUMENTS (fndecl) = NULL_TREE;

  /* Now store the final chain of decls for the arguments
     as the decl-chain of the current lexical scope.
     Put the enumerators in as well, at the front so that
     DECL_ARGUMENTS is not modified.  */
  current_binding_level->names = chainon (nonparms, DECL_ARGUMENTS (fndecl));

  if (use_eh_spec_block (current_function_decl))
    current_eh_spec_block = begin_eh_spec_block ();
}


/* We have finished doing semantic analysis on DECL, but have not yet
   generated RTL for its body.  Save away our current state, so that
   when we want to generate RTL later we know what to do.  */

static void
save_function_data (tree decl)
{
  struct language_function *f;

  /* Save the language-specific per-function data so that we can
     get it back when we really expand this function.  */
  gcc_assert (!DECL_PENDING_INLINE_P (decl));

  /* Make a copy.  */
  f = ggc_alloc<language_function> ();
  memcpy (f, cp_function_chain, sizeof (struct language_function));
  DECL_SAVED_FUNCTION_DATA (decl) = f;

  /* Clear out the bits we don't need.  */
  f->base.x_stmt_tree.x_cur_stmt_list = NULL;
  f->bindings = NULL;
  f->base.local_typedefs = NULL;
}


/* Set the return value of the constructor (if present).  */

static void
finish_constructor_body (void)
{
  tree val;
  tree exprstmt;

  if (targetm.cxx.cdtor_returns_this ())
    {
      /* Any return from a constructor will end up here.  */
      add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));

      val = DECL_ARGUMENTS (current_function_decl);
      val = build2 (MODIFY_EXPR, TREE_TYPE (val),
		    DECL_RESULT (current_function_decl), val);
      /* Return the address of the object.  */
      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
      add_stmt (exprstmt);
    }
}

/* Do all the processing for the beginning of a destructor; set up the
   vtable pointers and cleanups for bases and members.  */

static void
begin_destructor_body (void)
{
  tree compound_stmt;

  /* If the CURRENT_CLASS_TYPE is incomplete, we will have already
     issued an error message.  We still want to try to process the
     body of the function, but initialize_vtbl_ptrs will crash if
     TYPE_BINFO is NULL.  */
  if (COMPLETE_TYPE_P (current_class_type))
    {
      compound_stmt = begin_compound_stmt (0);
      /* Make all virtual function table pointers in non-virtual base
	 classes point to CURRENT_CLASS_TYPE's virtual function
	 tables.  */
      initialize_vtbl_ptrs (current_class_ptr);
      finish_compound_stmt (compound_stmt);

      if (flag_lifetime_dse
	  /* Clobbering an empty base is harmful if it overlays real data.  */
	  && !is_empty_class (current_class_type))
      {
	if (sanitize_flags_p (SANITIZE_VPTR)
	    && (flag_sanitize_recover & SANITIZE_VPTR) == 0
	    && TYPE_CONTAINS_VPTR_P (current_class_type))
	  {
	    tree binfo = TYPE_BINFO (current_class_type);
	    tree ref
	      = cp_build_fold_indirect_ref (current_class_ptr);

	    tree vtbl_ptr = build_vfield_ref (ref, TREE_TYPE (binfo));
	    tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr));
	    tree stmt = cp_build_modify_expr (input_location, vtbl_ptr,
					      NOP_EXPR, vtbl,
					      tf_warning_or_error);
	    /* If the vptr is shared with some virtual nearly empty base,
	       don't clear it if not in charge, the dtor of the virtual
	       nearly empty base will do that later.  */
	    if (CLASSTYPE_VBASECLASSES (current_class_type)
		&& CLASSTYPE_PRIMARY_BINFO (current_class_type)
		&& BINFO_VIRTUAL_P
			  (CLASSTYPE_PRIMARY_BINFO (current_class_type)))
	      {
		stmt = convert_to_void (stmt, ICV_STATEMENT,
					tf_warning_or_error);
		stmt = build_if_in_charge (stmt);
	      }
	    finish_decl_cleanup (NULL_TREE, stmt);
	  }
	else
	  finish_decl_cleanup (NULL_TREE, build_clobber_this ());
      }

      /* And insert cleanups for our bases and members so that they
	 will be properly destroyed if we throw.  */
      push_base_cleanups ();
    }
}

/* At the end of every destructor we generate code to delete the object if
   necessary.  Do that now.  */

static void
finish_destructor_body (void)
{
  tree exprstmt;

  /* Any return from a destructor will end up here; that way all base
     and member cleanups will be run when the function returns.  */
  add_stmt (build_stmt (input_location, LABEL_EXPR, cdtor_label));

  if (targetm.cxx.cdtor_returns_this ())
    {
      tree val;

      val = DECL_ARGUMENTS (current_function_decl);
      val = build2 (MODIFY_EXPR, TREE_TYPE (val),
		    DECL_RESULT (current_function_decl), val);
      /* Return the address of the object.  */
      exprstmt = build_stmt (input_location, RETURN_EXPR, val);
      add_stmt (exprstmt);
    }
}

/* Do the necessary processing for the beginning of a function body, which
   in this case includes member-initializers, but not the catch clauses of
   a function-try-block.  Currently, this means opening a binding level
   for the member-initializers (in a ctor), member cleanups (in a dtor),
   and capture proxies (in a lambda operator()).  */

tree
begin_function_body (void)
{
  tree stmt;

  if (! FUNCTION_NEEDS_BODY_BLOCK (current_function_decl))
    return NULL_TREE;

  if (processing_template_decl)
    /* Do nothing now.  */;
  else
    /* Always keep the BLOCK node associated with the outermost pair of
       curly braces of a function.  These are needed for correct
       operation of dwarfout.c.  */
    keep_next_level (true);

  stmt = begin_compound_stmt (BCS_FN_BODY);

  if (processing_template_decl)
    /* Do nothing now.  */;
  else if (DECL_DESTRUCTOR_P (current_function_decl))
    begin_destructor_body ();

  return stmt;
}

/* Do the processing for the end of a function body.  Currently, this means
   closing out the cleanups for fully-constructed bases and members, and in
   the case of the destructor, deleting the object if desired.  Again, this
   is only meaningful for [cd]tors, since they are the only functions where
   there is a significant distinction between the main body and any
   function catch clauses.  Handling, say, main() return semantics here
   would be wrong, as flowing off the end of a function catch clause for
   main() would also need to return 0.  */

void
finish_function_body (tree compstmt)
{
  if (compstmt == NULL_TREE)
    return;

  /* Close the block.  */
  finish_compound_stmt (compstmt);

  if (processing_template_decl)
    /* Do nothing now.  */;
  else if (DECL_CONSTRUCTOR_P (current_function_decl))
    finish_constructor_body ();
  else if (DECL_DESTRUCTOR_P (current_function_decl))
    finish_destructor_body ();
}

/* Given a function, returns the BLOCK corresponding to the outermost level
   of curly braces, skipping the artificial block created for constructor
   initializers.  */

tree
outer_curly_brace_block (tree fndecl)
{
  tree block = DECL_INITIAL (fndecl);
  if (BLOCK_OUTER_CURLY_BRACE_P (block))
    return block;
  block = BLOCK_SUBBLOCKS (block);
  if (BLOCK_OUTER_CURLY_BRACE_P (block))
    return block;
  block = BLOCK_SUBBLOCKS (block);
  gcc_assert (BLOCK_OUTER_CURLY_BRACE_P (block));
  return block;
}

/* If FNDECL is a class's key method, add the class to the list of
   keyed classes that should be emitted.  */

static void
record_key_method_defined (tree fndecl)
{
  if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fndecl)
      && DECL_VIRTUAL_P (fndecl)
      && !processing_template_decl)
    {
      tree fnclass = DECL_CONTEXT (fndecl);
      if (fndecl == CLASSTYPE_KEY_METHOD (fnclass))
	vec_safe_push (keyed_classes, fnclass);
    }
}

/* Subroutine of finish_function.
   Save the body of constexpr functions for possible
   future compile time evaluation.  */

static void
maybe_save_function_definition (tree fun)
{
  if (!processing_template_decl
      && DECL_DECLARED_CONSTEXPR_P (fun)
      && !cp_function_chain->invalid_constexpr
      && !DECL_CLONED_FUNCTION_P (fun))
    register_constexpr_fundef (fun, DECL_SAVED_TREE (fun));
}

/* Attempt to add a fix-it hint to RICHLOC suggesting the insertion
   of "return *this;" immediately before its location, using FNDECL's
   first statement (if any) to give the indentation, if appropriate.  */

static void
add_return_star_this_fixit (gcc_rich_location *richloc, tree fndecl)
{
  location_t indent = UNKNOWN_LOCATION;
  tree stmts = expr_first (DECL_SAVED_TREE (fndecl));
  if (stmts)
    indent = EXPR_LOCATION (stmts);
  richloc->add_fixit_insert_formatted ("return *this;",
				       richloc->get_loc (),
				       indent);
}

/* Finish up a function declaration and compile that function
   all the way to assembler language output.  The free the storage
   for the function definition. INLINE_P is TRUE if we just
   finished processing the body of an in-class inline function
   definition.  (This processing will have taken place after the
   class definition is complete.)  */

tree
finish_function (bool inline_p)
{
  tree fndecl = current_function_decl;
  tree fntype, ctype = NULL_TREE;

  /* When we get some parse errors, we can end up without a
     current_function_decl, so cope.  */
  if (fndecl == NULL_TREE)
    return error_mark_node;

  finish_lambda_scope ();

  if (c_dialect_objc ())
    objc_finish_function ();

  record_key_method_defined (fndecl);

  fntype = TREE_TYPE (fndecl);

  /*  TREE_READONLY (fndecl) = 1;
      This caused &foo to be of type ptr-to-const-function
      which then got a warning when stored in a ptr-to-function variable.  */

  gcc_assert (building_stmt_list_p ());
  /* The current function is being defined, so its DECL_INITIAL should
     be set, and unless there's a multiple definition, it should be
     error_mark_node.  */
  gcc_assert (DECL_INITIAL (fndecl) == error_mark_node);

  /* For a cloned function, we've already got all the code we need;
     there's no need to add any extra bits.  */
  if (!DECL_CLONED_FUNCTION_P (fndecl))
    {
      /* Make it so that `main' always returns 0 by default.  */
      if (DECL_MAIN_P (current_function_decl))
	finish_return_stmt (integer_zero_node);

      if (use_eh_spec_block (current_function_decl))
	finish_eh_spec_block (TYPE_RAISES_EXCEPTIONS
			      (TREE_TYPE (current_function_decl)),
			      current_eh_spec_block);
    }

  /* If we're saving up tree structure, tie off the function now.  */
  DECL_SAVED_TREE (fndecl) = pop_stmt_list (DECL_SAVED_TREE (fndecl));

  finish_fname_decls ();

  /* If this function can't throw any exceptions, remember that.  */
  if (!processing_template_decl
      && !cp_function_chain->can_throw
      && !flag_non_call_exceptions
      && !decl_replaceable_p (fndecl))
    TREE_NOTHROW (fndecl) = 1;

  /* This must come after expand_function_end because cleanups might
     have declarations (from inline functions) that need to go into
     this function's blocks.  */

  /* If the current binding level isn't the outermost binding level
     for this function, either there is a bug, or we have experienced
     syntax errors and the statement tree is malformed.  */
  if (current_binding_level->kind != sk_function_parms)
    {
      /* Make sure we have already experienced errors.  */
      gcc_assert (errorcount);

      /* Throw away the broken statement tree and extra binding
	 levels.  */
      DECL_SAVED_TREE (fndecl) = alloc_stmt_list ();

      while (current_binding_level->kind != sk_function_parms)
	{
	  if (current_binding_level->kind == sk_class)
	    pop_nested_class ();
	  else
	    poplevel (0, 0, 0);
	}
    }
  poplevel (1, 0, 1);

  /* Statements should always be full-expressions at the outermost set
     of curly braces for a function.  */
  gcc_assert (stmts_are_full_exprs_p ());

  /* If there are no return statements in a function with auto return type,
     the return type is void.  But if the declared type is something like
     auto*, this is an error.  */
  if (!processing_template_decl && FNDECL_USED_AUTO (fndecl)
      && TREE_TYPE (fntype) == current_function_auto_return_pattern)
    {
      if (is_auto (current_function_auto_return_pattern))
	{
	  apply_deduced_return_type (fndecl, void_type_node);
	  fntype = TREE_TYPE (fndecl);
	}
      else if (!current_function_returns_value
	       && !current_function_returns_null)
	{
	  error ("no return statements in function returning %qT",
		 current_function_auto_return_pattern);
	  inform (input_location, "only plain %<auto%> return type can be "
		  "deduced to %<void%>");
	}
    }

  // If this is a concept, check that the definition is reasonable.
  if (DECL_DECLARED_CONCEPT_P (fndecl))
    check_function_concept (fndecl);

  /* Lambda closure members are implicitly constexpr if possible.  */
  if (cxx_dialect >= cxx17
      && LAMBDA_TYPE_P (CP_DECL_CONTEXT (fndecl)))
    DECL_DECLARED_CONSTEXPR_P (fndecl)
      = ((processing_template_decl
	  || is_valid_constexpr_fn (fndecl, /*complain*/false))
	 && potential_constant_expression (DECL_SAVED_TREE (fndecl)));

  /* Save constexpr function body before it gets munged by
     the NRV transformation.   */
  maybe_save_function_definition (fndecl);

  /* Invoke the pre-genericize plugin before we start munging things.  */
  if (!processing_template_decl)
    invoke_plugin_callbacks (PLUGIN_PRE_GENERICIZE, fndecl);

  /* Perform delayed folding before NRV transformation.  */
  if (!processing_template_decl)
    cp_fold_function (fndecl);

  /* Set up the named return value optimization, if we can.  Candidate
     variables are selected in check_return_expr.  */
  if (current_function_return_value)
    {
      tree r = current_function_return_value;
      tree outer;

      if (r != error_mark_node
	  /* This is only worth doing for fns that return in memory--and
	     simpler, since we don't have to worry about promoted modes.  */
	  && aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl)), fndecl)
	  /* Only allow this for variables declared in the outer scope of
	     the function so we know that their lifetime always ends with a
	     return; see g++.dg/opt/nrv6.C.  We could be more flexible if
	     we were to do this optimization in tree-ssa.  */
	  && (outer = outer_curly_brace_block (fndecl))
	  && chain_member (r, BLOCK_VARS (outer)))
	finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));

      current_function_return_value = NULL_TREE;
    }

  /* Remember that we were in class scope.  */
  if (current_class_name)
    ctype = current_class_type;

  /* Must mark the RESULT_DECL as being in this function.  */
  DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl;

  /* Set the BLOCK_SUPERCONTEXT of the outermost function scope to point
     to the FUNCTION_DECL node itself.  */
  BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl;

  /* Save away current state, if appropriate.  */
  if (!processing_template_decl)
    save_function_data (fndecl);

  /* Complain if there's just no return statement.  */
  if (warn_return_type
      && !VOID_TYPE_P (TREE_TYPE (fntype))
      && !dependent_type_p (TREE_TYPE (fntype))
      && !current_function_returns_value && !current_function_returns_null
      /* Don't complain if we abort or throw.  */
      && !current_function_returns_abnormally
      /* Don't complain if there's an infinite loop.  */
      && !current_function_infinite_loop
      /* Don't complain if we are declared noreturn.  */
      && !TREE_THIS_VOLATILE (fndecl)
      && !DECL_NAME (DECL_RESULT (fndecl))
      && !TREE_NO_WARNING (fndecl)
      /* Structor return values (if any) are set by the compiler.  */
      && !DECL_CONSTRUCTOR_P (fndecl)
      && !DECL_DESTRUCTOR_P (fndecl)
      && targetm.warn_func_return (fndecl))
    {
      gcc_rich_location richloc (input_location);
      /* Potentially add a "return *this;" fix-it hint for
	 assignment operators.  */
      if (IDENTIFIER_ASSIGN_OP_P (DECL_NAME (fndecl)))
	{
	  tree valtype = TREE_TYPE (DECL_RESULT (fndecl));
	  if (TREE_CODE (valtype) == REFERENCE_TYPE
	      && same_type_ignoring_top_level_qualifiers_p
		  (TREE_TYPE (valtype), TREE_TYPE (current_class_ref)))
	    if (global_dc->option_enabled (OPT_Wreturn_type,
					   global_dc->option_state))
	      add_return_star_this_fixit (&richloc, fndecl);
	}
      warning_at (&richloc, OPT_Wreturn_type,
		  "no return statement in function returning non-void");
      TREE_NO_WARNING (fndecl) = 1;
    }

  /* Store the end of the function, so that we get good line number
     info for the epilogue.  */
  cfun->function_end_locus = input_location;

  /* Complain about parameters that are only set, but never otherwise used.  */
  if (warn_unused_but_set_parameter
      && !processing_template_decl
      && errorcount == unused_but_set_errorcount
      && !DECL_CLONED_FUNCTION_P (fndecl))
    {
      tree decl;

      for (decl = DECL_ARGUMENTS (fndecl);
	   decl;
	   decl = DECL_CHAIN (decl))
	if (TREE_USED (decl)
	    && TREE_CODE (decl) == PARM_DECL
	    && !DECL_READ_P (decl)
	    && DECL_NAME (decl)
	    && !DECL_ARTIFICIAL (decl)
	    && !TREE_NO_WARNING (decl)
	    && !DECL_IN_SYSTEM_HEADER (decl)
	    && TREE_TYPE (decl) != error_mark_node
	    && !TYPE_REF_P (TREE_TYPE (decl))
	    && (!CLASS_TYPE_P (TREE_TYPE (decl))
	        || !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl))))
	  warning_at (DECL_SOURCE_LOCATION (decl),
		      OPT_Wunused_but_set_parameter,
		      "parameter %qD set but not used", decl);
      unused_but_set_errorcount = errorcount;
    }

  /* Complain about locally defined typedefs that are not used in this
     function.  */
  maybe_warn_unused_local_typedefs ();

  /* Possibly warn about unused parameters.  */
  if (warn_unused_parameter
      && !processing_template_decl 
      && !DECL_CLONED_FUNCTION_P (fndecl))
    do_warn_unused_parameter (fndecl);

  /* Genericize before inlining.  */
  if (!processing_template_decl)
    {
      struct language_function *f = DECL_SAVED_FUNCTION_DATA (fndecl);
      cp_genericize (fndecl);
      /* Clear out the bits we don't need.  */
      f->x_current_class_ptr = NULL;
      f->x_current_class_ref = NULL;
      f->x_eh_spec_block = NULL;
      f->x_in_charge_parm = NULL;
      f->x_vtt_parm = NULL;
      f->x_return_value = NULL;
      f->bindings = NULL;
      f->extern_decl_map = NULL;
      f->infinite_loops = NULL;
    }

  /* We're leaving the context of this function, so zap cfun.  It's still in
     DECL_STRUCT_FUNCTION, and we'll restore it in tree_rest_of_compilation.  */
  set_cfun (NULL);
  current_function_decl = NULL;

  /* If this is an in-class inline definition, we may have to pop the
     bindings for the template parameters that we added in
     maybe_begin_member_template_processing when start_function was
     called.  */
  if (inline_p)
    maybe_end_member_template_processing ();

  /* Leave the scope of the class.  */
  if (ctype)
    pop_nested_class ();

  --function_depth;

  /* Clean up.  */
  current_function_decl = NULL_TREE;

  invoke_plugin_callbacks (PLUGIN_FINISH_PARSE_FUNCTION, fndecl);
  return fndecl;
}

/* Create the FUNCTION_DECL for a function definition.
   DECLSPECS and DECLARATOR are the parts of the declaration;
   they describe the return type and the name of the function,
   but twisted together in a fashion that parallels the syntax of C.

   This function creates a binding context for the function body
   as well as setting up the FUNCTION_DECL in current_function_decl.

   Returns a FUNCTION_DECL on success.

   If the DECLARATOR is not suitable for a function (it defines a datum
   instead), we return 0, which tells yyparse to report a parse error.

   May return void_type_node indicating that this method is actually
   a friend.  See grokfield for more details.

   Came here with a `.pushlevel' .

   DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING
   CHANGES TO CODE IN `grokfield'.  */

tree
grokmethod (cp_decl_specifier_seq *declspecs,
	    const cp_declarator *declarator, tree attrlist)
{
  tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0,
				&attrlist);

  if (fndecl == error_mark_node)
    return error_mark_node;

  if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
    {
      error ("invalid member function declaration");
      return error_mark_node;
    }

  if (attrlist)
    cplus_decl_attributes (&fndecl, attrlist, 0);

  /* Pass friends other than inline friend functions back.  */
  if (fndecl == void_type_node)
    return fndecl;

  if (DECL_IN_AGGR_P (fndecl))
    {
      if (DECL_CLASS_SCOPE_P (fndecl))
	error ("%qD is already defined in class %qT", fndecl,
	       DECL_CONTEXT (fndecl));
      return error_mark_node;
    }

  check_template_shadow (fndecl);

  if (TREE_PUBLIC (fndecl))
    DECL_COMDAT (fndecl) = 1;
  DECL_DECLARED_INLINE_P (fndecl) = 1;
  DECL_NO_INLINE_WARNING_P (fndecl) = 1;

  /* We process method specializations in finish_struct_1.  */
  if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl))
    {
      fndecl = push_template_decl (fndecl);
      if (fndecl == error_mark_node)
	return fndecl;
    }

  if (! DECL_FRIEND_P (fndecl))
    {
      if (DECL_CHAIN (fndecl))
	{
	  fndecl = copy_node (fndecl);
	  TREE_CHAIN (fndecl) = NULL_TREE;
	}
    }

  cp_finish_decl (fndecl, NULL_TREE, false, NULL_TREE, 0);

  DECL_IN_AGGR_P (fndecl) = 1;
  return fndecl;
}


/* VAR is a VAR_DECL.  If its type is incomplete, remember VAR so that
   we can lay it out later, when and if its type becomes complete.

   Also handle constexpr variables where the initializer involves
   an unlowered PTRMEM_CST because the class isn't complete yet.  */

void
maybe_register_incomplete_var (tree var)
{
  gcc_assert (VAR_P (var));

  /* Keep track of variables with incomplete types.  */
  if (!processing_template_decl && TREE_TYPE (var) != error_mark_node
      && DECL_EXTERNAL (var))
    {
      tree inner_type = TREE_TYPE (var);

      while (TREE_CODE (inner_type) == ARRAY_TYPE)
	inner_type = TREE_TYPE (inner_type);
      inner_type = TYPE_MAIN_VARIANT (inner_type);

      if ((!COMPLETE_TYPE_P (inner_type) && CLASS_TYPE_P (inner_type))
	  /* RTTI TD entries are created while defining the type_info.  */
	  || (TYPE_LANG_SPECIFIC (inner_type)
	      && TYPE_BEING_DEFINED (inner_type)))
	{
	  incomplete_var iv = {var, inner_type};
	  vec_safe_push (incomplete_vars, iv);
	}
      else if (!(DECL_LANG_SPECIFIC (var) && DECL_TEMPLATE_INFO (var))
	       && decl_constant_var_p (var)
	       && (TYPE_PTRMEM_P (inner_type) || CLASS_TYPE_P (inner_type)))
	{
	  /* When the outermost open class is complete we can resolve any
	     pointers-to-members.  */
	  tree context = outermost_open_class ();
	  incomplete_var iv = {var, context};
	  vec_safe_push (incomplete_vars, iv);
	}
    }
}

/* Called when a class type (given by TYPE) is defined.  If there are
   any existing VAR_DECLs whose type has been completed by this
   declaration, update them now.  */

void
complete_vars (tree type)
{
  unsigned ix;
  incomplete_var *iv;

  for (ix = 0; vec_safe_iterate (incomplete_vars, ix, &iv); )
    {
      if (same_type_p (type, iv->incomplete_type))
	{
	  tree var = iv->decl;
	  tree type = TREE_TYPE (var);

	  if (type != error_mark_node
	      && (TYPE_MAIN_VARIANT (strip_array_types (type))
		  == iv->incomplete_type))
	    {
	      /* Complete the type of the variable.  The VAR_DECL itself
		 will be laid out in expand_expr.  */
	      complete_type (type);
	      cp_apply_type_quals_to_decl (cp_type_quals (type), var);
	    }

	  /* Remove this entry from the list.  */
	  incomplete_vars->unordered_remove (ix);
	}
      else
	ix++;
    }

  /* Check for pending declarations which may have abstract type.  */
  complete_type_check_abstract (type);
}

/* If DECL is of a type which needs a cleanup, build and return an
   expression to perform that cleanup here.  Return NULL_TREE if no
   cleanup need be done.  DECL can also be a _REF when called from
   split_nonconstant_init_1.  */

tree
cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
{
  tree type;
  tree attr;
  tree cleanup;

  /* Assume no cleanup is required.  */
  cleanup = NULL_TREE;

  if (error_operand_p (decl))
    return cleanup;

  /* Handle "__attribute__((cleanup))".  We run the cleanup function
     before the destructor since the destructor is what actually
     terminates the lifetime of the object.  */
  if (DECL_P (decl))
    attr = lookup_attribute ("cleanup", DECL_ATTRIBUTES (decl));
  else
    attr = NULL_TREE;
  if (attr)
    {
      tree id;
      tree fn;
      tree arg;

      /* Get the name specified by the user for the cleanup function.  */
      id = TREE_VALUE (TREE_VALUE (attr));
      /* Look up the name to find the cleanup function to call.  It is
	 important to use lookup_name here because that is what is
	 used in c-common.c:handle_cleanup_attribute when performing
	 initial checks on the attribute.  Note that those checks
	 include ensuring that the function found is not an overloaded
	 function, or an object with an overloaded call operator,
	 etc.; we can rely on the fact that the function found is an
	 ordinary FUNCTION_DECL.  */
      fn = lookup_name (id);
      arg = build_address (decl);
      if (!mark_used (decl, complain) && !(complain & tf_error))
	return error_mark_node;
      cleanup = cp_build_function_call_nary (fn, complain, arg, NULL_TREE);
      if (cleanup == error_mark_node)
	return error_mark_node;
    }
  /* Handle ordinary C++ destructors.  */
  type = TREE_TYPE (decl);
  if (type_build_dtor_call (type))
    {
      int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR;
      tree addr;
      tree call;

      if (TREE_CODE (type) == ARRAY_TYPE)
	addr = decl;
      else
	addr = build_address (decl);

      call = build_delete (TREE_TYPE (addr), addr,
			   sfk_complete_destructor, flags, 0, complain);
      if (call == error_mark_node)
	cleanup = error_mark_node;
      else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
	/* Discard the call.  */;
      else if (cleanup)
	cleanup = cp_build_compound_expr (cleanup, call, complain);
      else
	cleanup = call;
    }

  /* build_delete sets the location of the destructor call to the
     current location, even though the destructor is going to be
     called later, at the end of the current scope.  This can lead to
     a "jumpy" behavior for users of debuggers when they step around
     the end of the block.  So let's unset the location of the
     destructor call instead.  */
  protected_set_expr_location (cleanup, UNKNOWN_LOCATION);

  if (cleanup
      && DECL_P (decl)
      && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (TREE_TYPE (decl)))
      /* Treat objects with destructors as used; the destructor may do
	 something substantive.  */
      && !mark_used (decl, complain) && !(complain & tf_error))
    return error_mark_node;

  return cleanup;
}


/* Return the FUNCTION_TYPE that corresponds to MEMFNTYPE, which can be a
   FUNCTION_DECL, METHOD_TYPE, FUNCTION_TYPE, pointer or reference to
   METHOD_TYPE or FUNCTION_TYPE, or pointer to member function.  */

tree
static_fn_type (tree memfntype)
{
  tree fntype;
  tree args;

  if (TYPE_PTRMEMFUNC_P (memfntype))
    memfntype = TYPE_PTRMEMFUNC_FN_TYPE (memfntype);
  if (INDIRECT_TYPE_P (memfntype)
      || TREE_CODE (memfntype) == FUNCTION_DECL)
    memfntype = TREE_TYPE (memfntype);
  if (TREE_CODE (memfntype) == FUNCTION_TYPE)
    return memfntype;
  gcc_assert (TREE_CODE (memfntype) == METHOD_TYPE);
  args = TYPE_ARG_TYPES (memfntype);
  fntype = build_function_type (TREE_TYPE (memfntype), TREE_CHAIN (args));
  fntype = apply_memfn_quals (fntype, type_memfn_quals (memfntype));
  fntype = (cp_build_type_attribute_variant
	    (fntype, TYPE_ATTRIBUTES (memfntype)));
  fntype = cxx_copy_lang_qualifiers (fntype, memfntype);
  return fntype;
}

/* DECL was originally constructed as a non-static member function,
   but turned out to be static.  Update it accordingly.  */

void
revert_static_member_fn (tree decl)
{
  tree stype = static_fn_type (decl);
  cp_cv_quals quals = type_memfn_quals (stype);
  cp_ref_qualifier rqual = type_memfn_rqual (stype);

  if (quals != TYPE_UNQUALIFIED || rqual != REF_QUAL_NONE)
    stype = apply_memfn_quals (stype, TYPE_UNQUALIFIED, REF_QUAL_NONE);

  TREE_TYPE (decl) = stype;

  if (DECL_ARGUMENTS (decl))
    DECL_ARGUMENTS (decl) = DECL_CHAIN (DECL_ARGUMENTS (decl));
  DECL_STATIC_FUNCTION_P (decl) = 1;
}

/* Return which tree structure is used by T, or TS_CP_GENERIC if T is
   one of the language-independent trees.  */

enum cp_tree_node_structure_enum
cp_tree_node_structure (union lang_tree_node * t)
{
  switch (TREE_CODE (&t->generic))
    {
    case DEFAULT_ARG:		return TS_CP_DEFAULT_ARG;
    case DEFERRED_NOEXCEPT:	return TS_CP_DEFERRED_NOEXCEPT;
    case IDENTIFIER_NODE:	return TS_CP_IDENTIFIER;
    case OVERLOAD:		return TS_CP_OVERLOAD;
    case TEMPLATE_PARM_INDEX:	return TS_CP_TPI;
    case PTRMEM_CST:		return TS_CP_PTRMEM;
    case BASELINK:		return TS_CP_BASELINK;
    case TEMPLATE_DECL:		return TS_CP_TEMPLATE_DECL;
    case STATIC_ASSERT:		return TS_CP_STATIC_ASSERT;
    case ARGUMENT_PACK_SELECT:  return TS_CP_ARGUMENT_PACK_SELECT;
    case TRAIT_EXPR:		return TS_CP_TRAIT_EXPR;
    case LAMBDA_EXPR:		return TS_CP_LAMBDA_EXPR;
    case TEMPLATE_INFO:		return TS_CP_TEMPLATE_INFO;
    case CONSTRAINT_INFO:       return TS_CP_CONSTRAINT_INFO;
    case USERDEF_LITERAL:	return TS_CP_USERDEF_LITERAL;
    default:			return TS_CP_GENERIC;
    }
}

/* Build the void_list_node (void_type_node having been created).  */
tree
build_void_list_node (void)
{
  tree t = build_tree_list (NULL_TREE, void_type_node);
  return t;
}

bool
cp_missing_noreturn_ok_p (tree decl)
{
  /* A missing noreturn is ok for the `main' function.  */
  return DECL_MAIN_P (decl);
}

/* Return the decl used to identify the COMDAT group into which DECL should
   be placed.  */

tree
cxx_comdat_group (tree decl)
{
  /* Virtual tables, construction virtual tables, and virtual table
     tables all go in a single COMDAT group, named after the primary
     virtual table.  */
  if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl))
    decl = CLASSTYPE_VTABLES (DECL_CONTEXT (decl));
  /* For all other DECLs, the COMDAT group is the mangled name of the
     declaration itself.  */
  else
    {
      while (DECL_THUNK_P (decl))
	{
	  /* If TARGET_USE_LOCAL_THUNK_ALIAS_P, use_thunk puts the thunk
	     into the same section as the target function.  In that case
	     we must return target's name.  */
	  tree target = THUNK_TARGET (decl);
	  if (TARGET_USE_LOCAL_THUNK_ALIAS_P (target)
	      && DECL_SECTION_NAME (target) != NULL
	      && DECL_ONE_ONLY (target))
	    decl = target;
	  else
	    break;
	}
    }

  return decl;
}

/* Returns the return type for FN as written by the user, which may include
   a placeholder for a deduced return type.  */

tree
fndecl_declared_return_type (tree fn)
{
  fn = STRIP_TEMPLATE (fn);
  if (FNDECL_USED_AUTO (fn))
    {
      struct language_function *f = NULL;
      if (DECL_STRUCT_FUNCTION (fn))
	f = DECL_STRUCT_FUNCTION (fn)->language;
      if (f == NULL)
	f = DECL_SAVED_FUNCTION_DATA (fn);
      return f->x_auto_return_pattern;
    }
  return TREE_TYPE (TREE_TYPE (fn));
}

/* Returns true iff DECL is a variable or function declared with an auto type
   that has not yet been deduced to a real type.  */

bool
undeduced_auto_decl (tree decl)
{
  if (cxx_dialect < cxx11)
    return false;
  return ((VAR_OR_FUNCTION_DECL_P (decl)
	   || TREE_CODE (decl) == TEMPLATE_DECL)
	  && type_uses_auto (TREE_TYPE (decl)));
}

/* Complain if DECL has an undeduced return type.  */

bool
require_deduced_type (tree decl, tsubst_flags_t complain)
{
  if (undeduced_auto_decl (decl))
    {
      if (complain & tf_error)
	error ("use of %qD before deduction of %<auto%>", decl);
      return false;
    }
  return true;
}

/* Create a representation of the explicit-specifier with
   constant-expression of EXPR.  COMPLAIN is as for tsubst.  */

tree
build_explicit_specifier (tree expr, tsubst_flags_t complain)
{
  if (processing_template_decl && value_dependent_expression_p (expr))
    /* Wait for instantiation, tsubst_function_decl will handle it.  */
    return expr;

  expr = build_converted_constant_expr (boolean_type_node, expr, complain);
  expr = instantiate_non_dependent_expr (expr);
  expr = cxx_constant_value (expr);
  return expr;
}

#include "gt-cp-decl.h"
