/* Language-dependent node constructors for parse phase of GNU compiler.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.
   Hacked 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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "cp-tree.h"
#include "gimple-expr.h"
#include "cgraph.h"
#include "stor-layout.h"
#include "print-tree.h"
#include "tree-iterator.h"
#include "tree-inline.h"
#include "debug.h"
#include "convert.h"
#include "gimplify.h"
#include "stringpool.h"
#include "attribs.h"
#include "flags.h"
#include "selftest.h"

static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
static hashval_t list_hash_pieces (tree, tree, tree);
static tree build_target_expr (tree, tree, tsubst_flags_t);
static tree count_trees_r (tree *, int *, void *);
static tree verify_stmt_tree_r (tree *, int *, void *);

static tree handle_init_priority_attribute (tree *, tree, tree, int, bool *);
static tree handle_abi_tag_attribute (tree *, tree, tree, int, bool *);

/* If REF is an lvalue, returns the kind of lvalue that REF is.
   Otherwise, returns clk_none.  */

cp_lvalue_kind
lvalue_kind (const_tree ref)
{
  cp_lvalue_kind op1_lvalue_kind = clk_none;
  cp_lvalue_kind op2_lvalue_kind = clk_none;

  /* Expressions of reference type are sometimes wrapped in
     INDIRECT_REFs.  INDIRECT_REFs are just internal compiler
     representation, not part of the language, so we have to look
     through them.  */
  if (REFERENCE_REF_P (ref))
    return lvalue_kind (TREE_OPERAND (ref, 0));

  if (TREE_TYPE (ref)
      && TYPE_REF_P (TREE_TYPE (ref)))
    {
      /* unnamed rvalue references are rvalues */
      if (TYPE_REF_IS_RVALUE (TREE_TYPE (ref))
	  && TREE_CODE (ref) != PARM_DECL
	  && !VAR_P (ref)
	  && TREE_CODE (ref) != COMPONENT_REF
	  /* Functions are always lvalues.  */
	  && TREE_CODE (TREE_TYPE (TREE_TYPE (ref))) != FUNCTION_TYPE)
	{
	  op1_lvalue_kind = clk_rvalueref;
	  if (implicit_rvalue_p (ref))
	    op1_lvalue_kind |= clk_implicit_rval;
	  return op1_lvalue_kind;
	}

      /* lvalue references and named rvalue references are lvalues.  */
      return clk_ordinary;
    }

  if (ref == current_class_ptr)
    return clk_none;

  /* Expressions with cv void type are prvalues.  */
  if (TREE_TYPE (ref) && VOID_TYPE_P (TREE_TYPE (ref)))
    return clk_none;

  switch (TREE_CODE (ref))
    {
    case SAVE_EXPR:
      return clk_none;

      /* preincrements and predecrements are valid lvals, provided
	 what they refer to are valid lvals.  */
    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case TRY_CATCH_EXPR:
    case REALPART_EXPR:
    case IMAGPART_EXPR:
    case VIEW_CONVERT_EXPR:
      return lvalue_kind (TREE_OPERAND (ref, 0));

    case ARRAY_REF:
      {
	tree op1 = TREE_OPERAND (ref, 0);
	if (TREE_CODE (TREE_TYPE (op1)) == ARRAY_TYPE)
	  {
	    op1_lvalue_kind = lvalue_kind (op1);
	    if (op1_lvalue_kind == clk_class)
	      /* in the case of an array operand, the result is an lvalue if
		 that operand is an lvalue and an xvalue otherwise */
	      op1_lvalue_kind = clk_rvalueref;
	    return op1_lvalue_kind;
	  }
	else
	  return clk_ordinary;
      }

    case MEMBER_REF:
    case DOTSTAR_EXPR:
      if (TREE_CODE (ref) == MEMBER_REF)
	op1_lvalue_kind = clk_ordinary;
      else
	op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
      if (TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
	op1_lvalue_kind = clk_none;
      else if (op1_lvalue_kind == clk_class)
	/* The result of a .* expression whose second operand is a pointer to a
	   data member is an lvalue if the first operand is an lvalue and an
	   xvalue otherwise.  */
	op1_lvalue_kind = clk_rvalueref;
      return op1_lvalue_kind;

    case COMPONENT_REF:
      if (BASELINK_P (TREE_OPERAND (ref, 1)))
	{
	  tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (ref, 1));

	  /* For static member function recurse on the BASELINK, we can get
	     here e.g. from reference_binding.  If BASELINK_FUNCTIONS is
	     OVERLOAD, the overload is resolved first if possible through
	     resolve_address_of_overloaded_function.  */
	  if (TREE_CODE (fn) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (fn))
	    return lvalue_kind (TREE_OPERAND (ref, 1));
	}
      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
      if (op1_lvalue_kind == clk_class)
	/* If E1 is an lvalue, then E1.E2 is an lvalue;
	   otherwise E1.E2 is an xvalue.  */
	op1_lvalue_kind = clk_rvalueref;

      /* Look at the member designator.  */
      if (!op1_lvalue_kind)
	;
      else if (is_overloaded_fn (TREE_OPERAND (ref, 1)))
	/* The "field" can be a FUNCTION_DECL or an OVERLOAD in some
	   situations.  If we're seeing a COMPONENT_REF, it's a non-static
	   member, so it isn't an lvalue. */
	op1_lvalue_kind = clk_none;
      else if (TREE_CODE (TREE_OPERAND (ref, 1)) != FIELD_DECL)
	/* This can be IDENTIFIER_NODE in a template.  */;
      else if (DECL_C_BIT_FIELD (TREE_OPERAND (ref, 1)))
	{
	  /* Clear the ordinary bit.  If this object was a class
	     rvalue we want to preserve that information.  */
	  op1_lvalue_kind &= ~clk_ordinary;
	  /* The lvalue is for a bitfield.  */
	  op1_lvalue_kind |= clk_bitfield;
	}
      else if (DECL_PACKED (TREE_OPERAND (ref, 1)))
	op1_lvalue_kind |= clk_packed;

      return op1_lvalue_kind;

    case STRING_CST:
    case COMPOUND_LITERAL_EXPR:
      return clk_ordinary;

    case CONST_DECL:
      /* CONST_DECL without TREE_STATIC are enumeration values and
	 thus not lvalues.  With TREE_STATIC they are used by ObjC++
	 in objc_build_string_object and need to be considered as
	 lvalues.  */
      if (! TREE_STATIC (ref))
	return clk_none;
      /* FALLTHRU */
    case VAR_DECL:
      if (VAR_P (ref) && DECL_HAS_VALUE_EXPR_P (ref))
	return lvalue_kind (DECL_VALUE_EXPR (CONST_CAST_TREE (ref)));

      if (TREE_READONLY (ref) && ! TREE_STATIC (ref)
	  && DECL_LANG_SPECIFIC (ref)
	  && DECL_IN_AGGR_P (ref))
	return clk_none;
      /* FALLTHRU */
    case INDIRECT_REF:
    case ARROW_EXPR:
    case PARM_DECL:
    case RESULT_DECL:
    case PLACEHOLDER_EXPR:
      return clk_ordinary;

      /* A scope ref in a template, left as SCOPE_REF to support later
	 access checking.  */
    case SCOPE_REF:
      gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
      {
	tree op = TREE_OPERAND (ref, 1);
	if (TREE_CODE (op) == FIELD_DECL)
	  return (DECL_C_BIT_FIELD (op) ? clk_bitfield : clk_ordinary);
	else
	  return lvalue_kind (op);
      }

    case MAX_EXPR:
    case MIN_EXPR:
      /* Disallow <? and >? as lvalues if either argument side-effects.  */
      if (TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 0))
	  || TREE_SIDE_EFFECTS (TREE_OPERAND (ref, 1)))
	return clk_none;
      op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 0));
      op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1));
      break;

    case COND_EXPR:
      if (processing_template_decl)
	{
	  /* Within templates, a REFERENCE_TYPE will indicate whether
	     the COND_EXPR result is an ordinary lvalue or rvalueref.
	     Since REFERENCE_TYPEs are handled above, if we reach this
	     point, we know we got a plain rvalue.  Unless we have a
	     type-dependent expr, that is, but we shouldn't be testing
	     lvalueness if we can't even tell the types yet!  */
	  gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
	  goto default_;
	}
      {
	tree op1 = TREE_OPERAND (ref, 1);
	if (!op1) op1 = TREE_OPERAND (ref, 0);
	tree op2 = TREE_OPERAND (ref, 2);
	op1_lvalue_kind = lvalue_kind (op1);
	op2_lvalue_kind = lvalue_kind (op2);
	if (!op1_lvalue_kind != !op2_lvalue_kind)
	  {
	    /* The second or the third operand (but not both) is a
	       throw-expression; the result is of the type
	       and value category of the other.  */
	    if (op1_lvalue_kind && TREE_CODE (op2) == THROW_EXPR)
	      op2_lvalue_kind = op1_lvalue_kind;
	    else if (op2_lvalue_kind && TREE_CODE (op1) == THROW_EXPR)
	      op1_lvalue_kind = op2_lvalue_kind;
	  }
      }
      break;

    case MODOP_EXPR:
      /* We expect to see unlowered MODOP_EXPRs only during
	 template processing.  */
      gcc_assert (processing_template_decl);
      return clk_ordinary;

    case MODIFY_EXPR:
    case TYPEID_EXPR:
      return clk_ordinary;

    case COMPOUND_EXPR:
      return lvalue_kind (TREE_OPERAND (ref, 1));

    case TARGET_EXPR:
      return clk_class;

    case VA_ARG_EXPR:
      return (CLASS_TYPE_P (TREE_TYPE (ref)) ? clk_class : clk_none);

    case CALL_EXPR:
      /* We can see calls outside of TARGET_EXPR in templates.  */
      if (CLASS_TYPE_P (TREE_TYPE (ref)))
	return clk_class;
      return clk_none;

    case FUNCTION_DECL:
      /* All functions (except non-static-member functions) are
	 lvalues.  */
      return (DECL_NONSTATIC_MEMBER_FUNCTION_P (ref)
	      ? clk_none : clk_ordinary);

    case BASELINK:
      /* We now represent a reference to a single static member function
	 with a BASELINK.  */
      /* This CONST_CAST is okay because BASELINK_FUNCTIONS returns
	 its argument unmodified and we assign it to a const_tree.  */
      return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));

    case NON_DEPENDENT_EXPR:
    case PAREN_EXPR:
      return lvalue_kind (TREE_OPERAND (ref, 0));

    case TEMPLATE_PARM_INDEX:
      if (CLASS_TYPE_P (TREE_TYPE (ref)))
	/* A template parameter object is an lvalue.  */
	return clk_ordinary;
      return clk_none;

    default:
    default_:
      if (!TREE_TYPE (ref))
	return clk_none;
      if (CLASS_TYPE_P (TREE_TYPE (ref))
	  || TREE_CODE (TREE_TYPE (ref)) == ARRAY_TYPE)
	return clk_class;
      return clk_none;
    }

  /* If one operand is not an lvalue at all, then this expression is
     not an lvalue.  */
  if (!op1_lvalue_kind || !op2_lvalue_kind)
    return clk_none;

  /* Otherwise, it's an lvalue, and it has all the odd properties
     contributed by either operand.  */
  op1_lvalue_kind = op1_lvalue_kind | op2_lvalue_kind;
  /* It's not an ordinary lvalue if it involves any other kind.  */
  if ((op1_lvalue_kind & ~clk_ordinary) != clk_none)
    op1_lvalue_kind &= ~clk_ordinary;
  /* It can't be both a pseudo-lvalue and a non-addressable lvalue.
     A COND_EXPR of those should be wrapped in a TARGET_EXPR.  */
  if ((op1_lvalue_kind & (clk_rvalueref|clk_class))
      && (op1_lvalue_kind & (clk_bitfield|clk_packed)))
    op1_lvalue_kind = clk_none;
  return op1_lvalue_kind;
}

/* Returns the kind of lvalue that REF is, in the sense of [basic.lval].  */

cp_lvalue_kind
real_lvalue_p (const_tree ref)
{
  cp_lvalue_kind kind = lvalue_kind (ref);
  if (kind & (clk_rvalueref|clk_class))
    return clk_none;
  else
    return kind;
}

/* c-common wants us to return bool.  */

bool
lvalue_p (const_tree t)
{
  return real_lvalue_p (t);
}

/* This differs from lvalue_p in that xvalues are included.  */

bool
glvalue_p (const_tree ref)
{
  cp_lvalue_kind kind = lvalue_kind (ref);
  if (kind & clk_class)
    return false;
  else
    return (kind != clk_none);
}

/* This differs from glvalue_p in that class prvalues are included.  */

bool
obvalue_p (const_tree ref)
{
  return (lvalue_kind (ref) != clk_none);
}

/* Returns true if REF is an xvalue (the result of dereferencing an rvalue
   reference), false otherwise.  */

bool
xvalue_p (const_tree ref)
{
  return (lvalue_kind (ref) & clk_rvalueref);
}

/* True if REF is a bit-field.  */

bool
bitfield_p (const_tree ref)
{
  return (lvalue_kind (ref) & clk_bitfield);
}

/* C++-specific version of stabilize_reference.  */

tree
cp_stabilize_reference (tree ref)
{
  STRIP_ANY_LOCATION_WRAPPER (ref);
  switch (TREE_CODE (ref))
    {
    case NON_DEPENDENT_EXPR:
      /* We aren't actually evaluating this.  */
      return ref;

    /* We need to treat specially anything stabilize_reference doesn't
       handle specifically.  */
    case VAR_DECL:
    case PARM_DECL:
    case RESULT_DECL:
    CASE_CONVERT:
    case FLOAT_EXPR:
    case FIX_TRUNC_EXPR:
    case INDIRECT_REF:
    case COMPONENT_REF:
    case BIT_FIELD_REF:
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
    case ERROR_MARK:
      break;
    default:
      cp_lvalue_kind kind = lvalue_kind (ref);
      if ((kind & ~clk_class) != clk_none)
	{
	  tree type = unlowered_expr_type (ref);
	  bool rval = !!(kind & clk_rvalueref);
	  type = cp_build_reference_type (type, rval);
	  /* This inhibits warnings in, eg, cxx_mark_addressable
	     (c++/60955).  */
	  warning_sentinel s (extra_warnings);
	  ref = build_static_cast (input_location, type, ref,
				   tf_error);
	}
    }

  return stabilize_reference (ref);
}

/* Test whether DECL is a builtin that may appear in a
   constant-expression. */

bool
builtin_valid_in_constant_expr_p (const_tree decl)
{
  STRIP_ANY_LOCATION_WRAPPER (decl);
  if (TREE_CODE (decl) != FUNCTION_DECL)
    /* Not a function.  */
    return false;
  if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL)
    {
      if (fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
	switch (DECL_FE_FUNCTION_CODE (decl))
	  {
	  case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
	  case CP_BUILT_IN_SOURCE_LOCATION:
	  case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
	  case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
	    return true;
	  default:
	    break;
	  }
      /* Not a built-in.  */
      return false;
    }
  switch (DECL_FUNCTION_CODE (decl))
    {
      /* These always have constant results like the corresponding
	 macros/symbol.  */
    case BUILT_IN_FILE:
    case BUILT_IN_FUNCTION:
    case BUILT_IN_LINE:

      /* The following built-ins are valid in constant expressions
	 when their arguments are.  */
    case BUILT_IN_ADD_OVERFLOW_P:
    case BUILT_IN_SUB_OVERFLOW_P:
    case BUILT_IN_MUL_OVERFLOW_P:

      /* These have constant results even if their operands are
	 non-constant.  */
    case BUILT_IN_CONSTANT_P:
    case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
      return true;
    default:
      return false;
    }
}

/* Build a TARGET_EXPR, initializing the DECL with the VALUE.  */

static tree
build_target_expr (tree decl, tree value, tsubst_flags_t complain)
{
  tree t;
  tree type = TREE_TYPE (decl);

  value = mark_rvalue_use (value);

  gcc_checking_assert (VOID_TYPE_P (TREE_TYPE (value))
		       || TREE_TYPE (decl) == TREE_TYPE (value)
		       /* On ARM ctors return 'this'.  */
		       || (TYPE_PTR_P (TREE_TYPE (value))
			   && TREE_CODE (value) == CALL_EXPR)
		       || useless_type_conversion_p (TREE_TYPE (decl),
						     TREE_TYPE (value)));

  /* Set TREE_READONLY for optimization, such as gimplify_init_constructor
     moving a constant aggregate into .rodata.  */
  if (CP_TYPE_CONST_NON_VOLATILE_P (type)
      && !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
      && !VOID_TYPE_P (TREE_TYPE (value))
      && reduced_constant_expression_p (value))
    TREE_READONLY (decl) = true;

  if (complain & tf_no_cleanup)
    /* The caller is building a new-expr and does not need a cleanup.  */
    t = NULL_TREE;
  else
    {
      t = cxx_maybe_build_cleanup (decl, complain);
      if (t == error_mark_node)
	return error_mark_node;
    }
  t = build4 (TARGET_EXPR, type, decl, value, t, NULL_TREE);
  if (location_t eloc = cp_expr_location (value))
    SET_EXPR_LOCATION (t, eloc);
  /* We always set TREE_SIDE_EFFECTS so that expand_expr does not
     ignore the TARGET_EXPR.  If there really turn out to be no
     side-effects, then the optimizer should be able to get rid of
     whatever code is generated anyhow.  */
  TREE_SIDE_EFFECTS (t) = 1;

  return t;
}

/* Return an undeclared local temporary of type TYPE for use in building a
   TARGET_EXPR.  */

tree
build_local_temp (tree type)
{
  tree slot = build_decl (input_location,
			  VAR_DECL, NULL_TREE, type);
  DECL_ARTIFICIAL (slot) = 1;
  DECL_IGNORED_P (slot) = 1;
  DECL_CONTEXT (slot) = current_function_decl;
  layout_decl (slot, 0);
  return slot;
}

/* Return whether DECL is such a local temporary (or one from
   create_tmp_var_raw).  */

bool
is_local_temp (tree decl)
{
  return (VAR_P (decl) && DECL_ARTIFICIAL (decl)
	  && !TREE_STATIC (decl));
}

/* Set various status flags when building an AGGR_INIT_EXPR object T.  */

static void
process_aggr_init_operands (tree t)
{
  bool side_effects;

  side_effects = TREE_SIDE_EFFECTS (t);
  if (!side_effects)
    {
      int i, n;
      n = TREE_OPERAND_LENGTH (t);
      for (i = 1; i < n; i++)
	{
	  tree op = TREE_OPERAND (t, i);
	  if (op && TREE_SIDE_EFFECTS (op))
	    {
	      side_effects = 1;
	      break;
	    }
	}
    }
  TREE_SIDE_EFFECTS (t) = side_effects;
}

/* Build an AGGR_INIT_EXPR of class tcc_vl_exp with the indicated RETURN_TYPE,
   FN, and SLOT.  NARGS is the number of call arguments which are specified
   as a tree array ARGS.  */

static tree
build_aggr_init_array (tree return_type, tree fn, tree slot, int nargs,
		       tree *args)
{
  tree t;
  int i;

  t = build_vl_exp (AGGR_INIT_EXPR, nargs + 3);
  TREE_TYPE (t) = return_type;
  AGGR_INIT_EXPR_FN (t) = fn;
  AGGR_INIT_EXPR_SLOT (t) = slot;
  for (i = 0; i < nargs; i++)
    AGGR_INIT_EXPR_ARG (t, i) = args[i];
  process_aggr_init_operands (t);
  return t;
}

/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
   target.  TYPE is the type to be initialized.

   Build an AGGR_INIT_EXPR to represent the initialization.  This function
   differs from build_cplus_new in that an AGGR_INIT_EXPR can only be used
   to initialize another object, whereas a TARGET_EXPR can either
   initialize another object or create its own temporary object, and as a
   result building up a TARGET_EXPR requires that the type's destructor be
   callable.  */

tree
build_aggr_init_expr (tree type, tree init)
{
  tree fn;
  tree slot;
  tree rval;
  int is_ctor;

  gcc_assert (!VOID_TYPE_P (type));

  /* Don't build AGGR_INIT_EXPR in a template.  */
  if (processing_template_decl)
    return init;

  fn = cp_get_callee (init);
  if (fn == NULL_TREE)
    return convert (type, init);

  is_ctor = (TREE_CODE (fn) == ADDR_EXPR
	     && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
	     && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0)));

  /* We split the CALL_EXPR into its function and its arguments here.
     Then, in expand_expr, we put them back together.  The reason for
     this is that this expression might be a default argument
     expression.  In that case, we need a new temporary every time the
     expression is used.  That's what break_out_target_exprs does; it
     replaces every AGGR_INIT_EXPR with a copy that uses a fresh
     temporary slot.  Then, expand_expr builds up a call-expression
     using the new slot.  */

  /* If we don't need to use a constructor to create an object of this
     type, don't mess with AGGR_INIT_EXPR.  */
  if (is_ctor || TREE_ADDRESSABLE (type))
    {
      slot = build_local_temp (type);

      if (TREE_CODE (init) == CALL_EXPR)
	{
	  rval = build_aggr_init_array (void_type_node, fn, slot,
					call_expr_nargs (init),
					CALL_EXPR_ARGP (init));
	  AGGR_INIT_FROM_THUNK_P (rval)
	    = CALL_FROM_THUNK_P (init);
	}
      else
	{
	  rval = build_aggr_init_array (void_type_node, fn, slot,
					aggr_init_expr_nargs (init),
					AGGR_INIT_EXPR_ARGP (init));
	  AGGR_INIT_FROM_THUNK_P (rval)
	    = AGGR_INIT_FROM_THUNK_P (init);
	}
      TREE_SIDE_EFFECTS (rval) = 1;
      AGGR_INIT_VIA_CTOR_P (rval) = is_ctor;
      TREE_NOTHROW (rval) = TREE_NOTHROW (init);
      CALL_EXPR_OPERATOR_SYNTAX (rval) = CALL_EXPR_OPERATOR_SYNTAX (init);
      CALL_EXPR_ORDERED_ARGS (rval) = CALL_EXPR_ORDERED_ARGS (init);
      CALL_EXPR_REVERSE_ARGS (rval) = CALL_EXPR_REVERSE_ARGS (init);
    }
  else
    rval = init;

  return rval;
}

/* INIT is a CALL_EXPR or AGGR_INIT_EXPR which needs info about its
   target.  TYPE is the type that this initialization should appear to
   have.

   Build an encapsulation of the initialization to perform
   and return it so that it can be processed by language-independent
   and language-specific expression expanders.  */

tree
build_cplus_new (tree type, tree init, tsubst_flags_t complain)
{
  /* This function should cope with what build_special_member_call
     can produce.  When performing parenthesized aggregate initialization,
     it can produce a { }.  */
  if (BRACE_ENCLOSED_INITIALIZER_P (init))
    {
      gcc_assert (cxx_dialect >= cxx20);
      return finish_compound_literal (type, init, complain);
    }

  tree rval = build_aggr_init_expr (type, init);
  tree slot;

  if (init == error_mark_node)
    return error_mark_node;

  if (!complete_type_or_maybe_complain (type, init, complain))
    return error_mark_node;

  /* Make sure that we're not trying to create an instance of an
     abstract class.  */
  if (abstract_virtuals_error (NULL_TREE, type, complain))
    return error_mark_node;

  if (TREE_CODE (rval) == AGGR_INIT_EXPR)
    slot = AGGR_INIT_EXPR_SLOT (rval);
  else if (TREE_CODE (rval) == CALL_EXPR
	   || TREE_CODE (rval) == CONSTRUCTOR)
    slot = build_local_temp (type);
  else
    return rval;

  rval = build_target_expr (slot, rval, complain);

  if (rval != error_mark_node)
    TARGET_EXPR_IMPLICIT_P (rval) = 1;

  return rval;
}

/* Subroutine of build_vec_init_expr: Build up a single element
   intialization as a proxy for the full array initialization to get things
   marked as used and any appropriate diagnostics.

   This used to be necessary because we were deferring building the actual
   constructor calls until gimplification time; now we only do it to set
   VEC_INIT_EXPR_IS_CONSTEXPR.

   We assume that init is either NULL_TREE, {}, void_type_node (indicating
   value-initialization), or another array to copy.  */

static tree
build_vec_init_elt (tree type, tree init, tsubst_flags_t complain)
{
  tree inner_type = strip_array_types (type);

  if (integer_zerop (array_type_nelts_total (type))
      || !CLASS_TYPE_P (inner_type))
    /* No interesting initialization to do.  */
    return integer_zero_node;
  if (init && BRACE_ENCLOSED_INITIALIZER_P (init))
    {
      /* Even if init has initializers for some array elements,
	 we're interested in the {}-init of trailing elements.	*/
      if (CP_AGGREGATE_TYPE_P (inner_type))
	{
	  tree empty = build_constructor (init_list_type_node, nullptr);
	  return digest_init (inner_type, empty, complain);
	}
      else
	/* It's equivalent to value-init.  */
	init = void_type_node;
    }
  if (init == void_type_node)
    return build_value_init (inner_type, complain);

  releasing_vec argvec;
  if (init && !BRACE_ENCLOSED_INITIALIZER_P (init))
    {
      gcc_assert (same_type_ignoring_top_level_qualifiers_p
		  (type, TREE_TYPE (init)));
      tree init_type = strip_array_types (TREE_TYPE (init));
      tree dummy = build_dummy_object (init_type);
      if (!lvalue_p (init))
	dummy = move (dummy);
      argvec->quick_push (dummy);
    }
  init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
				    &argvec, inner_type, LOOKUP_NORMAL,
				    complain);

  /* For a trivial constructor, build_over_call creates a TARGET_EXPR.  But
     we don't want one here because we aren't creating a temporary.  */
  if (TREE_CODE (init) == TARGET_EXPR)
    init = TARGET_EXPR_INITIAL (init);

  return init;
}

/* Return a TARGET_EXPR which expresses the initialization of an array to
   be named later, either default-initialization or copy-initialization
   from another array of the same type.  */

tree
build_vec_init_expr (tree type, tree init, tsubst_flags_t complain)
{
  if (tree vi = get_vec_init_expr (init))
    return vi;

  tree elt_init;
  if (init && TREE_CODE (init) == CONSTRUCTOR
      && !BRACE_ENCLOSED_INITIALIZER_P (init))
    /* We built any needed constructor calls in digest_init.  */
    elt_init = init;
  else
    elt_init = build_vec_init_elt (type, init, complain);

  bool value_init = false;
  if (init == void_type_node)
    {
      value_init = true;
      init = NULL_TREE;
    }

  tree slot = build_local_temp (type);
  init = build2 (VEC_INIT_EXPR, type, slot, init);
  TREE_SIDE_EFFECTS (init) = true;
  SET_EXPR_LOCATION (init, input_location);

  if (cxx_dialect >= cxx11)
    {
      bool cx = potential_constant_expression (elt_init);
      if (BRACE_ENCLOSED_INITIALIZER_P (init))
	cx &= potential_constant_expression (init);
      VEC_INIT_EXPR_IS_CONSTEXPR (init) = cx;
    }
  VEC_INIT_EXPR_VALUE_INIT (init) = value_init;

  return init;
}

/* Call build_vec_init to expand VEC_INIT into TARGET (for which NULL_TREE
   means VEC_INIT_EXPR_SLOT).  */

tree
expand_vec_init_expr (tree target, tree vec_init, tsubst_flags_t complain,
		      vec<tree,va_gc> **flags)
{
  iloc_sentinel ils = EXPR_LOCATION (vec_init);

  if (!target)
    target = VEC_INIT_EXPR_SLOT (vec_init);
  tree init = VEC_INIT_EXPR_INIT (vec_init);
  int from_array = (init && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE);
  return build_vec_init (target, NULL_TREE, init,
			 VEC_INIT_EXPR_VALUE_INIT (vec_init),
			 from_array, complain, flags);
}

/* Give a helpful diagnostic for a non-constexpr VEC_INIT_EXPR in a context
   that requires a constant expression.  */

void
diagnose_non_constexpr_vec_init (tree expr)
{
  tree type = TREE_TYPE (VEC_INIT_EXPR_SLOT (expr));
  tree init, elt_init;
  if (VEC_INIT_EXPR_VALUE_INIT (expr))
    init = void_type_node;
  else
    init = VEC_INIT_EXPR_INIT (expr);

  elt_init = build_vec_init_elt (type, init, tf_warning_or_error);
  require_potential_constant_expression (elt_init);
}

tree
build_array_copy (tree init)
{
  return get_target_expr (build_vec_init_expr
			  (TREE_TYPE (init), init, tf_warning_or_error));
}

/* Build a TARGET_EXPR using INIT to initialize a new temporary of the
   indicated TYPE.  */

tree
build_target_expr_with_type (tree init, tree type, tsubst_flags_t complain)
{
  gcc_assert (!VOID_TYPE_P (type));
  gcc_assert (!VOID_TYPE_P (TREE_TYPE (init)));

  if (TREE_CODE (init) == TARGET_EXPR
      || init == error_mark_node)
    return init;
  else if (CLASS_TYPE_P (type) && type_has_nontrivial_copy_init (type)
	   && TREE_CODE (init) != COND_EXPR
	   && TREE_CODE (init) != CONSTRUCTOR
	   && TREE_CODE (init) != VA_ARG_EXPR
	   && TREE_CODE (init) != CALL_EXPR)
    /* We need to build up a copy constructor call.  COND_EXPR is a special
       case because we already have copies on the arms and we don't want
       another one here.  A CONSTRUCTOR is aggregate initialization, which
       is handled separately.  A VA_ARG_EXPR is magic creation of an
       aggregate; there's no additional work to be done.  A CALL_EXPR
       already creates a prvalue.  */
    return force_rvalue (init, complain);

  return force_target_expr (type, init, complain);
}

/* Like the above function, but without the checking.  This function should
   only be used by code which is deliberately trying to subvert the type
   system, such as call_builtin_trap.  Or build_over_call, to avoid
   infinite recursion.  */

tree
force_target_expr (tree type, tree init, tsubst_flags_t complain)
{
  tree slot;

  gcc_assert (!VOID_TYPE_P (type));

  slot = build_local_temp (type);
  return build_target_expr (slot, init, complain);
}

/* Like build_target_expr_with_type, but use the type of INIT.  */

tree
get_target_expr (tree init, tsubst_flags_t complain /* = tf_warning_or_error */)
{
  if (TREE_CODE (init) == AGGR_INIT_EXPR)
    return build_target_expr (AGGR_INIT_EXPR_SLOT (init), init, complain);
  else if (TREE_CODE (init) == VEC_INIT_EXPR)
    return build_target_expr (VEC_INIT_EXPR_SLOT (init), init, complain);
  else
    {
      init = convert_bitfield_to_declared_type (init);
      return build_target_expr_with_type (init, TREE_TYPE (init), complain);
    }
}

/* If EXPR is a bitfield reference, convert it to the declared type of
   the bitfield, and return the resulting expression.  Otherwise,
   return EXPR itself.  */

tree
convert_bitfield_to_declared_type (tree expr)
{
  tree bitfield_type;

  bitfield_type = is_bitfield_expr_with_lowered_type (expr);
  if (bitfield_type)
    expr = convert_to_integer_nofold (TYPE_MAIN_VARIANT (bitfield_type),
				      expr);
  return expr;
}

/* EXPR is being used in an rvalue context.  Return a version of EXPR
   that is marked as an rvalue.  */

tree
rvalue (tree expr)
{
  tree type;

  if (error_operand_p (expr))
    return expr;

  expr = mark_rvalue_use (expr);

  /* [basic.lval]

     Non-class rvalues always have cv-unqualified types.  */
  type = TREE_TYPE (expr);
  if (!CLASS_TYPE_P (type) && cv_qualified_p (type))
    type = cv_unqualified (type);

  /* We need to do this for rvalue refs as well to get the right answer
     from decltype; see c++/36628.  */
  if (!processing_template_decl && glvalue_p (expr))
    {
      /* But don't use this function for class lvalues; use move (to treat an
	 lvalue as an xvalue) or force_rvalue (to make a prvalue copy).  */
      gcc_checking_assert (!CLASS_TYPE_P (type));
      expr = build1 (NON_LVALUE_EXPR, type, expr);
    }
  else if (type != TREE_TYPE (expr))
    expr = build_nop (type, expr);

  return expr;
}


struct cplus_array_info
{
  tree type;
  tree domain;
};

struct cplus_array_hasher : ggc_ptr_hash<tree_node>
{
  typedef cplus_array_info *compare_type;

  static hashval_t hash (tree t);
  static bool equal (tree, cplus_array_info *);
};

/* Hash an ARRAY_TYPE.  K is really of type `tree'.  */

hashval_t
cplus_array_hasher::hash (tree t)
{
  hashval_t hash;

  hash = TYPE_UID (TREE_TYPE (t));
  if (TYPE_DOMAIN (t))
    hash ^= TYPE_UID (TYPE_DOMAIN (t));
  return hash;
}

/* Compare two ARRAY_TYPEs.  K1 is really of type `tree', K2 is really
   of type `cplus_array_info*'. */

bool
cplus_array_hasher::equal (tree t1, cplus_array_info *t2)
{
  return (TREE_TYPE (t1) == t2->type && TYPE_DOMAIN (t1) == t2->domain);
}

/* Hash table containing dependent array types, which are unsuitable for
   the language-independent type hash table.  */
static GTY (()) hash_table<cplus_array_hasher> *cplus_array_htab;

/* Build an ARRAY_TYPE without laying it out.  */

static tree
build_min_array_type (tree elt_type, tree index_type)
{
  tree t = cxx_make_type (ARRAY_TYPE);
  TREE_TYPE (t) = elt_type;
  TYPE_DOMAIN (t) = index_type;
  return t;
}

/* Set TYPE_CANONICAL like build_array_type_1, but using
   build_cplus_array_type.  */

static void
set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep)
{
  /* Set the canonical type for this new node.  */
  if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
      || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (TYPE_CANONICAL (elt_type) != elt_type
	   || (index_type && TYPE_CANONICAL (index_type) != index_type))
    TYPE_CANONICAL (t)
      = build_cplus_array_type (TYPE_CANONICAL (elt_type),
				index_type
				? TYPE_CANONICAL (index_type) : index_type,
				dep);
  else
    TYPE_CANONICAL (t) = t;
}

/* Like build_array_type, but handle special C++ semantics: an array of a
   variant element type is a variant of the array of the main variant of
   the element type.  IS_DEPENDENT is -ve if we should determine the
   dependency.  Otherwise its bool value indicates dependency.  */

tree
build_cplus_array_type (tree elt_type, tree index_type, int dependent)
{
  tree t;

  if (elt_type == error_mark_node || index_type == error_mark_node)
    return error_mark_node;

  if (dependent < 0)
    dependent = (uses_template_parms (elt_type)
		 || (index_type && uses_template_parms (index_type)));

  if (elt_type != TYPE_MAIN_VARIANT (elt_type))
    /* Start with an array of the TYPE_MAIN_VARIANT.  */
    t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
				index_type, dependent);
  else if (dependent)
    {
      /* Since type_hash_canon calls layout_type, we need to use our own
	 hash table.  */
      cplus_array_info cai;
      hashval_t hash;

      if (cplus_array_htab == NULL)
	cplus_array_htab = hash_table<cplus_array_hasher>::create_ggc (61);
      
      hash = TYPE_UID (elt_type);
      if (index_type)
	hash ^= TYPE_UID (index_type);
      cai.type = elt_type;
      cai.domain = index_type;

      tree *e = cplus_array_htab->find_slot_with_hash (&cai, hash, INSERT); 
      if (*e)
	/* We have found the type: we're done.  */
	return (tree) *e;
      else
	{
	  /* Build a new array type.  */
	  t = build_min_array_type (elt_type, index_type);

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

	  /* Set the canonical type for this new node.  */
	  set_array_type_canon (t, elt_type, index_type, dependent);

	  /* Mark it as dependent now, this saves time later.  */
	  TYPE_DEPENDENT_P_VALID (t) = true;
	  TYPE_DEPENDENT_P (t) = true;
	}
    }
  else
    {
      bool typeless_storage = is_byte_access_type (elt_type);
      t = build_array_type (elt_type, index_type, typeless_storage);

      /* Mark as non-dependenty now, this will save time later.  */
      TYPE_DEPENDENT_P_VALID (t) = true;
    }

  /* Now check whether we already have this array variant.  */
  if (elt_type != TYPE_MAIN_VARIANT (elt_type))
    {
      tree m = t;
      for (t = m; t; t = TYPE_NEXT_VARIANT (t))
	if (TREE_TYPE (t) == elt_type
	    && TYPE_NAME (t) == NULL_TREE
	    && TYPE_ATTRIBUTES (t) == NULL_TREE)
	  break;
      if (!t)
	{
	  t = build_min_array_type (elt_type, index_type);
	  /* Mark dependency now, this saves time later.  */
	  TYPE_DEPENDENT_P_VALID (t) = true;
	  TYPE_DEPENDENT_P (t) = dependent;
	  set_array_type_canon (t, elt_type, index_type, dependent);
	  if (!dependent)
	    {
	      layout_type (t);
	      /* Make sure sizes are shared with the main variant.
		 layout_type can't be called after setting TYPE_NEXT_VARIANT,
		 as it will overwrite alignment etc. of all variants.  */
	      TYPE_SIZE (t) = TYPE_SIZE (m);
	      TYPE_SIZE_UNIT (t) = TYPE_SIZE_UNIT (m);
	      TYPE_TYPELESS_STORAGE (t) = TYPE_TYPELESS_STORAGE (m);
	    }

	  TYPE_MAIN_VARIANT (t) = m;
	  TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
	  TYPE_NEXT_VARIANT (m) = t;
	}
    }

  /* Avoid spurious warnings with VLAs (c++/54583).  */
  if (TYPE_SIZE (t) && EXPR_P (TYPE_SIZE (t)))
    suppress_warning (TYPE_SIZE (t), OPT_Wunused);

  /* Push these needs up to the ARRAY_TYPE so that initialization takes
     place more easily.  */
  bool needs_ctor = (TYPE_NEEDS_CONSTRUCTING (t)
		     = TYPE_NEEDS_CONSTRUCTING (elt_type));
  bool needs_dtor = (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
		     = TYPE_HAS_NONTRIVIAL_DESTRUCTOR (elt_type));

  if (!dependent && t == TYPE_MAIN_VARIANT (t)
      && !COMPLETE_TYPE_P (t) && COMPLETE_TYPE_P (elt_type))
    {
      /* The element type has been completed since the last time we saw
	 this array type; update the layout and 'tor flags for any variants
	 that need it.  */
      layout_type (t);
      for (tree v = TYPE_NEXT_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v))
	{
	  TYPE_NEEDS_CONSTRUCTING (v) = needs_ctor;
	  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (v) = needs_dtor;
	}
    }

  return t;
}

/* Return an ARRAY_TYPE with element type ELT and length N.  */

tree
build_array_of_n_type (tree elt, int n)
{
  return build_cplus_array_type (elt, build_index_type (size_int (n - 1)));
}

/* True iff T is an array of unknown bound.  */

bool
array_of_unknown_bound_p (const_tree t)
{
  return (TREE_CODE (t) == ARRAY_TYPE
	  && !TYPE_DOMAIN (t));
}

/* True iff T is an N3639 array of runtime bound (VLA).  These were approved
   for C++14 but then removed.  This should only be used for N3639
   specifically; code wondering more generally if something is a VLA should use
   vla_type_p.  */

bool
array_of_runtime_bound_p (tree t)
{
  if (!t || TREE_CODE (t) != ARRAY_TYPE)
    return false;
  if (variably_modified_type_p (TREE_TYPE (t), NULL_TREE))
    return false;
  tree dom = TYPE_DOMAIN (t);
  if (!dom)
    return false;
  tree max = TYPE_MAX_VALUE (dom);
  return (!potential_rvalue_constant_expression (max)
	  || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)));
}

/* True iff T is a variable length array.  */

bool
vla_type_p (tree t)
{
  for (; t && TREE_CODE (t) == ARRAY_TYPE;
       t = TREE_TYPE (t))
    if (tree dom = TYPE_DOMAIN (t))
      {
	tree max = TYPE_MAX_VALUE (dom);
	if (!potential_rvalue_constant_expression (max)
	    || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)))
	  return true;
      }
  return false;
}


/* Return a reference type node of MODE referring to TO_TYPE.  If MODE
   is VOIDmode the standard pointer mode will be picked.  If RVAL is
   true, return an rvalue reference type, otherwise return an lvalue
   reference type.  If a type node exists, reuse it, otherwise create
   a new one.  */
tree
cp_build_reference_type_for_mode (tree to_type, machine_mode mode, bool rval)
{
  tree lvalue_ref, t;

  if (to_type == error_mark_node)
    return error_mark_node;

  if (TYPE_REF_P (to_type))
    {
      rval = rval && TYPE_REF_IS_RVALUE (to_type);
      to_type = TREE_TYPE (to_type);
    }

  lvalue_ref = build_reference_type_for_mode (to_type, mode, false);

  if (!rval)
    return lvalue_ref;

  /* This code to create rvalue reference types is based on and tied
     to the code creating lvalue reference types in the middle-end
     functions build_reference_type_for_mode and build_reference_type.

     It works by putting the rvalue reference type nodes after the
     lvalue reference nodes in the TYPE_NEXT_REF_TO linked list, so
     they will effectively be ignored by the middle end.  */

  for (t = lvalue_ref; (t = TYPE_NEXT_REF_TO (t)); )
    if (TYPE_REF_IS_RVALUE (t))
      return t;

  t = build_distinct_type_copy (lvalue_ref);

  TYPE_REF_IS_RVALUE (t) = true;
  TYPE_NEXT_REF_TO (t) = TYPE_NEXT_REF_TO (lvalue_ref);
  TYPE_NEXT_REF_TO (lvalue_ref) = t;

  if (TYPE_STRUCTURAL_EQUALITY_P (to_type))
    SET_TYPE_STRUCTURAL_EQUALITY (t);
  else if (TYPE_CANONICAL (to_type) != to_type)
    TYPE_CANONICAL (t) 
      = cp_build_reference_type_for_mode (TYPE_CANONICAL (to_type), mode, rval);
  else
    TYPE_CANONICAL (t) = t;

  layout_type (t);

  return t;

}

/* Return a reference type node referring to TO_TYPE.  If RVAL is
   true, return an rvalue reference type, otherwise return an lvalue
   reference type.  If a type node exists, reuse it, otherwise create
   a new one.  */
tree
cp_build_reference_type (tree to_type, bool rval)
{
  return cp_build_reference_type_for_mode (to_type, VOIDmode, rval);
}

/* Returns EXPR cast to rvalue reference type, like std::move.  */

tree
move (tree expr)
{
  tree type = TREE_TYPE (expr);
  gcc_assert (!TYPE_REF_P (type));
  if (xvalue_p (expr))
    return expr;
  type = cp_build_reference_type (type, /*rval*/true);
  return build_static_cast (input_location, type, expr,
			    tf_warning_or_error);
}

/* Used by the C++ front end to build qualified array types.  However,
   the C version of this function does not properly maintain canonical
   types (which are not used in C).  */
tree
c_build_qualified_type (tree type, int type_quals, tree /* orig_qual_type */,
			size_t /* orig_qual_indirect */)
{
  return cp_build_qualified_type (type, type_quals);
}


/* Make a variant of TYPE, qualified with the TYPE_QUALS.  Handles
   arrays correctly.  In particular, if TYPE is an array of T's, and
   TYPE_QUALS is non-empty, returns an array of qualified T's.

   FLAGS determines how to deal with ill-formed qualifications. If
   tf_ignore_bad_quals is set, then bad qualifications are dropped
   (this is permitted if TYPE was introduced via a typedef or template
   type parameter). If bad qualifications are dropped and tf_warning
   is set, then a warning is issued for non-const qualifications.  If
   tf_ignore_bad_quals is not set and tf_error is not set, we
   return error_mark_node. Otherwise, we issue an error, and ignore
   the qualifications.

   Qualification of a reference type is valid when the reference came
   via a typedef or template type argument. [dcl.ref] No such
   dispensation is provided for qualifying a function type.  [dcl.fct]
   DR 295 queries this and the proposed resolution brings it into line
   with qualifying a reference.  We implement the DR.  We also behave
   in a similar manner for restricting non-pointer types.  */

tree
cp_build_qualified_type (tree type, int type_quals,
			 tsubst_flags_t complain /* = tf_warning_or_error */)
{
  tree result;
  int bad_quals = TYPE_UNQUALIFIED;

  if (type == error_mark_node)
    return type;

  if (type_quals == cp_type_quals (type))
    return type;

  if (TREE_CODE (type) == ARRAY_TYPE)
    {
      /* In C++, the qualification really applies to the array element
	 type.  Obtain the appropriately qualified element type.  */
      tree t;
      tree element_type
	= cp_build_qualified_type (TREE_TYPE (type), type_quals, complain);

      if (element_type == error_mark_node)
	return error_mark_node;

      /* See if we already have an identically qualified type.  Tests
	 should be equivalent to those in check_qualified_type.  */
      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
	if (TREE_TYPE (t) == element_type
	    && TYPE_NAME (t) == TYPE_NAME (type)
	    && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
	    && attribute_list_equal (TYPE_ATTRIBUTES (t),
				     TYPE_ATTRIBUTES (type)))
	  break;

      if (!t)
	{
	  /* If we already know the dependentness, tell the array type
	     constructor.  This is important for module streaming, as we cannot
	     dynamically determine that on read in.  */
	  t = build_cplus_array_type (element_type, TYPE_DOMAIN (type),
				      TYPE_DEPENDENT_P_VALID (type)
				      ? int (TYPE_DEPENDENT_P (type)) : -1);

	  /* Keep the typedef name.  */
	  if (TYPE_NAME (t) != TYPE_NAME (type))
	    {
	      t = build_variant_type_copy (t);
	      TYPE_NAME (t) = TYPE_NAME (type);
	      SET_TYPE_ALIGN (t, TYPE_ALIGN (type));
	      TYPE_USER_ALIGN (t) = TYPE_USER_ALIGN (type);
	    }
	}

      /* Even if we already had this variant, we update
	 TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case
	 they changed since the variant was originally created.

	 This seems hokey; if there is some way to use a previous
	 variant *without* coming through here,
	 TYPE_NEEDS_CONSTRUCTING will never be updated.  */
      TYPE_NEEDS_CONSTRUCTING (t)
	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (element_type));
      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t)
	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (element_type));
      return t;
    }
  else if (TREE_CODE (type) == TYPE_PACK_EXPANSION)
    {
      tree t = PACK_EXPANSION_PATTERN (type);

      t = cp_build_qualified_type (t, type_quals, complain);
      return make_pack_expansion (t, complain);
    }

  /* A reference or method type shall not be cv-qualified.
     [dcl.ref], [dcl.fct].  This used to be an error, but as of DR 295
     (in CD1) we always ignore extra cv-quals on functions.  */

  /* [dcl.ref/1] Cv-qualified references are ill-formed except when
     the cv-qualifiers are introduced through the use of a typedef-name
     ([dcl.typedef], [temp.param]) or decltype-specifier
     ([dcl.type.decltype]),in which case the cv-qualifiers are
     ignored.  */
  if (type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)
      && (TYPE_REF_P (type)
	  || FUNC_OR_METHOD_TYPE_P (type)))
    {
      if (TYPE_REF_P (type)
	  && (!typedef_variant_p (type) || FUNC_OR_METHOD_TYPE_P (type)))
	bad_quals |= type_quals & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
      type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE);
    }

  /* But preserve any function-cv-quals on a FUNCTION_TYPE.  */
  if (TREE_CODE (type) == FUNCTION_TYPE)
    type_quals |= type_memfn_quals (type);

  /* A restrict-qualified type must be a pointer (or reference)
     to object or incomplete type. */
  if ((type_quals & TYPE_QUAL_RESTRICT)
      && TREE_CODE (type) != TEMPLATE_TYPE_PARM
      && TREE_CODE (type) != TYPENAME_TYPE
      && !INDIRECT_TYPE_P (type))
    {
      bad_quals |= TYPE_QUAL_RESTRICT;
      type_quals &= ~TYPE_QUAL_RESTRICT;
    }

  if (bad_quals == TYPE_UNQUALIFIED
      || (complain & tf_ignore_bad_quals))
    /*OK*/;
  else if (!(complain & tf_error))
    return error_mark_node;
  else
    {
      tree bad_type = build_qualified_type (ptr_type_node, bad_quals);
      error ("%qV qualifiers cannot be applied to %qT",
	     bad_type, type);
    }

  /* Retrieve (or create) the appropriately qualified variant.  */
  result = build_qualified_type (type, type_quals);

  return result;
}

/* Return TYPE with const and volatile removed.  */

tree
cv_unqualified (tree type)
{
  int quals;

  if (type == error_mark_node)
    return type;

  quals = cp_type_quals (type);
  quals &= ~(TYPE_QUAL_CONST|TYPE_QUAL_VOLATILE);
  return cp_build_qualified_type (type, quals);
}

/* Subroutine of strip_typedefs.  We want to apply to RESULT the attributes
   from ATTRIBS that affect type identity, and no others.  If any are not
   applied, set *remove_attributes to true.  */

static tree
apply_identity_attributes (tree result, tree attribs, bool *remove_attributes)
{
  tree first_ident = NULL_TREE;
  tree new_attribs = NULL_TREE;
  tree *p = &new_attribs;

  if (OVERLOAD_TYPE_P (result))
    {
      /* On classes and enums all attributes are ingrained.  */
      gcc_assert (attribs == TYPE_ATTRIBUTES (result));
      return result;
    }

  for (tree a = attribs; a; a = TREE_CHAIN (a))
    {
      const attribute_spec *as
	= lookup_attribute_spec (get_attribute_name (a));
      if (as && as->affects_type_identity)
	{
	  if (!first_ident)
	    first_ident = a;
	  else if (first_ident == error_mark_node)
	    {
	      *p = tree_cons (TREE_PURPOSE (a), TREE_VALUE (a), NULL_TREE);
	      p = &TREE_CHAIN (*p);
	    }
	}
      else if (first_ident && first_ident != error_mark_node)
	{
	  for (tree a2 = first_ident; a2 != a; a2 = TREE_CHAIN (a2))
	    {
	      *p = tree_cons (TREE_PURPOSE (a2), TREE_VALUE (a2), NULL_TREE);
	      p = &TREE_CHAIN (*p);
	    }
	  first_ident = error_mark_node;
	}
    }
  if (first_ident != error_mark_node)
    new_attribs = first_ident;

  if (first_ident == attribs)
    /* All attributes affected type identity.  */;
  else
    *remove_attributes = true;

  return cp_build_type_attribute_variant (result, new_attribs);
}

/* Builds a qualified variant of T that is either not a typedef variant
   (the default behavior) or not a typedef variant of a user-facing type
   (if FLAGS contains STF_USER_FACING).

   E.g. consider the following declarations:
     typedef const int ConstInt;
     typedef ConstInt* PtrConstInt;
   If T is PtrConstInt, this function returns a type representing
     const int*.
   In other words, if T is a typedef, the function returns the underlying type.
   The cv-qualification and attributes of the type returned match the
   input type.
   They will always be compatible types.
   The returned type is built so that all of its subtypes
   recursively have their typedefs stripped as well.

   This is different from just returning TYPE_CANONICAL (T)
   Because of several reasons:
    * If T is a type that needs structural equality
      its TYPE_CANONICAL (T) will be NULL.
    * TYPE_CANONICAL (T) desn't carry type attributes
      and loses template parameter names.

   If REMOVE_ATTRIBUTES is non-null, also strip attributes that don't
   affect type identity, and set the referent to true if any were
   stripped.  */

tree
strip_typedefs (tree t, bool *remove_attributes /* = NULL */,
		unsigned int flags /* = 0 */)
{
  tree result = NULL, type = NULL, t0 = NULL;

  if (!t || t == error_mark_node)
    return t;

  if (TREE_CODE (t) == TREE_LIST)
    {
      bool changed = false;
      releasing_vec vec;
      tree r = t;
      for (; t; t = TREE_CHAIN (t))
	{
	  gcc_assert (!TREE_PURPOSE (t));
	  tree elt = strip_typedefs (TREE_VALUE (t), remove_attributes, flags);
	  if (elt != TREE_VALUE (t))
	    changed = true;
	  vec_safe_push (vec, elt);
	}
      if (changed)
	r = build_tree_list_vec (vec);
      return r;
    }

  gcc_assert (TYPE_P (t));

  if (t == TYPE_CANONICAL (t))
    return t;

  if (!(flags & STF_STRIP_DEPENDENT)
      && dependent_alias_template_spec_p (t, nt_opaque))
    /* DR 1558: However, if the template-id is dependent, subsequent
       template argument substitution still applies to the template-id.  */
    return t;

  switch (TREE_CODE (t))
    {
    case POINTER_TYPE:
      type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
      result = build_pointer_type_for_mode (type, TYPE_MODE (t), false);
      break;
    case REFERENCE_TYPE:
      type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
      result = cp_build_reference_type_for_mode (type, TYPE_MODE (t), TYPE_REF_IS_RVALUE (t));
      break;
    case OFFSET_TYPE:
      t0 = strip_typedefs (TYPE_OFFSET_BASETYPE (t), remove_attributes, flags);
      type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
      result = build_offset_type (t0, type);
      break;
    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (t))
	{
	  t0 = strip_typedefs (TYPE_PTRMEMFUNC_FN_TYPE (t),
			       remove_attributes, flags);
	  result = build_ptrmemfunc_type (t0);
	}
      break;
    case ARRAY_TYPE:
      type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
      t0  = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags);
      gcc_checking_assert (TYPE_DEPENDENT_P_VALID (t)
			   || !dependent_type_p (t));
      result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t));
      break;
    case FUNCTION_TYPE:
    case METHOD_TYPE:
      {
	tree arg_types = NULL, arg_node, arg_node2, arg_type;
	bool changed;

	/* Because we stomp on TREE_PURPOSE of TYPE_ARG_TYPES in many places
	   around the compiler (e.g. cp_parser_late_parsing_default_args), we
	   can't expect that re-hashing a function type will find a previous
	   equivalent type, so try to reuse the input type if nothing has
	   changed.  If the type is itself a variant, that will change.  */
	bool is_variant = typedef_variant_p (t);
	if (remove_attributes
	    && (TYPE_ATTRIBUTES (t) || TYPE_USER_ALIGN (t)))
	  is_variant = true;

	type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
	tree canon_spec = (flag_noexcept_type
			   ? canonical_eh_spec (TYPE_RAISES_EXCEPTIONS (t))
			   : NULL_TREE);
	changed = (type != TREE_TYPE (t) || is_variant
		   || TYPE_RAISES_EXCEPTIONS (t) != canon_spec);

	for (arg_node = TYPE_ARG_TYPES (t);
	     arg_node;
	     arg_node = TREE_CHAIN (arg_node))
	  {
	    if (arg_node == void_list_node)
	      break;
	    arg_type = strip_typedefs (TREE_VALUE (arg_node),
				       remove_attributes, flags);
	    gcc_assert (arg_type);
	    if (arg_type == TREE_VALUE (arg_node) && !changed)
	      continue;

	    if (!changed)
	      {
		changed = true;
		for (arg_node2 = TYPE_ARG_TYPES (t);
		     arg_node2 != arg_node;
		     arg_node2 = TREE_CHAIN (arg_node2))
		  arg_types
		    = tree_cons (TREE_PURPOSE (arg_node2),
				 TREE_VALUE (arg_node2), arg_types);
	      }

	    arg_types
	      = tree_cons (TREE_PURPOSE (arg_node), arg_type, arg_types);
	  }

	if (!changed)
	  return t;

	if (arg_types)
	  arg_types = nreverse (arg_types);

	/* A list of parameters not ending with an ellipsis
	   must end with void_list_node.  */
	if (arg_node)
	  arg_types = chainon (arg_types, void_list_node);

	if (TREE_CODE (t) == METHOD_TYPE)
	  {
	    tree class_type = TREE_TYPE (TREE_VALUE (arg_types));
	    gcc_assert (class_type);
	    result =
	      build_method_type_directly (class_type, type,
					  TREE_CHAIN (arg_types));
	  }
	else
	  {
	    result = build_function_type (type, arg_types);
	    result = apply_memfn_quals (result, type_memfn_quals (t));
	  }

	result = build_cp_fntype_variant (result,
					  type_memfn_rqual (t), canon_spec,
					  TYPE_HAS_LATE_RETURN_TYPE (t));
      }
      break;
    case TYPENAME_TYPE:
      {
	bool changed = false;
	tree fullname = TYPENAME_TYPE_FULLNAME (t);
	if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR
	    && TREE_OPERAND (fullname, 1))
	  {
	    tree args = TREE_OPERAND (fullname, 1);
	    tree new_args = copy_node (args);
	    for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
	      {
		tree arg = TREE_VEC_ELT (args, i);
		tree strip_arg;
		if (TYPE_P (arg))
		  strip_arg = strip_typedefs (arg, remove_attributes, flags);
		else
		  strip_arg = strip_typedefs_expr (arg, remove_attributes,
						   flags);
		TREE_VEC_ELT (new_args, i) = strip_arg;
		if (strip_arg != arg)
		  changed = true;
	      }
	    if (changed)
	      {
		NON_DEFAULT_TEMPLATE_ARGS_COUNT (new_args)
		  = NON_DEFAULT_TEMPLATE_ARGS_COUNT (args);
		fullname
		  = lookup_template_function (TREE_OPERAND (fullname, 0),
					      new_args);
	      }
	    else
	      ggc_free (new_args);
	  }
	tree ctx = strip_typedefs (TYPE_CONTEXT (t), remove_attributes, flags);
	if (!changed && ctx == TYPE_CONTEXT (t) && !typedef_variant_p (t))
	  return t;
	tree name = fullname;
	if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
	  name = TREE_OPERAND (fullname, 0);
	/* Use build_typename_type rather than make_typename_type because we
	   don't want to resolve it here, just strip typedefs.  */
	result = build_typename_type (ctx, name, fullname, typename_type);
      }
      break;
    case DECLTYPE_TYPE:
      result = strip_typedefs_expr (DECLTYPE_TYPE_EXPR (t),
				    remove_attributes, flags);
      if (result == DECLTYPE_TYPE_EXPR (t))
	result = NULL_TREE;
      else
	result = (finish_decltype_type
		  (result,
		   DECLTYPE_TYPE_ID_EXPR_OR_MEMBER_ACCESS_P (t),
		   tf_none));
      break;
    case UNDERLYING_TYPE:
      type = strip_typedefs (UNDERLYING_TYPE_TYPE (t),
			     remove_attributes, flags);
      result = finish_underlying_type (type);
      break;
    case TYPE_PACK_EXPANSION:
      {
	tree pat = PACK_EXPANSION_PATTERN (t);
	if (TYPE_P (pat))
	  {
	    type = strip_typedefs (pat, remove_attributes, flags);
	    if (type != pat)
	      {
		result = build_distinct_type_copy (t);
		PACK_EXPANSION_PATTERN (result) = type;
	      }
	  }
      }
      break;
    default:
      break;
    }

  if (!result)
    {
      if (typedef_variant_p (t))
	{
	  if ((flags & STF_USER_VISIBLE)
	      && !user_facing_original_type_p (t))
	    return t;
	  /* If T is a non-template alias or typedef, we can assume that
	     instantiating its definition will hit any substitution failure,
	     so we don't need to retain it here as well.  */
	  if (!alias_template_specialization_p (t, nt_opaque))
	    flags |= STF_STRIP_DEPENDENT;
	  result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)),
				   remove_attributes, flags);
	}
      else
	result = TYPE_MAIN_VARIANT (t);
    }
  /*gcc_assert (!typedef_variant_p (result)
	      || dependent_alias_template_spec_p (result, nt_opaque)
	      || ((flags & STF_USER_VISIBLE)
		  && !user_facing_original_type_p (result)));*/

  if (COMPLETE_TYPE_P (result) && !COMPLETE_TYPE_P (t))
  /* If RESULT is complete and T isn't, it's likely the case that T
     is a variant of RESULT which hasn't been updated yet.  Skip the
     attribute handling.  */;
  else
    {
      if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result)
	  || TYPE_ALIGN (t) != TYPE_ALIGN (result))
	{
	  gcc_assert (TYPE_USER_ALIGN (t));
	  if (remove_attributes)
	    *remove_attributes = true;
	  else
	    {
	      if (TYPE_ALIGN (t) == TYPE_ALIGN (result))
		result = build_variant_type_copy (result);
	      else
		result = build_aligned_type (result, TYPE_ALIGN (t));
	      TYPE_USER_ALIGN (result) = true;
	    }
	}

      if (TYPE_ATTRIBUTES (t))
	{
	  if (remove_attributes)
	    result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t),
						remove_attributes);
	  else
	    result = cp_build_type_attribute_variant (result,
						      TYPE_ATTRIBUTES (t));
	}
    }

  return cp_build_qualified_type (result, cp_type_quals (t));
}

/* Like strip_typedefs above, but works on expressions, so that in

   template<class T> struct A
   {
     typedef T TT;
     B<sizeof(TT)> b;
   };

   sizeof(TT) is replaced by sizeof(T).  */

tree
strip_typedefs_expr (tree t, bool *remove_attributes, unsigned int flags)
{
  unsigned i,n;
  tree r, type, *ops;
  enum tree_code code;

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

  STRIP_ANY_LOCATION_WRAPPER (t);

  if (DECL_P (t) || CONSTANT_CLASS_P (t))
    return t;

  /* Some expressions have type operands, so let's handle types here rather
     than check TYPE_P in multiple places below.  */
  if (TYPE_P (t))
    return strip_typedefs (t, remove_attributes, flags);

  code = TREE_CODE (t);
  switch (code)
    {
    case IDENTIFIER_NODE:
    case TEMPLATE_PARM_INDEX:
    case OVERLOAD:
    case BASELINK:
    case ARGUMENT_PACK_SELECT:
      return t;

    case TRAIT_EXPR:
      {
	tree type1 = strip_typedefs (TRAIT_EXPR_TYPE1 (t),
				     remove_attributes, flags);
	tree type2 = strip_typedefs (TRAIT_EXPR_TYPE2 (t),
				     remove_attributes, flags);
	if (type1 == TRAIT_EXPR_TYPE1 (t)
	    && type2 == TRAIT_EXPR_TYPE2 (t))
	  return t;
	r = copy_node (t);
	TRAIT_EXPR_TYPE1 (r) = type1;
	TRAIT_EXPR_TYPE2 (r) = type2;
	return r;
      }

    case TREE_LIST:
      {
	releasing_vec vec;
	bool changed = false;
	tree it;
	for (it = t; it; it = TREE_CHAIN (it))
	  {
	    tree val = strip_typedefs_expr (TREE_VALUE (it),
					    remove_attributes, flags);
	    vec_safe_push (vec, val);
	    if (val != TREE_VALUE (it))
	      changed = true;
	    gcc_assert (TREE_PURPOSE (it) == NULL_TREE);
	  }
	if (changed)
	  {
	    r = NULL_TREE;
	    FOR_EACH_VEC_ELT_REVERSE (*vec, i, it)
	      r = tree_cons (NULL_TREE, it, r);
	  }
	else
	  r = t;
	return r;
      }

    case TREE_VEC:
      {
	bool changed = false;
	releasing_vec vec;
	n = TREE_VEC_LENGTH (t);
	vec_safe_reserve (vec, n);
	for (i = 0; i < n; ++i)
	  {
	    tree op = strip_typedefs_expr (TREE_VEC_ELT (t, i),
					   remove_attributes, flags);
	    vec->quick_push (op);
	    if (op != TREE_VEC_ELT (t, i))
	      changed = true;
	  }
	if (changed)
	  {
	    r = copy_node (t);
	    for (i = 0; i < n; ++i)
	      TREE_VEC_ELT (r, i) = (*vec)[i];
	    NON_DEFAULT_TEMPLATE_ARGS_COUNT (r)
	      = NON_DEFAULT_TEMPLATE_ARGS_COUNT (t);
	  }
	else
	  r = t;
	return r;
      }

    case CONSTRUCTOR:
      {
	bool changed = false;
	vec<constructor_elt, va_gc> *vec
	  = vec_safe_copy (CONSTRUCTOR_ELTS (t));
	n = CONSTRUCTOR_NELTS (t);
	type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
	for (i = 0; i < n; ++i)
	  {
	    constructor_elt *e = &(*vec)[i];
	    tree op = strip_typedefs_expr (e->value, remove_attributes, flags);
	    if (op != e->value)
	      {
		changed = true;
		e->value = op;
	      }
	    gcc_checking_assert
	      (e->index == strip_typedefs_expr (e->index, remove_attributes,
						flags));
	  }

	if (!changed && type == TREE_TYPE (t))
	  {
	    vec_free (vec);
	    return t;
	  }
	else
	  {
	    r = copy_node (t);
	    TREE_TYPE (r) = type;
	    CONSTRUCTOR_ELTS (r) = vec;
	    return r;
	  }
      }

    case LAMBDA_EXPR:
      return t;

    case STATEMENT_LIST:
      error ("statement-expression in a constant expression");
      return error_mark_node;

    default:
      break;
    }

  gcc_assert (EXPR_P (t));

  n = cp_tree_operand_length (t);
  ops = XALLOCAVEC (tree, n);
  type = TREE_TYPE (t);

  switch (code)
    {
    CASE_CONVERT:
    case IMPLICIT_CONV_EXPR:
    case DYNAMIC_CAST_EXPR:
    case STATIC_CAST_EXPR:
    case CONST_CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case CAST_EXPR:
    case NEW_EXPR:
      type = strip_typedefs (type, remove_attributes, flags);
      /* fallthrough */

    default:
      for (i = 0; i < n; ++i)
	ops[i] = strip_typedefs_expr (TREE_OPERAND (t, i),
				      remove_attributes, flags);
      break;
    }

  /* If nothing changed, return t.  */
  for (i = 0; i < n; ++i)
    if (ops[i] != TREE_OPERAND (t, i))
      break;
  if (i == n && type == TREE_TYPE (t))
    return t;

  r = copy_node (t);
  TREE_TYPE (r) = type;
  for (i = 0; i < n; ++i)
    TREE_OPERAND (r, i) = ops[i];
  return r;
}

/* Makes a copy of BINFO and TYPE, which is to be inherited into a
   graph dominated by T.  If BINFO is NULL, TYPE is a dependent base,
   and we do a shallow copy.  If BINFO is non-NULL, we do a deep copy.
   VIRT indicates whether TYPE is inherited virtually or not.
   IGO_PREV points at the previous binfo of the inheritance graph
   order chain.  The newly copied binfo's TREE_CHAIN forms this
   ordering.

   The CLASSTYPE_VBASECLASSES vector of T is constructed in the
   correct order. That is in the order the bases themselves should be
   constructed in.

   The BINFO_INHERITANCE of a virtual base class points to the binfo
   of the most derived type. ??? We could probably change this so that
   BINFO_INHERITANCE becomes synonymous with BINFO_PRIMARY, and hence
   remove a field.  They currently can only differ for primary virtual
   virtual bases.  */

tree
copy_binfo (tree binfo, tree type, tree t, tree *igo_prev, int virt)
{
  tree new_binfo;

  if (virt)
    {
      /* See if we've already made this virtual base.  */
      new_binfo = binfo_for_vbase (type, t);
      if (new_binfo)
	return new_binfo;
    }

  new_binfo = make_tree_binfo (binfo ? BINFO_N_BASE_BINFOS (binfo) : 0);
  BINFO_TYPE (new_binfo) = type;

  /* Chain it into the inheritance graph.  */
  TREE_CHAIN (*igo_prev) = new_binfo;
  *igo_prev = new_binfo;

  if (binfo && !BINFO_DEPENDENT_BASE_P (binfo))
    {
      int ix;
      tree base_binfo;

      gcc_assert (SAME_BINFO_TYPE_P (BINFO_TYPE (binfo), type));

      BINFO_OFFSET (new_binfo) = BINFO_OFFSET (binfo);
      BINFO_VIRTUALS (new_binfo) = BINFO_VIRTUALS (binfo);

      /* We do not need to copy the accesses, as they are read only.  */
      BINFO_BASE_ACCESSES (new_binfo) = BINFO_BASE_ACCESSES (binfo);

      /* Recursively copy base binfos of BINFO.  */
      for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
	{
	  tree new_base_binfo;
	  new_base_binfo = copy_binfo (base_binfo, BINFO_TYPE (base_binfo),
				       t, igo_prev,
				       BINFO_VIRTUAL_P (base_binfo));

	  if (!BINFO_INHERITANCE_CHAIN (new_base_binfo))
	    BINFO_INHERITANCE_CHAIN (new_base_binfo) = new_binfo;
	  BINFO_BASE_APPEND (new_binfo, new_base_binfo);
	}
    }
  else
    BINFO_DEPENDENT_BASE_P (new_binfo) = 1;

  if (virt)
    {
      /* Push it onto the list after any virtual bases it contains
	 will have been pushed.  */
      CLASSTYPE_VBASECLASSES (t)->quick_push (new_binfo);
      BINFO_VIRTUAL_P (new_binfo) = 1;
      BINFO_INHERITANCE_CHAIN (new_binfo) = TYPE_BINFO (t);
    }

  return new_binfo;
}

/* Hashing of lists so that we don't make duplicates.
   The entry point is `list_hash_canon'.  */

struct list_proxy
{
  tree purpose;
  tree value;
  tree chain;
};

struct list_hasher : ggc_ptr_hash<tree_node>
{
  typedef list_proxy *compare_type;

  static hashval_t hash (tree);
  static bool equal (tree, list_proxy *);
};

/* Now here is the hash table.  When recording a list, it is added
   to the slot whose index is the hash code mod the table size.
   Note that the hash table is used for several kinds of lists.
   While all these live in the same table, they are completely independent,
   and the hash code is computed differently for each of these.  */

static GTY (()) hash_table<list_hasher> *list_hash_table;

/* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy
   for a node we are thinking about adding).  */

bool
list_hasher::equal (tree t, list_proxy *proxy)
{
  return (TREE_VALUE (t) == proxy->value
	  && TREE_PURPOSE (t) == proxy->purpose
	  && TREE_CHAIN (t) == proxy->chain);
}

/* Compute a hash code for a list (chain of TREE_LIST nodes
   with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
   TREE_COMMON slots), by adding the hash codes of the individual entries.  */

static hashval_t
list_hash_pieces (tree purpose, tree value, tree chain)
{
  hashval_t hashcode = 0;

  if (chain)
    hashcode += TREE_HASH (chain);

  if (value)
    hashcode += TREE_HASH (value);
  else
    hashcode += 1007;
  if (purpose)
    hashcode += TREE_HASH (purpose);
  else
    hashcode += 1009;
  return hashcode;
}

/* Hash an already existing TREE_LIST.  */

hashval_t
list_hasher::hash (tree t)
{
  return list_hash_pieces (TREE_PURPOSE (t),
			   TREE_VALUE (t),
			   TREE_CHAIN (t));
}

/* Given list components PURPOSE, VALUE, AND CHAIN, return the canonical
   object for an identical list if one already exists.  Otherwise, build a
   new one, and record it as the canonical object.  */

tree
hash_tree_cons (tree purpose, tree value, tree chain)
{
  int hashcode = 0;
  tree *slot;
  struct list_proxy proxy;

  /* Hash the list node.  */
  hashcode = list_hash_pieces (purpose, value, chain);
  /* Create a proxy for the TREE_LIST we would like to create.  We
     don't actually create it so as to avoid creating garbage.  */
  proxy.purpose = purpose;
  proxy.value = value;
  proxy.chain = chain;
  /* See if it is already in the table.  */
  slot = list_hash_table->find_slot_with_hash (&proxy, hashcode, INSERT);
  /* If not, create a new node.  */
  if (!*slot)
    *slot = tree_cons (purpose, value, chain);
  return (tree) *slot;
}

/* Constructor for hashed lists.  */

tree
hash_tree_chain (tree value, tree chain)
{
  return hash_tree_cons (NULL_TREE, value, chain);
}

void
debug_binfo (tree elem)
{
  HOST_WIDE_INT n;
  tree virtuals;

  fprintf (stderr, "type \"%s\", offset = " HOST_WIDE_INT_PRINT_DEC
	   "\nvtable type:\n",
	   TYPE_NAME_STRING (BINFO_TYPE (elem)),
	   TREE_INT_CST_LOW (BINFO_OFFSET (elem)));
  debug_tree (BINFO_TYPE (elem));
  if (BINFO_VTABLE (elem))
    fprintf (stderr, "vtable decl \"%s\"\n",
	     IDENTIFIER_POINTER (DECL_NAME (get_vtbl_decl_for_binfo (elem))));
  else
    fprintf (stderr, "no vtable decl yet\n");
  fprintf (stderr, "virtuals:\n");
  virtuals = BINFO_VIRTUALS (elem);
  n = 0;

  while (virtuals)
    {
      tree fndecl = TREE_VALUE (virtuals);
      fprintf (stderr, "%s [%ld =? %ld]\n",
	       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)),
	       (long) n, (long) TREE_INT_CST_LOW (DECL_VINDEX (fndecl)));
      ++n;
      virtuals = TREE_CHAIN (virtuals);
    }
}

/* Build a representation for the qualified name SCOPE::NAME.  TYPE is
   the type of the result expression, if known, or NULL_TREE if the
   resulting expression is type-dependent.  If TEMPLATE_P is true,
   NAME is known to be a template because the user explicitly used the
   "template" keyword after the "::".

   All SCOPE_REFs should be built by use of this function.  */

tree
build_qualified_name (tree type, tree scope, tree name, bool template_p)
{
  tree t;
  if (type == error_mark_node
      || scope == error_mark_node
      || name == error_mark_node)
    return error_mark_node;
  gcc_assert (TREE_CODE (name) != SCOPE_REF);
  t = build2 (SCOPE_REF, type, scope, name);
  QUALIFIED_NAME_IS_TEMPLATE (t) = template_p;
  PTRMEM_OK_P (t) = true;
  if (type)
    t = convert_from_reference (t);
  return t;
}

/* Like check_qualified_type, but also check ref-qualifier, exception
   specification, and whether the return type was specified after the
   parameters.  */

static bool
cp_check_qualified_type (const_tree cand, const_tree base, int type_quals,
			 cp_ref_qualifier rqual, tree raises, bool late)
{
  return (TYPE_QUALS (cand) == type_quals
	  && check_base_type (cand, base)
	  && comp_except_specs (raises, TYPE_RAISES_EXCEPTIONS (cand),
				ce_exact)
	  && TYPE_HAS_LATE_RETURN_TYPE (cand) == late
	  && type_memfn_rqual (cand) == rqual);
}

/* Build the FUNCTION_TYPE or METHOD_TYPE with the ref-qualifier RQUAL.  */

tree
build_ref_qualified_type (tree type, cp_ref_qualifier rqual)
{
  tree raises = TYPE_RAISES_EXCEPTIONS (type);
  bool late = TYPE_HAS_LATE_RETURN_TYPE (type);
  return build_cp_fntype_variant (type, rqual, raises, late);
}

tree
make_binding_vec (tree name, unsigned clusters MEM_STAT_DECL)
{
  /* Stored in an unsigned short, but we're limited to the number of
     modules anyway.  */
  gcc_checking_assert (clusters <= (unsigned short)(~0));
  size_t length = (offsetof (tree_binding_vec, vec)
		   + clusters * sizeof (binding_cluster));
  tree vec = ggc_alloc_cleared_tree_node_stat (length PASS_MEM_STAT);
  TREE_SET_CODE (vec, BINDING_VECTOR);
  BINDING_VECTOR_NAME (vec) = name;
  BINDING_VECTOR_ALLOC_CLUSTERS (vec) = clusters;
  BINDING_VECTOR_NUM_CLUSTERS (vec) = 0;

  return vec;
}

/* Make a raw overload node containing FN.  */

tree
ovl_make (tree fn, tree next)
{
  tree result = make_node (OVERLOAD);

  if (TREE_CODE (fn) == OVERLOAD)
    OVL_NESTED_P (result) = true;

  TREE_TYPE (result) = (next || TREE_CODE (fn) == TEMPLATE_DECL
			? unknown_type_node : TREE_TYPE (fn));
  if (next && TREE_CODE (next) == OVERLOAD && OVL_DEDUP_P (next))
    OVL_DEDUP_P (result) = true;
  OVL_FUNCTION (result) = fn;
  OVL_CHAIN (result) = next;
  return result;
}

/* Add FN to the (potentially NULL) overload set OVL.  USING_OR_HIDDEN is >
   zero if this is a using-decl.  It is > 1 if we're exporting the
   using decl.  USING_OR_HIDDEN is < 0, if FN is hidden.  (A decl
   cannot be both using and hidden.)  We keep the hidden decls first,
   but remaining ones are unordered.  */

tree
ovl_insert (tree fn, tree maybe_ovl, int using_or_hidden)
{
  tree result = maybe_ovl;
  tree insert_after = NULL_TREE;

  /* Skip hidden.  */
  for (; maybe_ovl && TREE_CODE (maybe_ovl) == OVERLOAD
	 && OVL_HIDDEN_P (maybe_ovl);
       maybe_ovl = OVL_CHAIN (maybe_ovl))
    {
      gcc_checking_assert (!OVL_LOOKUP_P (maybe_ovl));
      insert_after = maybe_ovl;
    }

  if (maybe_ovl || using_or_hidden || TREE_CODE (fn) == TEMPLATE_DECL)
    {
      maybe_ovl = ovl_make (fn, maybe_ovl);

      if (using_or_hidden < 0)
	OVL_HIDDEN_P (maybe_ovl) = true;
      if (using_or_hidden > 0)
	{
	  OVL_DEDUP_P (maybe_ovl) = OVL_USING_P (maybe_ovl) = true;
	  if (using_or_hidden > 1)
	    OVL_EXPORT_P (maybe_ovl) = true;
	}
    }
  else
    maybe_ovl = fn;

  if (insert_after)
    {
      OVL_CHAIN (insert_after) = maybe_ovl;
      TREE_TYPE (insert_after) = unknown_type_node;
    }
  else
    result = maybe_ovl;

  return result;
}

/* Skip any hidden names at the beginning of OVL.   */

tree
ovl_skip_hidden (tree ovl)
{
  while (ovl && TREE_CODE (ovl) == OVERLOAD && OVL_HIDDEN_P (ovl))
    ovl = OVL_CHAIN (ovl);

  return ovl;
}

/* NODE is an OVL_HIDDEN_P node that is now revealed.  */

tree
ovl_iterator::reveal_node (tree overload, tree node)
{
  /* We cannot have returned NODE as part of a lookup overload, so we
     don't have to worry about preserving that.  */

  OVL_HIDDEN_P (node) = false;
  if (tree chain = OVL_CHAIN (node))
    if (TREE_CODE (chain) == OVERLOAD)
      {
	if (OVL_HIDDEN_P (chain))
	  {
	    /* The node needs moving, and the simplest way is to remove it
	       and reinsert.  */
	    overload = remove_node (overload, node);
	    overload = ovl_insert (OVL_FUNCTION (node), overload);
	  }
	else if (OVL_DEDUP_P (chain))
	  OVL_DEDUP_P (node) = true;
      }
  return overload;
}

/* NODE is on the overloads of OVL.  Remove it.  
   The removed node is unaltered and may continue to be iterated
   from (i.e. it is safe to remove a node from an overload one is
   currently iterating over).  */

tree
ovl_iterator::remove_node (tree overload, tree node)
{
  tree *slot = &overload;
  while (*slot != node)
    {
      tree probe = *slot;
      gcc_checking_assert (!OVL_LOOKUP_P (probe));

      slot = &OVL_CHAIN (probe);
    }

  /* Stitch out NODE.  We don't have to worry about now making a
     singleton overload (and consequently maybe setting its type),
     because all uses of this function will be followed by inserting a
     new node that must follow the place we've cut this out from.  */
  if (TREE_CODE (node) != OVERLOAD)
    /* Cloned inherited ctors don't mark themselves as via_using.  */
    *slot = NULL_TREE;
  else
    *slot = OVL_CHAIN (node);

  return overload;
}

/* Mark or unmark a lookup set. */

void
lookup_mark (tree ovl, bool val)
{
  for (lkp_iterator iter (ovl); iter; ++iter)
    {
      gcc_checking_assert (LOOKUP_SEEN_P (*iter) != val);
      LOOKUP_SEEN_P (*iter) = val;
    }
}

/* Add a set of new FNS into a lookup.  */

tree
lookup_add (tree fns, tree lookup)
{
  if (fns == error_mark_node || lookup == error_mark_node)
    return error_mark_node;

  if (lookup || TREE_CODE (fns) == TEMPLATE_DECL)
    {
      lookup = ovl_make (fns, lookup);
      OVL_LOOKUP_P (lookup) = true;
    }
  else
    lookup = fns;

  return lookup;
}

/* FNS is a new overload set, add them to LOOKUP, if they are not
   already present there.  */

tree
lookup_maybe_add (tree fns, tree lookup, bool deduping)
{
  if (deduping)
    for (tree next, probe = fns; probe; probe = next)
      {
	tree fn = probe;
	next = NULL_TREE;

	if (TREE_CODE (probe) == OVERLOAD)
	  {
	    fn = OVL_FUNCTION (probe);
	    next = OVL_CHAIN (probe);
	  }

	if (!LOOKUP_SEEN_P (fn))
	  LOOKUP_SEEN_P (fn) = true;
	else
	  {
	    /* This function was already seen.  Insert all the
	       predecessors onto the lookup.  */
	    for (; fns != probe; fns = OVL_CHAIN (fns))
	      {
		lookup = lookup_add (OVL_FUNCTION (fns), lookup);
		/* Propagate OVL_USING, but OVL_HIDDEN &
		   OVL_DEDUP_P don't matter.  */
		if (OVL_USING_P (fns))
		  OVL_USING_P (lookup) = true;
	      }

	    /* And now skip this function.  */
	    fns = next;
	  }
      }

  if (fns)
    /* We ended in a set of new functions.  Add them all in one go.  */
    lookup = lookup_add (fns, lookup);

  return lookup;
}

/* Returns nonzero if X is an expression for a (possibly overloaded)
   function.  If "f" is a function or function template, "f", "c->f",
   "c.f", "C::f", and "f<int>" will all be considered possibly
   overloaded functions.  Returns 2 if the function is actually
   overloaded, i.e., if it is impossible to know the type of the
   function without performing overload resolution.  */
 
int
is_overloaded_fn (tree x)
{
  STRIP_ANY_LOCATION_WRAPPER (x);

  /* A baselink is also considered an overloaded function.  */
  if (TREE_CODE (x) == OFFSET_REF
      || TREE_CODE (x) == COMPONENT_REF)
    x = TREE_OPERAND (x, 1);
  x = MAYBE_BASELINK_FUNCTIONS (x);
  if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
    x = TREE_OPERAND (x, 0);

  if (DECL_FUNCTION_TEMPLATE_P (OVL_FIRST (x))
      || (TREE_CODE (x) == OVERLOAD && !OVL_SINGLE_P (x)))
    return 2;

  return OVL_P (x);
}

/* X is the CALL_EXPR_FN of a CALL_EXPR.  If X represents a dependent name
   (14.6.2), return the IDENTIFIER_NODE for that name.  Otherwise, return
   NULL_TREE.  */

tree
dependent_name (tree x)
{
  /* FIXME a dependent name must be unqualified, but this function doesn't
     distinguish between qualified and unqualified identifiers.  */
  if (identifier_p (x))
    return x;
  if (TREE_CODE (x) == TEMPLATE_ID_EXPR)
    x = TREE_OPERAND (x, 0);
  if (OVL_P (x))
    return OVL_NAME (x);
  return NULL_TREE;
}

/* Returns true iff X is an expression for an overloaded function
   whose type cannot be known without performing overload
   resolution.  */

bool
really_overloaded_fn (tree x)
{
  return is_overloaded_fn (x) == 2;
}

/* Get the overload set FROM refers to.  Returns NULL if it's not an
   overload set.  */

tree
maybe_get_fns (tree from)
{
  STRIP_ANY_LOCATION_WRAPPER (from);

  /* A baselink is also considered an overloaded function.  */
  if (TREE_CODE (from) == OFFSET_REF
      || TREE_CODE (from) == COMPONENT_REF)
    from = TREE_OPERAND (from, 1);
  if (BASELINK_P (from))
    from = BASELINK_FUNCTIONS (from);
  if (TREE_CODE (from) == TEMPLATE_ID_EXPR)
    from = TREE_OPERAND (from, 0);

  if (OVL_P (from))
    return from;

  return NULL;
}

/* FROM refers to an overload set.  Return that set (or die).  */

tree
get_fns (tree from)
{
  tree res = maybe_get_fns (from);

  gcc_assert (res);
  return res;
}

/* Return the first function of the overload set FROM refers to.  */

tree
get_first_fn (tree from)
{
  return OVL_FIRST (get_fns (from));
}

/* Return the scope where the overloaded functions OVL were found.  */

tree
ovl_scope (tree ovl)
{
  if (TREE_CODE (ovl) == OFFSET_REF
      || TREE_CODE (ovl) == COMPONENT_REF)
    ovl = TREE_OPERAND (ovl, 1);
  if (TREE_CODE (ovl) == BASELINK)
    return BINFO_TYPE (BASELINK_BINFO (ovl));
  if (TREE_CODE (ovl) == TEMPLATE_ID_EXPR)
    ovl = TREE_OPERAND (ovl, 0);
  /* Skip using-declarations.  */
  lkp_iterator iter (ovl);
  do
    ovl = *iter;
  while (iter.using_p () && ++iter);

  return CP_DECL_CONTEXT (ovl);
}

#define PRINT_RING_SIZE 4

static const char *
cxx_printable_name_internal (tree decl, int v, bool translate)
{
  static unsigned int uid_ring[PRINT_RING_SIZE];
  static char *print_ring[PRINT_RING_SIZE];
  static bool trans_ring[PRINT_RING_SIZE];
  static int ring_counter;
  int i;

  /* Only cache functions.  */
  if (v < 2
      || TREE_CODE (decl) != FUNCTION_DECL
      || DECL_LANG_SPECIFIC (decl) == 0)
    return lang_decl_name (decl, v, translate);

  /* See if this print name is lying around.  */
  for (i = 0; i < PRINT_RING_SIZE; i++)
    if (uid_ring[i] == DECL_UID (decl) && translate == trans_ring[i])
      /* yes, so return it.  */
      return print_ring[i];

  if (++ring_counter == PRINT_RING_SIZE)
    ring_counter = 0;

  if (current_function_decl != NULL_TREE)
    {
      /* There may be both translated and untranslated versions of the
	 name cached.  */
      for (i = 0; i < 2; i++)
	{
	  if (uid_ring[ring_counter] == DECL_UID (current_function_decl))
	    ring_counter += 1;
	  if (ring_counter == PRINT_RING_SIZE)
	    ring_counter = 0;
	}
      gcc_assert (uid_ring[ring_counter] != DECL_UID (current_function_decl));
    }

  free (print_ring[ring_counter]);

  print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v, translate));
  uid_ring[ring_counter] = DECL_UID (decl);
  trans_ring[ring_counter] = translate;
  return print_ring[ring_counter];
}

const char *
cxx_printable_name (tree decl, int v)
{
  return cxx_printable_name_internal (decl, v, false);
}

const char *
cxx_printable_name_translate (tree decl, int v)
{
  return cxx_printable_name_internal (decl, v, true);
}

/* Return the canonical version of exception-specification RAISES for a C++17
   function type, for use in type comparison and building TYPE_CANONICAL.  */

tree
canonical_eh_spec (tree raises)
{
  if (raises == NULL_TREE)
    return raises;
  else if (DEFERRED_NOEXCEPT_SPEC_P (raises)
	   || UNPARSED_NOEXCEPT_SPEC_P (raises)
	   || uses_template_parms (raises)
	   || uses_template_parms (TREE_PURPOSE (raises)))
    /* Keep a dependent or deferred exception specification.  */
    return raises;
  else if (nothrow_spec_p (raises))
    /* throw() -> noexcept.  */
    return noexcept_true_spec;
  else
    /* For C++17 type matching, anything else -> nothing.  */
    return NULL_TREE;
}

tree
build_cp_fntype_variant (tree type, cp_ref_qualifier rqual,
			 tree raises, bool late)
{
  cp_cv_quals type_quals = TYPE_QUALS (type);

  if (cp_check_qualified_type (type, type, type_quals, rqual, raises, late))
    return type;

  tree v = TYPE_MAIN_VARIANT (type);
  for (; v; v = TYPE_NEXT_VARIANT (v))
    if (cp_check_qualified_type (v, type, type_quals, rqual, raises, late))
      return v;

  /* Need to build a new variant.  */
  v = build_variant_type_copy (type);
  if (!TYPE_DEPENDENT_P (v))
    /* We no longer know that it's not type-dependent.  */
    TYPE_DEPENDENT_P_VALID (v) = false;
  TYPE_RAISES_EXCEPTIONS (v) = raises;
  TYPE_HAS_LATE_RETURN_TYPE (v) = late;
  switch (rqual)
    {
    case REF_QUAL_RVALUE:
      FUNCTION_RVALUE_QUALIFIED (v) = 1;
      FUNCTION_REF_QUALIFIED (v) = 1;
      break;
    case REF_QUAL_LVALUE:
      FUNCTION_RVALUE_QUALIFIED (v) = 0;
      FUNCTION_REF_QUALIFIED (v) = 1;
      break;
    default:
      FUNCTION_REF_QUALIFIED (v) = 0;
      break;
    }

  /* Canonicalize the exception specification.  */
  tree cr = flag_noexcept_type ? canonical_eh_spec (raises) : NULL_TREE;

  if (TYPE_STRUCTURAL_EQUALITY_P (type))
    /* Propagate structural equality. */
    SET_TYPE_STRUCTURAL_EQUALITY (v);
  else if (TYPE_CANONICAL (type) != type || cr != raises || late)
    /* Build the underlying canonical type, since it is different
       from TYPE. */
    TYPE_CANONICAL (v) = build_cp_fntype_variant (TYPE_CANONICAL (type),
						  rqual, cr, false);
  else
    /* T is its own canonical type. */
    TYPE_CANONICAL (v) = v;

  return v;
}

/* TYPE is a function or method type with a deferred exception
   specification that has been parsed to RAISES.  Fixup all the type
   variants that are affected in place.  Via decltype &| noexcept
   tricks, the unparsed spec could have escaped into the type system.
   The general case is hard to fixup canonical types for.  */

void
fixup_deferred_exception_variants (tree type, tree raises)
{
  tree original = TYPE_RAISES_EXCEPTIONS (type);
  tree cr = flag_noexcept_type ? canonical_eh_spec (raises) : NULL_TREE;

  gcc_checking_assert (UNPARSED_NOEXCEPT_SPEC_P (original));

  /* Though sucky, this walk will process the canonical variants
     first.  */
  tree prev = NULL_TREE;
  for (tree variant = TYPE_MAIN_VARIANT (type);
       variant; prev = variant, variant = TYPE_NEXT_VARIANT (variant))
    if (TYPE_RAISES_EXCEPTIONS (variant) == original)
      {
	gcc_checking_assert (variant != TYPE_MAIN_VARIANT (type));

	if (!TYPE_STRUCTURAL_EQUALITY_P (variant))
	  {
	    cp_cv_quals var_quals = TYPE_QUALS (variant);
	    cp_ref_qualifier rqual = type_memfn_rqual (variant);

	    /* If VARIANT would become a dup (cp_check_qualified_type-wise)
	       of an existing variant in the variant list of TYPE after its
	       exception specification has been parsed, elide it.  Otherwise,
	       build_cp_fntype_variant could use it, leading to "canonical
	       types differ for identical types."  */
	    tree v = TYPE_MAIN_VARIANT (type);
	    for (; v; v = TYPE_NEXT_VARIANT (v))
	      if (cp_check_qualified_type (v, variant, var_quals,
					   rqual, cr, false))
		{
		  /* The main variant will not match V, so PREV will never
		     be null.  */
		  TYPE_NEXT_VARIANT (prev) = TYPE_NEXT_VARIANT (variant);
		  break;
		}
	    TYPE_RAISES_EXCEPTIONS (variant) = raises;

	    if (!v)
	      v = build_cp_fntype_variant (TYPE_CANONICAL (variant),
					   rqual, cr, false);
	    TYPE_CANONICAL (variant) = TYPE_CANONICAL (v);
	  }
	else
	  TYPE_RAISES_EXCEPTIONS (variant) = raises;

	if (!TYPE_DEPENDENT_P (variant))
	  /* We no longer know that it's not type-dependent.  */
	  TYPE_DEPENDENT_P_VALID (variant) = false;
      }
}

/* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions
   listed in RAISES.  */

tree
build_exception_variant (tree type, tree raises)
{
  cp_ref_qualifier rqual = type_memfn_rqual (type);
  bool late = TYPE_HAS_LATE_RETURN_TYPE (type);
  return build_cp_fntype_variant (type, rqual, raises, late);
}

/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new
   BOUND_TEMPLATE_TEMPLATE_PARM bound with NEWARGS as its template
   arguments.  */

tree
bind_template_template_parm (tree t, tree newargs)
{
  tree decl = TYPE_NAME (t);
  tree t2;

  t2 = cxx_make_type (BOUND_TEMPLATE_TEMPLATE_PARM);
  decl = build_decl (input_location,
		     TYPE_DECL, DECL_NAME (decl), NULL_TREE);
  SET_DECL_TEMPLATE_PARM_P (decl);

  /* These nodes have to be created to reflect new TYPE_DECL and template
     arguments.  */
  TEMPLATE_TYPE_PARM_INDEX (t2) = copy_node (TEMPLATE_TYPE_PARM_INDEX (t));
  TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (t2)) = decl;
  TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)
    = build_template_info (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t), newargs);

  TREE_TYPE (decl) = t2;
  TYPE_NAME (t2) = decl;
  TYPE_STUB_DECL (t2) = decl;
  TYPE_SIZE (t2) = 0;

  if (any_template_arguments_need_structural_equality_p (newargs))
    SET_TYPE_STRUCTURAL_EQUALITY (t2);
  else
    TYPE_CANONICAL (t2) = canonical_type_parameter (t2);

  return t2;
}

/* Called from count_trees via walk_tree.  */

static tree
count_trees_r (tree *tp, int *walk_subtrees, void *data)
{
  ++*((int *) data);

  if (TYPE_P (*tp))
    *walk_subtrees = 0;

  return NULL_TREE;
}

/* Debugging function for measuring the rough complexity of a tree
   representation.  */

int
count_trees (tree t)
{
  int n_trees = 0;
  cp_walk_tree_without_duplicates (&t, count_trees_r, &n_trees);
  return n_trees;
}

/* Called from verify_stmt_tree via walk_tree.  */

static tree
verify_stmt_tree_r (tree* tp, int * /*walk_subtrees*/, void* data)
{
  tree t = *tp;
  hash_table<nofree_ptr_hash <tree_node> > *statements
      = static_cast <hash_table<nofree_ptr_hash <tree_node> > *> (data);
  tree_node **slot;

  if (!STATEMENT_CODE_P (TREE_CODE (t)))
    return NULL_TREE;

  /* If this statement is already present in the hash table, then
     there is a circularity in the statement tree.  */
  gcc_assert (!statements->find (t));

  slot = statements->find_slot (t, INSERT);
  *slot = t;

  return NULL_TREE;
}

/* Debugging function to check that the statement T has not been
   corrupted.  For now, this function simply checks that T contains no
   circularities.  */

void
verify_stmt_tree (tree t)
{
  hash_table<nofree_ptr_hash <tree_node> > statements (37);
  cp_walk_tree (&t, verify_stmt_tree_r, &statements, NULL);
}

/* Check if the type T depends on a type with no linkage and if so,
   return it.  If RELAXED_P then do not consider a class type declared
   within a vague-linkage function to have no linkage.  Remember:
   no-linkage is not the same as internal-linkage.  */

tree
no_linkage_check (tree t, bool relaxed_p)
{
  tree r;

  /* Lambda types that don't have mangling scope have no linkage.  We
     check CLASSTYPE_LAMBDA_EXPR for error_mark_node because
     when we get here from pushtag none of the lambda information is
     set up yet, so we want to assume that the lambda has linkage and
     fix it up later if not.  We need to check this even in templates so
     that we properly handle a lambda-expression in the signature.  */
  if (LAMBDA_TYPE_P (t)
      && CLASSTYPE_LAMBDA_EXPR (t) != error_mark_node)
    {
      tree extra = LAMBDA_TYPE_EXTRA_SCOPE (t);
      if (!extra)
	return t;
    }

  /* Otherwise there's no point in checking linkage on template functions; we
     can't know their complete types.  */
  if (processing_template_decl)
    return NULL_TREE;

  switch (TREE_CODE (t))
    {
    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (t))
	goto ptrmem;
      /* Fall through.  */
    case UNION_TYPE:
      if (!CLASS_TYPE_P (t))
	return NULL_TREE;
      /* Fall through.  */
    case ENUMERAL_TYPE:
      /* Only treat unnamed types as having no linkage if they're at
	 namespace scope.  This is core issue 966.  */
      if (TYPE_UNNAMED_P (t) && TYPE_NAMESPACE_SCOPE_P (t))
	return t;

      for (r = CP_TYPE_CONTEXT (t); ; )
	{
	  /* If we're a nested type of a !TREE_PUBLIC class, we might not
	     have linkage, or we might just be in an anonymous namespace.
	     If we're in a TREE_PUBLIC class, we have linkage.  */
	  if (TYPE_P (r) && !TREE_PUBLIC (TYPE_NAME (r)))
	    return no_linkage_check (TYPE_CONTEXT (t), relaxed_p);
	  else if (TREE_CODE (r) == FUNCTION_DECL)
	    {
	      if (!relaxed_p || !vague_linkage_p (r))
		return t;
	      else
		r = CP_DECL_CONTEXT (r);
	    }
	  else
	    break;
	}

      return NULL_TREE;

    case ARRAY_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case VECTOR_TYPE:
      return no_linkage_check (TREE_TYPE (t), relaxed_p);

    case OFFSET_TYPE:
    ptrmem:
      r = no_linkage_check (TYPE_PTRMEM_POINTED_TO_TYPE (t),
			    relaxed_p);
      if (r)
	return r;
      return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t), relaxed_p);

    case METHOD_TYPE:
    case FUNCTION_TYPE:
      {
	tree parm = TYPE_ARG_TYPES (t);
	if (TREE_CODE (t) == METHOD_TYPE)
	  /* The 'this' pointer isn't interesting; a method has the same
	     linkage (or lack thereof) as its enclosing class.  */
	  parm = TREE_CHAIN (parm);
	for (;
	     parm && parm != void_list_node;
	     parm = TREE_CHAIN (parm))
	  {
	    r = no_linkage_check (TREE_VALUE (parm), relaxed_p);
	    if (r)
	      return r;
	  }
	return no_linkage_check (TREE_TYPE (t), relaxed_p);
      }

    default:
      return NULL_TREE;
    }
}

extern int depth_reached;

void
cxx_print_statistics (void)
{
  print_template_statistics ();
  if (GATHER_STATISTICS)
    fprintf (stderr, "maximum template instantiation depth reached: %d\n",
	     depth_reached);
}

/* Return, as an INTEGER_CST node, the number of elements for TYPE
   (which is an ARRAY_TYPE).  This counts only elements of the top
   array.  */

tree
array_type_nelts_top (tree type)
{
  return fold_build2_loc (input_location,
		      PLUS_EXPR, sizetype,
		      array_type_nelts (type),
		      size_one_node);
}

/* Return, as an INTEGER_CST node, the number of elements for TYPE
   (which is an ARRAY_TYPE).  This one is a recursive count of all
   ARRAY_TYPEs that are clumped together.  */

tree
array_type_nelts_total (tree type)
{
  tree sz = array_type_nelts_top (type);
  type = TREE_TYPE (type);
  while (TREE_CODE (type) == ARRAY_TYPE)
    {
      tree n = array_type_nelts_top (type);
      sz = fold_build2_loc (input_location,
			MULT_EXPR, sizetype, sz, n);
      type = TREE_TYPE (type);
    }
  return sz;
}

/* Return true if FNDECL is std::source_location::current () method.  */

bool
source_location_current_p (tree fndecl)
{
  gcc_checking_assert (TREE_CODE (fndecl) == FUNCTION_DECL
		       && DECL_IMMEDIATE_FUNCTION_P (fndecl));
  if (DECL_NAME (fndecl) == NULL_TREE
      || TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
      || TREE_CODE (TREE_TYPE (TREE_TYPE (fndecl))) != RECORD_TYPE
      || DECL_CONTEXT (fndecl) != TREE_TYPE (TREE_TYPE (fndecl))
      || !id_equal (DECL_NAME (fndecl), "current"))
    return false;

  tree source_location = DECL_CONTEXT (fndecl);
  if (TYPE_NAME (source_location) == NULL_TREE
      || TREE_CODE (TYPE_NAME (source_location)) != TYPE_DECL
      || TYPE_IDENTIFIER (source_location) == NULL_TREE
      || !id_equal (TYPE_IDENTIFIER (source_location),
		    "source_location")
      || !decl_in_std_namespace_p (TYPE_NAME (source_location)))
    return false;

  return true;
}

struct bot_data
{
  splay_tree target_remap;
  bool clear_location;
};

/* Called from break_out_target_exprs via mapcar.  */

static tree
bot_manip (tree* tp, int* walk_subtrees, void* data_)
{
  bot_data &data = *(bot_data*)data_;
  splay_tree target_remap = data.target_remap;
  tree t = *tp;

  if (!TYPE_P (t) && TREE_CONSTANT (t) && !TREE_SIDE_EFFECTS (t))
    {
      /* There can't be any TARGET_EXPRs or their slot variables below this
	 point.  But we must make a copy, in case subsequent processing
	 alters any part of it.  For example, during gimplification a cast
	 of the form (T) &X::f (where "f" is a member function) will lead
	 to replacing the PTRMEM_CST for &X::f with a VAR_DECL.  */
      *walk_subtrees = 0;
      *tp = unshare_expr (t);
      return NULL_TREE;
    }
  if (TREE_CODE (t) == TARGET_EXPR)
    {
      tree u;

      if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
	{
	  u = build_cplus_new (TREE_TYPE (t), TREE_OPERAND (t, 1),
			       tf_warning_or_error);
	  if (u == error_mark_node)
	    return u;
	  if (AGGR_INIT_ZERO_FIRST (TREE_OPERAND (t, 1)))
	    AGGR_INIT_ZERO_FIRST (TREE_OPERAND (u, 1)) = true;
	}
      else
	u = force_target_expr (TREE_TYPE (t), TREE_OPERAND (t, 1),
			       tf_warning_or_error);

      TARGET_EXPR_IMPLICIT_P (u) = TARGET_EXPR_IMPLICIT_P (t);
      TARGET_EXPR_LIST_INIT_P (u) = TARGET_EXPR_LIST_INIT_P (t);
      TARGET_EXPR_DIRECT_INIT_P (u) = TARGET_EXPR_DIRECT_INIT_P (t);

      /* Map the old variable to the new one.  */
      splay_tree_insert (target_remap,
			 (splay_tree_key) TREE_OPERAND (t, 0),
			 (splay_tree_value) TREE_OPERAND (u, 0));

      TREE_OPERAND (u, 1) = break_out_target_exprs (TREE_OPERAND (u, 1),
						    data.clear_location);
      if (TREE_OPERAND (u, 1) == error_mark_node)
	return error_mark_node;

      /* Replace the old expression with the new version.  */
      *tp = u;
      /* We don't have to go below this point; the recursive call to
	 break_out_target_exprs will have handled anything below this
	 point.  */
      *walk_subtrees = 0;
      return NULL_TREE;
    }
  if (TREE_CODE (*tp) == SAVE_EXPR)
    {
      t = *tp;
      splay_tree_node n = splay_tree_lookup (target_remap,
					     (splay_tree_key) t);
      if (n)
	{
	  *tp = (tree)n->value;
	  *walk_subtrees = 0;
	}
      else
	{
	  copy_tree_r (tp, walk_subtrees, NULL);
	  splay_tree_insert (target_remap,
			     (splay_tree_key)t,
			     (splay_tree_value)*tp);
	  /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
	  splay_tree_insert (target_remap,
			     (splay_tree_key)*tp,
			     (splay_tree_value)*tp);
	}
      return NULL_TREE;
    }
  if (TREE_CODE (*tp) == DECL_EXPR
      && VAR_P (DECL_EXPR_DECL (*tp))
      && DECL_ARTIFICIAL (DECL_EXPR_DECL (*tp))
      && !TREE_STATIC (DECL_EXPR_DECL (*tp)))
    {
      tree t;
      splay_tree_node n
	= splay_tree_lookup (target_remap,
			     (splay_tree_key) DECL_EXPR_DECL (*tp));
      if (n)
	t = (tree) n->value;
      else
	{
	  t = create_temporary_var (TREE_TYPE (DECL_EXPR_DECL (*tp)));
	  DECL_INITIAL (t) = DECL_INITIAL (DECL_EXPR_DECL (*tp));
	  splay_tree_insert (target_remap,
			     (splay_tree_key) DECL_EXPR_DECL (*tp),
			     (splay_tree_value) t);
	}
      copy_tree_r (tp, walk_subtrees, NULL);
      DECL_EXPR_DECL (*tp) = t;
      if (data.clear_location && EXPR_HAS_LOCATION (*tp))
	SET_EXPR_LOCATION (*tp, input_location);
      return NULL_TREE;
    }
  if (TREE_CODE (*tp) == BIND_EXPR && BIND_EXPR_VARS (*tp))
    {
      copy_tree_r (tp, walk_subtrees, NULL);
      for (tree *p = &BIND_EXPR_VARS (*tp); *p; p = &DECL_CHAIN (*p))
	{
	  gcc_assert (VAR_P (*p) && DECL_ARTIFICIAL (*p) && !TREE_STATIC (*p));
	  tree t = create_temporary_var (TREE_TYPE (*p));
	  DECL_INITIAL (t) = DECL_INITIAL (*p);
	  DECL_CHAIN (t) = DECL_CHAIN (*p);
	  splay_tree_insert (target_remap, (splay_tree_key) *p,
			     (splay_tree_value) t);
	  *p = t;
	}
      if (data.clear_location && EXPR_HAS_LOCATION (*tp))
	SET_EXPR_LOCATION (*tp, input_location);
      return NULL_TREE;
    }

  /* Make a copy of this node.  */
  t = copy_tree_r (tp, walk_subtrees, NULL);
  if (TREE_CODE (*tp) == CALL_EXPR || TREE_CODE (*tp) == AGGR_INIT_EXPR)
    if (!processing_template_decl)
      set_flags_from_callee (*tp);
  if (data.clear_location && EXPR_HAS_LOCATION (*tp))
    SET_EXPR_LOCATION (*tp, input_location);
  return t;
}

/* Replace all remapped VAR_DECLs in T with their new equivalents.
   DATA is really a splay-tree mapping old variables to new
   variables.  */

static tree
bot_replace (tree* t, int* /*walk_subtrees*/, void* data_)
{
  bot_data &data = *(bot_data*)data_;
  splay_tree target_remap = data.target_remap;

  if (VAR_P (*t))
    {
      splay_tree_node n = splay_tree_lookup (target_remap,
					     (splay_tree_key) *t);
      if (n)
	*t = (tree) n->value;
    }
  else if (TREE_CODE (*t) == PARM_DECL
	   && DECL_NAME (*t) == this_identifier
	   && !DECL_CONTEXT (*t))
    {
      /* In an NSDMI we need to replace the 'this' parameter we used for
	 parsing with the real one for this function.  */
      *t = current_class_ptr;
    }
  else if (TREE_CODE (*t) == CONVERT_EXPR
	   && CONVERT_EXPR_VBASE_PATH (*t))
    {
      /* In an NSDMI build_base_path defers building conversions to morally
	 virtual bases, and we handle it here.  */
      tree basetype = TREE_TYPE (*t);
      *t = convert_to_base (TREE_OPERAND (*t, 0), basetype,
			    /*check_access=*/false, /*nonnull=*/true,
			    tf_warning_or_error);
    }

  return NULL_TREE;
}

/* When we parse a default argument expression, we may create
   temporary variables via TARGET_EXPRs.  When we actually use the
   default-argument expression, we make a copy of the expression
   and replace the temporaries with appropriate local versions.

   If CLEAR_LOCATION is true, override any EXPR_LOCATION with
   input_location.  */

tree
break_out_target_exprs (tree t, bool clear_location /* = false */)
{
  static int target_remap_count;
  static splay_tree target_remap;

  if (!target_remap_count++)
    target_remap = splay_tree_new (splay_tree_compare_pointers,
				   /*splay_tree_delete_key_fn=*/NULL,
				   /*splay_tree_delete_value_fn=*/NULL);
  bot_data data = { target_remap, clear_location };
  if (cp_walk_tree (&t, bot_manip, &data, NULL) == error_mark_node)
    t = error_mark_node;
  cp_walk_tree (&t, bot_replace, &data, NULL);

  if (!--target_remap_count)
    {
      splay_tree_delete (target_remap);
      target_remap = NULL;
    }

  return t;
}

/* Build an expression for the subobject of OBJ at CONSTRUCTOR index INDEX,
   which we expect to have type TYPE.  */

tree
build_ctor_subob_ref (tree index, tree type, tree obj)
{
  if (index == NULL_TREE)
    /* Can't refer to a particular member of a vector.  */
    obj = NULL_TREE;
  else if (TREE_CODE (index) == INTEGER_CST)
    obj = cp_build_array_ref (input_location, obj, index, tf_none);
  else
    obj = build_class_member_access_expr (obj, index, NULL_TREE,
					  /*reference*/false, tf_none);
  if (obj)
    {
      tree objtype = TREE_TYPE (obj);
      if (TREE_CODE (objtype) == ARRAY_TYPE && !TYPE_DOMAIN (objtype))
	{
	  /* When the destination object refers to a flexible array member
	     verify that it matches the type of the source object except
	     for its domain and qualifiers.  */
	  gcc_assert (comptypes (TYPE_MAIN_VARIANT (type),
	  			 TYPE_MAIN_VARIANT (objtype),
	  			 COMPARE_REDECLARATION));
	}
      else
	gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, objtype));
    }

  return obj;
}

struct replace_placeholders_t
{
  tree obj;	    /* The object to be substituted for a PLACEHOLDER_EXPR.  */
  tree exp;	    /* The outermost exp.  */
  bool seen;	    /* Whether we've encountered a PLACEHOLDER_EXPR.  */
  hash_set<tree> *pset;	/* To avoid walking same trees multiple times.  */
};

/* Like substitute_placeholder_in_expr, but handle C++ tree codes and
   build up subexpressions as we go deeper.  */

static tree
replace_placeholders_r (tree* t, int* walk_subtrees, void* data_)
{
  replace_placeholders_t *d = static_cast<replace_placeholders_t*>(data_);
  tree obj = d->obj;

  if (TYPE_P (*t) || TREE_CONSTANT (*t))
    {
      *walk_subtrees = false;
      return NULL_TREE;
    }

  switch (TREE_CODE (*t))
    {
    case PLACEHOLDER_EXPR:
      {
	tree x = obj;
	for (; !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (*t),
							   TREE_TYPE (x));
	     x = TREE_OPERAND (x, 0))
	  gcc_assert (handled_component_p (x));
	*t = unshare_expr (x);
	*walk_subtrees = false;
	d->seen = true;
      }
      break;

    case CONSTRUCTOR:
      {
	constructor_elt *ce;
	vec<constructor_elt,va_gc> *v = CONSTRUCTOR_ELTS (*t);
	/* Don't walk into CONSTRUCTOR_PLACEHOLDER_BOUNDARY ctors
	   other than the d->exp one, those have PLACEHOLDER_EXPRs
	   related to another object.  */
	if ((CONSTRUCTOR_PLACEHOLDER_BOUNDARY (*t)
	     && *t != d->exp)
	    || d->pset->add (*t))
	  {
	    *walk_subtrees = false;
	    return NULL_TREE;
	  }
	for (unsigned i = 0; vec_safe_iterate (v, i, &ce); ++i)
	  {
	    tree *valp = &ce->value;
	    tree type = TREE_TYPE (*valp);
	    tree subob = obj;

	    /* Elements with RANGE_EXPR index shouldn't have any
	       placeholders in them.  */
	    if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
	      continue;

	    if (TREE_CODE (*valp) == CONSTRUCTOR
		&& AGGREGATE_TYPE_P (type))
	      {
		/* If we're looking at the initializer for OBJ, then build
		   a sub-object reference.  If we're looking at an
		   initializer for another object, just pass OBJ down.  */
		if (same_type_ignoring_top_level_qualifiers_p
		    (TREE_TYPE (*t), TREE_TYPE (obj)))
		  subob = build_ctor_subob_ref (ce->index, type, obj);
		if (TREE_CODE (*valp) == TARGET_EXPR)
		  valp = &TARGET_EXPR_INITIAL (*valp);
	      }
	    d->obj = subob;
	    cp_walk_tree (valp, replace_placeholders_r, data_, NULL);
	    d->obj = obj;
	  }
	*walk_subtrees = false;
	break;
      }

    default:
      if (d->pset->add (*t))
	*walk_subtrees = false;
      break;
    }

  return NULL_TREE;
}

/* Replace PLACEHOLDER_EXPRs in EXP with object OBJ.  SEEN_P is set if
   a PLACEHOLDER_EXPR has been encountered.  */

tree
replace_placeholders (tree exp, tree obj, bool *seen_p /*= NULL*/)
{
  /* This is only relevant for C++14.  */
  if (cxx_dialect < cxx14)
    return exp;

  /* If the object isn't a (member of a) class, do nothing.  */
  tree op0 = obj;
  while (handled_component_p (op0))
    op0 = TREE_OPERAND (op0, 0);
  if (!CLASS_TYPE_P (strip_array_types (TREE_TYPE (op0))))
    return exp;

  tree *tp = &exp;
  if (TREE_CODE (exp) == TARGET_EXPR)
    tp = &TARGET_EXPR_INITIAL (exp);
  hash_set<tree> pset;
  replace_placeholders_t data = { obj, *tp, false, &pset };
  cp_walk_tree (tp, replace_placeholders_r, &data, NULL);
  if (seen_p)
    *seen_p = data.seen;
  return exp;
}

/* Callback function for find_placeholders.  */

static tree
find_placeholders_r (tree *t, int *walk_subtrees, void *)
{
  if (TYPE_P (*t) || TREE_CONSTANT (*t))
    {
      *walk_subtrees = false;
      return NULL_TREE;
    }

  switch (TREE_CODE (*t))
    {
    case PLACEHOLDER_EXPR:
      return *t;

    case CONSTRUCTOR:
      if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (*t))
	*walk_subtrees = false;
      break;

    default:
      break;
    }

  return NULL_TREE;
}

/* Return true if EXP contains a PLACEHOLDER_EXPR.  Don't walk into
   ctors with CONSTRUCTOR_PLACEHOLDER_BOUNDARY flag set.  */

bool
find_placeholders (tree exp)
{
  /* This is only relevant for C++14.  */
  if (cxx_dialect < cxx14)
    return false;

  return cp_walk_tree_without_duplicates (&exp, find_placeholders_r, NULL);
}

/* Similar to `build_nt', but for template definitions of dependent
   expressions  */

tree
build_min_nt_loc (location_t loc, enum tree_code code, ...)
{
  tree t;
  int length;
  int i;
  va_list p;

  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);

  va_start (p, code);

  t = make_node (code);
  SET_EXPR_LOCATION (t, loc);
  length = TREE_CODE_LENGTH (code);

  for (i = 0; i < length; i++)
    TREE_OPERAND (t, i) = va_arg (p, tree);

  va_end (p);
  return t;
}

/* Similar to `build', but for template definitions.  */

tree
build_min (enum tree_code code, tree tt, ...)
{
  tree t;
  int length;
  int i;
  va_list p;

  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);

  va_start (p, tt);

  t = make_node (code);
  length = TREE_CODE_LENGTH (code);
  TREE_TYPE (t) = tt;

  for (i = 0; i < length; i++)
    {
      tree x = va_arg (p, tree);
      TREE_OPERAND (t, i) = x;
      if (x && !TYPE_P (x) && TREE_SIDE_EFFECTS (x))
	TREE_SIDE_EFFECTS (t) = 1;
    }

  va_end (p);

  return t;
}

/* Similar to `build', but for template definitions of non-dependent
   expressions. NON_DEP is the non-dependent expression that has been
   built.  */

tree
build_min_non_dep (enum tree_code code, tree non_dep, ...)
{
  tree t;
  int length;
  int i;
  va_list p;

  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);

  va_start (p, non_dep);

  if (REFERENCE_REF_P (non_dep))
    non_dep = TREE_OPERAND (non_dep, 0);

  t = make_node (code);
  SET_EXPR_LOCATION (t, cp_expr_loc_or_input_loc (non_dep));
  length = TREE_CODE_LENGTH (code);
  TREE_TYPE (t) = unlowered_expr_type (non_dep);
  TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);

  for (i = 0; i < length; i++)
    TREE_OPERAND (t, i) = va_arg (p, tree);

  va_end (p);
  return convert_from_reference (t);
}

/* Similar to build_min_nt, but call expressions  */

tree
build_min_nt_call_vec (tree fn, vec<tree, va_gc> *args)
{
  tree ret, t;
  unsigned int ix;

  ret = build_vl_exp (CALL_EXPR, vec_safe_length (args) + 3);
  CALL_EXPR_FN (ret) = fn;
  CALL_EXPR_STATIC_CHAIN (ret) = NULL_TREE;
  FOR_EACH_VEC_SAFE_ELT (args, ix, t)
    CALL_EXPR_ARG (ret, ix) = t;

  return ret;
}

/* Similar to `build_min_nt_call_vec', but for template definitions of
   non-dependent expressions. NON_DEP is the non-dependent expression
   that has been built.  */

tree
build_min_non_dep_call_vec (tree non_dep, tree fn, vec<tree, va_gc> *argvec)
{
  tree t = build_min_nt_call_vec (fn, argvec);
  if (REFERENCE_REF_P (non_dep))
    non_dep = TREE_OPERAND (non_dep, 0);
  TREE_TYPE (t) = TREE_TYPE (non_dep);
  TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (non_dep);
  return convert_from_reference (t);
}

/* Similar to build_min_non_dep, but for expressions that have been resolved to
   a call to an operator overload.  OP is the operator that has been
   overloaded.  NON_DEP is the non-dependent expression that's been built,
   which should be a CALL_EXPR or an INDIRECT_REF to a CALL_EXPR.  OVERLOAD is
   the overload that NON_DEP is calling.  */

tree
build_min_non_dep_op_overload (enum tree_code op,
			       tree non_dep,
			       tree overload, ...)
{
  va_list p;
  int nargs, expected_nargs;
  tree fn, call;

  non_dep = extract_call_expr (non_dep);

  nargs = call_expr_nargs (non_dep);

  expected_nargs = cp_tree_code_length (op);
  if (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE)
    expected_nargs -= 1;
  if ((op == POSTINCREMENT_EXPR
       || op == POSTDECREMENT_EXPR)
      /* With -fpermissive non_dep could be operator++().  */
      && (!flag_permissive || nargs != expected_nargs))
    expected_nargs += 1;
  gcc_assert (nargs == expected_nargs);

  releasing_vec args;
  va_start (p, overload);

  if (TREE_CODE (TREE_TYPE (overload)) == FUNCTION_TYPE)
    {
      fn = overload;
      for (int i = 0; i < nargs; i++)
	{
	  tree arg = va_arg (p, tree);
	  vec_safe_push (args, arg);
	}
    }
  else if (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE)
    {
      tree object = va_arg (p, tree);
      tree binfo = TYPE_BINFO (TREE_TYPE (object));
      tree method = build_baselink (binfo, binfo, overload, NULL_TREE);
      fn = build_min (COMPONENT_REF, TREE_TYPE (overload),
		      object, method, NULL_TREE);
      for (int i = 0; i < nargs; i++)
	{
	  tree arg = va_arg (p, tree);
	  vec_safe_push (args, arg);
	}
    }
  else
    gcc_unreachable ();

  va_end (p);
  call = build_min_non_dep_call_vec (non_dep, fn, args);

  tree call_expr = extract_call_expr (call);
  KOENIG_LOOKUP_P (call_expr) = KOENIG_LOOKUP_P (non_dep);
  CALL_EXPR_OPERATOR_SYNTAX (call_expr) = true;
  CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (non_dep);
  CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (non_dep);

  return call;
}

/* Similar to above build_min_non_dep_op_overload, but arguments
   are taken from ARGS vector.  */

tree
build_min_non_dep_op_overload (tree non_dep, tree overload, tree object,
			       vec<tree, va_gc> *args)
{
  non_dep = extract_call_expr (non_dep);

  unsigned int nargs = call_expr_nargs (non_dep);
  gcc_assert (TREE_CODE (TREE_TYPE (overload)) == METHOD_TYPE);
  tree binfo = TYPE_BINFO (TREE_TYPE (object));
  tree method = build_baselink (binfo, binfo, overload, NULL_TREE);
  tree fn = build_min (COMPONENT_REF, TREE_TYPE (overload),
		       object, method, NULL_TREE);
  gcc_assert (vec_safe_length (args) == nargs);

  tree call = build_min_non_dep_call_vec (non_dep, fn, args);

  tree call_expr = extract_call_expr (call);
  KOENIG_LOOKUP_P (call_expr) = KOENIG_LOOKUP_P (non_dep);
  CALL_EXPR_OPERATOR_SYNTAX (call_expr) = true;
  CALL_EXPR_ORDERED_ARGS (call_expr) = CALL_EXPR_ORDERED_ARGS (non_dep);
  CALL_EXPR_REVERSE_ARGS (call_expr) = CALL_EXPR_REVERSE_ARGS (non_dep);

  return call;
}

/* Return a new tree vec copied from VEC, with ELT inserted at index IDX.  */

vec<tree, va_gc> *
vec_copy_and_insert (vec<tree, va_gc> *old_vec, tree elt, unsigned idx)
{
  unsigned len = vec_safe_length (old_vec);
  gcc_assert (idx <= len);

  vec<tree, va_gc> *new_vec = NULL;
  vec_alloc (new_vec, len + 1);

  unsigned i;
  for (i = 0; i < len; ++i)
    {
      if (i == idx)
	new_vec->quick_push (elt);
      new_vec->quick_push ((*old_vec)[i]);
    }
  if (i == idx)
    new_vec->quick_push (elt);

  return new_vec;
}

tree
get_type_decl (tree t)
{
  if (TREE_CODE (t) == TYPE_DECL)
    return t;
  if (TYPE_P (t))
    return TYPE_STUB_DECL (t);
  gcc_assert (t == error_mark_node);
  return t;
}

/* Returns the namespace that contains DECL, whether directly or
   indirectly.  */

tree
decl_namespace_context (tree decl)
{
  while (1)
    {
      if (TREE_CODE (decl) == NAMESPACE_DECL)
	return decl;
      else if (TYPE_P (decl))
	decl = CP_DECL_CONTEXT (TYPE_MAIN_DECL (decl));
      else
	decl = CP_DECL_CONTEXT (decl);
    }
}

/* Returns true if decl is within an anonymous namespace, however deeply
   nested, or false otherwise.  */

bool
decl_anon_ns_mem_p (tree decl)
{
  return !TREE_PUBLIC (decl_namespace_context (decl));
}

/* Returns true if the enclosing scope of DECL has internal or no linkage.  */

bool
decl_internal_context_p (const_tree decl)
{
  while (TREE_CODE (decl) != NAMESPACE_DECL)
    {
      /* Classes inside anonymous namespaces have TREE_PUBLIC == 0.  */
      if (TYPE_P (decl))
	return !TREE_PUBLIC (TYPE_MAIN_DECL (decl));

      decl = CP_DECL_CONTEXT (decl);
    }
  return !TREE_PUBLIC (decl);
}

/* Subroutine of cp_tree_equal: t1 and t2 are the CALL_EXPR_FNs of two
   CALL_EXPRS.  Return whether they are equivalent.  */

static bool
called_fns_equal (tree t1, tree t2)
{
  /* Core 1321: dependent names are equivalent even if the overload sets
     are different.  But do compare explicit template arguments.  */
  tree name1 = dependent_name (t1);
  tree name2 = dependent_name (t2);
  if (name1 || name2)
    {
      tree targs1 = NULL_TREE, targs2 = NULL_TREE;

      if (name1 != name2)
	return false;

      /* FIXME dependent_name currently returns an unqualified name regardless
	 of whether the function was named with a qualified- or unqualified-id.
	 Until that's fixed, check that we aren't looking at overload sets from
	 different scopes.  */
      if (is_overloaded_fn (t1) && is_overloaded_fn (t2)
	  && (DECL_CONTEXT (get_first_fn (t1))
	      != DECL_CONTEXT (get_first_fn (t2))))
	return false;

      if (TREE_CODE (t1) == TEMPLATE_ID_EXPR)
	targs1 = TREE_OPERAND (t1, 1);
      if (TREE_CODE (t2) == TEMPLATE_ID_EXPR)
	targs2 = TREE_OPERAND (t2, 1);
      return cp_tree_equal (targs1, targs2);
    }
  else
    return cp_tree_equal (t1, t2);
}

/* Return truthvalue of whether T1 is the same tree structure as T2.
   Return 1 if they are the same. Return 0 if they are different.  */

bool
cp_tree_equal (tree t1, tree t2)
{
  enum tree_code code1, code2;

  if (t1 == t2)
    return true;
  if (!t1 || !t2)
    return false;

  code1 = TREE_CODE (t1);
  code2 = TREE_CODE (t2);

  if (code1 != code2)
    return false;

  if (CONSTANT_CLASS_P (t1)
      && !same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    return false;

  switch (code1)
    {
    case VOID_CST:
      /* There's only a single VOID_CST node, so we should never reach
	 here.  */
      gcc_unreachable ();

    case INTEGER_CST:
      return tree_int_cst_equal (t1, t2);

    case REAL_CST:
      return real_identical (&TREE_REAL_CST (t1), &TREE_REAL_CST (t2));

    case STRING_CST:
      return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
	&& !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
		    TREE_STRING_LENGTH (t1));

    case FIXED_CST:
      return FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
				     TREE_FIXED_CST (t2));

    case COMPLEX_CST:
      return cp_tree_equal (TREE_REALPART (t1), TREE_REALPART (t2))
	&& cp_tree_equal (TREE_IMAGPART (t1), TREE_IMAGPART (t2));

    case VECTOR_CST:
      return operand_equal_p (t1, t2, OEP_ONLY_CONST);

    case CONSTRUCTOR:
      /* We need to do this when determining whether or not two
	 non-type pointer to member function template arguments
	 are the same.  */
      if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
	  || CONSTRUCTOR_NELTS (t1) != CONSTRUCTOR_NELTS (t2))
	return false;
      {
	tree field, value;
	unsigned int i;
	FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t1), i, field, value)
	  {
	    constructor_elt *elt2 = CONSTRUCTOR_ELT (t2, i);
	    if (!cp_tree_equal (field, elt2->index)
		|| !cp_tree_equal (value, elt2->value))
	      return false;
	  }
      }
      return true;

    case TREE_LIST:
      if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)))
	return false;
      if (!cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
	return false;
      return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));

    case SAVE_EXPR:
      return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));

    case CALL_EXPR:
      {
	if (KOENIG_LOOKUP_P (t1) != KOENIG_LOOKUP_P (t2))
	  return false;

	if (!called_fns_equal (CALL_EXPR_FN (t1), CALL_EXPR_FN (t2)))
	  return false;

	call_expr_arg_iterator iter1, iter2;
	init_call_expr_arg_iterator (t1, &iter1);
	init_call_expr_arg_iterator (t2, &iter2);
	if (iter1.n != iter2.n)
	  return false;

	while (more_call_expr_args_p (&iter1))
	  {
	    tree arg1 = next_call_expr_arg (&iter1);
	    tree arg2 = next_call_expr_arg (&iter2);

	    gcc_checking_assert (arg1 && arg2);
	    if (!cp_tree_equal (arg1, arg2))
	      return false;
	  }

	return true;
      }

    case TARGET_EXPR:
      {
	tree o1 = TREE_OPERAND (t1, 0);
	tree o2 = TREE_OPERAND (t2, 0);

	/* Special case: if either target is an unallocated VAR_DECL,
	   it means that it's going to be unified with whatever the
	   TARGET_EXPR is really supposed to initialize, so treat it
	   as being equivalent to anything.  */
	if (VAR_P (o1) && DECL_NAME (o1) == NULL_TREE
	    && !DECL_RTL_SET_P (o1))
	  /*Nop*/;
	else if (VAR_P (o2) && DECL_NAME (o2) == NULL_TREE
		 && !DECL_RTL_SET_P (o2))
	  /*Nop*/;
	else if (!cp_tree_equal (o1, o2))
	  return false;

	return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
      }

    case PARM_DECL:
      /* For comparing uses of parameters in late-specified return types
	 with an out-of-class definition of the function, but can also come
	 up for expressions that involve 'this' in a member function
	 template.  */

      if (comparing_specializations
	  && DECL_CONTEXT (t1) != DECL_CONTEXT (t2))
	/* When comparing hash table entries, only an exact match is
	   good enough; we don't want to replace 'this' with the
	   version from another function.  But be more flexible
	   with parameters with identical contexts.  */
	return false;

      if (same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	{
	  if (DECL_ARTIFICIAL (t1) ^ DECL_ARTIFICIAL (t2))
	    return false;
	  if (CONSTRAINT_VAR_P (t1) ^ CONSTRAINT_VAR_P (t2))
	    return false;
	  if (DECL_ARTIFICIAL (t1)
	      || (DECL_PARM_LEVEL (t1) == DECL_PARM_LEVEL (t2)
		  && DECL_PARM_INDEX (t1) == DECL_PARM_INDEX (t2)))
	    return true;
	}
      return false;

    case VAR_DECL:
    case CONST_DECL:
    case FIELD_DECL:
    case FUNCTION_DECL:
    case TEMPLATE_DECL:
    case IDENTIFIER_NODE:
    case SSA_NAME:
    case USING_DECL:
    case DEFERRED_PARSE:
      return false;

    case BASELINK:
      return (BASELINK_BINFO (t1) == BASELINK_BINFO (t2)
	      && BASELINK_ACCESS_BINFO (t1) == BASELINK_ACCESS_BINFO (t2)
	      && BASELINK_QUALIFIED_P (t1) == BASELINK_QUALIFIED_P (t2)
	      && cp_tree_equal (BASELINK_FUNCTIONS (t1),
				BASELINK_FUNCTIONS (t2)));

    case TEMPLATE_PARM_INDEX:
      return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
	      && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2)
	      && (TEMPLATE_PARM_PARAMETER_PACK (t1)
		  == TEMPLATE_PARM_PARAMETER_PACK (t2))
	      && same_type_p (TREE_TYPE (TEMPLATE_PARM_DECL (t1)),
			      TREE_TYPE (TEMPLATE_PARM_DECL (t2))));

    case TEMPLATE_ID_EXPR:
      if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
	return false;
      if (!comp_template_args (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)))
	return false;
      return true;

    case CONSTRAINT_INFO:
      return cp_tree_equal (CI_ASSOCIATED_CONSTRAINTS (t1),
                            CI_ASSOCIATED_CONSTRAINTS (t2));

    case CHECK_CONSTR:
      return (CHECK_CONSTR_CONCEPT (t1) == CHECK_CONSTR_CONCEPT (t2)
              && comp_template_args (CHECK_CONSTR_ARGS (t1),
				     CHECK_CONSTR_ARGS (t2)));

    case TREE_VEC:
      /* These are template args.  Really we should be getting the
	 caller to do this as it knows it to be true.  */
      if (!comp_template_args (t1, t2, NULL, NULL, false))
	return false;
      return true;

    case SIZEOF_EXPR:
    case ALIGNOF_EXPR:
      {
	tree o1 = TREE_OPERAND (t1, 0);
	tree o2 = TREE_OPERAND (t2, 0);

	if (code1 == SIZEOF_EXPR)
	  {
	    if (SIZEOF_EXPR_TYPE_P (t1))
	      o1 = TREE_TYPE (o1);
	    if (SIZEOF_EXPR_TYPE_P (t2))
	      o2 = TREE_TYPE (o2);
	  }
	else if (ALIGNOF_EXPR_STD_P (t1) != ALIGNOF_EXPR_STD_P (t2))
	  return false;

	if (TREE_CODE (o1) != TREE_CODE (o2))
	  return false;

	if (ARGUMENT_PACK_P (o1))
	  return template_args_equal (o1, o2);
	else if (TYPE_P (o1))
	  return same_type_p (o1, o2);
	else
	  return cp_tree_equal (o1, o2);
      }

    case MODOP_EXPR:
      {
	tree t1_op1, t2_op1;

	if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
	  return false;

	t1_op1 = TREE_OPERAND (t1, 1);
	t2_op1 = TREE_OPERAND (t2, 1);
	if (TREE_CODE (t1_op1) != TREE_CODE (t2_op1))
	  return false;

	return cp_tree_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t2, 2));
      }

    case PTRMEM_CST:
      /* Two pointer-to-members are the same if they point to the same
	 field or function in the same class.  */
      if (PTRMEM_CST_MEMBER (t1) != PTRMEM_CST_MEMBER (t2))
	return false;

      return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));

    case OVERLOAD:
      {
	/* Two overloads. Must be exactly the same set of decls.  */
	lkp_iterator first (t1);
	lkp_iterator second (t2);

	for (; first && second; ++first, ++second)
	  if (*first != *second)
	    return false;
	return !(first || second);
      }

    case TRAIT_EXPR:
      if (TRAIT_EXPR_KIND (t1) != TRAIT_EXPR_KIND (t2))
	return false;
      return same_type_p (TRAIT_EXPR_TYPE1 (t1), TRAIT_EXPR_TYPE1 (t2))
	&& cp_tree_equal (TRAIT_EXPR_TYPE2 (t1), TRAIT_EXPR_TYPE2 (t2));

    case NON_LVALUE_EXPR:
    case VIEW_CONVERT_EXPR:
      /* Used for location wrappers with possibly NULL types.  */
      if (!TREE_TYPE (t1) || !TREE_TYPE (t2))
	{
	  if (TREE_TYPE (t1) || TREE_TYPE (t2))
	    return false;
	  break;
	}
      /* FALLTHROUGH  */

    case CAST_EXPR:
    case STATIC_CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case CONST_CAST_EXPR:
    case DYNAMIC_CAST_EXPR:
    case IMPLICIT_CONV_EXPR:
    case NEW_EXPR:
    case BIT_CAST_EXPR:
    CASE_CONVERT:
      if (!same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)))
	return false;
      /* Now compare operands as usual.  */
      break;

    case DEFERRED_NOEXCEPT:
      return (cp_tree_equal (DEFERRED_NOEXCEPT_PATTERN (t1),
			     DEFERRED_NOEXCEPT_PATTERN (t2))
	      && comp_template_args (DEFERRED_NOEXCEPT_ARGS (t1),
				     DEFERRED_NOEXCEPT_ARGS (t2)));

    case LAMBDA_EXPR:
      /* Two lambda-expressions are never considered equivalent.  */
      return false;

    case TYPE_ARGUMENT_PACK:
    case NONTYPE_ARGUMENT_PACK:
      {
	tree p1 = ARGUMENT_PACK_ARGS (t1);
	tree p2 = ARGUMENT_PACK_ARGS (t2);
	int len = TREE_VEC_LENGTH (p1);
	if (TREE_VEC_LENGTH (p2) != len)
	  return false;

	for (int ix = 0; ix != len; ix++)
	  if (!template_args_equal (TREE_VEC_ELT (p1, ix),
				    TREE_VEC_ELT (p2, ix)))
	    return false;
	return true;
      }

    case EXPR_PACK_EXPANSION:
      if (!cp_tree_equal (PACK_EXPANSION_PATTERN (t1),
			  PACK_EXPANSION_PATTERN (t2)))
	return false;
      if (!comp_template_args (PACK_EXPANSION_EXTRA_ARGS (t1),
			       PACK_EXPANSION_EXTRA_ARGS (t2)))
	return false;
      return true;

    default:
      break;
    }

  switch (TREE_CODE_CLASS (code1))
    {
    case tcc_unary:
    case tcc_binary:
    case tcc_comparison:
    case tcc_expression:
    case tcc_vl_exp:
    case tcc_reference:
    case tcc_statement:
      {
	int n = cp_tree_operand_length (t1);
	if (TREE_CODE_CLASS (code1) == tcc_vl_exp
	    && n != TREE_OPERAND_LENGTH (t2))
	  return false;

	for (int i = 0; i < n; ++i)
	  if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
	    return false;

	return true;
      }

    case tcc_type:
      return same_type_p (t1, t2);

    default:
      gcc_unreachable ();
    }

  /* We can get here with --disable-checking.  */
  return false;
}

/* The type of ARG when used as an lvalue.  */

tree
lvalue_type (tree arg)
{
  tree type = TREE_TYPE (arg);
  return type;
}

/* The type of ARG for printing error messages; denote lvalues with
   reference types.  */

tree
error_type (tree arg)
{
  tree type = TREE_TYPE (arg);

  if (TREE_CODE (type) == ARRAY_TYPE)
    ;
  else if (TREE_CODE (type) == ERROR_MARK)
    ;
  else if (lvalue_p (arg))
    type = build_reference_type (lvalue_type (arg));
  else if (MAYBE_CLASS_TYPE_P (type))
    type = lvalue_type (arg);

  return type;
}

/* Does FUNCTION use a variable-length argument list?  */

int
varargs_function_p (const_tree function)
{
  return stdarg_p (TREE_TYPE (function));
}

/* Returns 1 if decl is a member of a class.  */

int
member_p (const_tree decl)
{
  const_tree const ctx = DECL_CONTEXT (decl);
  return (ctx && TYPE_P (ctx));
}

/* Create a placeholder for member access where we don't actually have an
   object that the access is against.  For a general declval<T> equivalent,
   use build_stub_object instead.  */

tree
build_dummy_object (tree type)
{
  tree decl = build1 (CONVERT_EXPR, build_pointer_type (type), void_node);
  return cp_build_fold_indirect_ref (decl);
}

/* We've gotten a reference to a member of TYPE.  Return *this if appropriate,
   or a dummy object otherwise.  If BINFOP is non-0, it is filled with the
   binfo path from current_class_type to TYPE, or 0.  */

tree
maybe_dummy_object (tree type, tree* binfop)
{
  tree decl, context;
  tree binfo;
  tree current = current_nonlambda_class_type ();

  if (current
      && (binfo = lookup_base (current, type, ba_any, NULL,
			       tf_warning_or_error)))
    context = current;
  else
    {
      /* Reference from a nested class member function.  */
      context = type;
      binfo = TYPE_BINFO (type);
    }

  if (binfop)
    *binfop = binfo;

  /* current_class_ref might not correspond to current_class_type if
     we're in tsubst_default_argument or a lambda-declarator; in either
     case, we want to use current_class_ref if it matches CONTEXT.  */
  tree ctype = current_class_ref ? TREE_TYPE (current_class_ref) : NULL_TREE;
  if (ctype
      && same_type_ignoring_top_level_qualifiers_p (ctype, context))
    decl = current_class_ref;
  else
    {
      /* Return a dummy object whose cv-quals are consistent with (the
	 non-lambda) 'this' if available.  */
      if (ctype)
	{
	  int quals = TYPE_UNQUALIFIED;
	  if (tree lambda = CLASSTYPE_LAMBDA_EXPR (ctype))
	    {
	      if (tree cap = lambda_expr_this_capture (lambda, false))
		quals = cp_type_quals (TREE_TYPE (TREE_TYPE (cap)));
	    }
	  else
	    quals = cp_type_quals (ctype);
	  context = cp_build_qualified_type (context, quals);
	}
      decl = build_dummy_object (context);
    }

  return decl;
}

/* Returns 1 if OB is a placeholder object, or a pointer to one.  */

bool
is_dummy_object (const_tree ob)
{
  if (INDIRECT_REF_P (ob))
    ob = TREE_OPERAND (ob, 0);
  return (TREE_CODE (ob) == CONVERT_EXPR
	  && TREE_OPERAND (ob, 0) == void_node);
}

/* Returns true if TYPE is char, unsigned char, or std::byte.  */

bool
is_byte_access_type (tree type)
{
  type = TYPE_MAIN_VARIANT (type);
  if (type == char_type_node
      || type == unsigned_char_type_node)
    return true;

  return (TREE_CODE (type) == ENUMERAL_TYPE
	  && TYPE_CONTEXT (type) == std_node
	  && !strcmp ("byte", TYPE_NAME_STRING (type)));
}

/* Returns true if TYPE is unsigned char or std::byte.  */

bool
is_byte_access_type_not_plain_char (tree type)
{
  type = TYPE_MAIN_VARIANT (type);
  if (type == char_type_node)
    return false;

  return is_byte_access_type (type);
}

/* Returns 1 iff type T is something we want to treat as a scalar type for
   the purpose of deciding whether it is trivial/POD/standard-layout.  */

bool
scalarish_type_p (const_tree t)
{
  if (t == error_mark_node)
    return 1;

  return (SCALAR_TYPE_P (t) || VECTOR_TYPE_P (t));
}

/* Returns true iff T requires non-trivial default initialization.  */

bool
type_has_nontrivial_default_init (const_tree t)
{
  t = strip_array_types (CONST_CAST_TREE (t));

  if (CLASS_TYPE_P (t))
    return TYPE_HAS_COMPLEX_DFLT (t);
  else
    return 0;
}

/* Track classes with only deleted copy/move constructors so that we can warn
   if they are used in call/return by value.  */

static GTY(()) hash_set<tree>* deleted_copy_types;
static void
remember_deleted_copy (const_tree t)
{
  if (!deleted_copy_types)
    deleted_copy_types = hash_set<tree>::create_ggc(37);
  deleted_copy_types->add (CONST_CAST_TREE (t));
}
void
maybe_warn_parm_abi (tree t, location_t loc)
{
  if (!deleted_copy_types
      || !deleted_copy_types->contains (t))
    return;

  if ((flag_abi_version == 12 || warn_abi_version == 12)
      && classtype_has_non_deleted_move_ctor (t))
    {
      bool w;
      auto_diagnostic_group d;
      if (flag_abi_version > 12)
	w = warning_at (loc, OPT_Wabi, "%<-fabi-version=13%> (GCC 8.2) fixes "
			"the calling convention for %qT, which was "
			"accidentally changed in 8.1", t);
      else
	w = warning_at (loc, OPT_Wabi, "%<-fabi-version=12%> (GCC 8.1) "
			"accidentally changes the calling convention for %qT",
			t);
      if (w)
	inform (location_of (t), " declared here");
      return;
    }

  auto_diagnostic_group d;
  if (warning_at (loc, OPT_Wabi, "the calling convention for %qT changes in "
		  "%<-fabi-version=13%> (GCC 8.2)", t))
    inform (location_of (t), " because all of its copy and move "
	    "constructors are deleted");
}

/* Returns true iff copying an object of type T (including via move
   constructor) is non-trivial.  That is, T has no non-trivial copy
   constructors and no non-trivial move constructors, and not all copy/move
   constructors are deleted.  This function implements the ABI notion of
   non-trivial copy, which has diverged from the one in the standard.  */

bool
type_has_nontrivial_copy_init (const_tree type)
{
  tree t = strip_array_types (CONST_CAST_TREE (type));

  if (CLASS_TYPE_P (t))
    {
      gcc_assert (COMPLETE_TYPE_P (t));

      if (TYPE_HAS_COMPLEX_COPY_CTOR (t)
	  || TYPE_HAS_COMPLEX_MOVE_CTOR (t))
	/* Nontrivial.  */
	return true;

      if (cxx_dialect < cxx11)
	/* No deleted functions before C++11.  */
	return false;

      /* Before ABI v12 we did a bitwise copy of types with only deleted
	 copy/move constructors.  */
      if (!abi_version_at_least (12)
	  && !(warn_abi && abi_version_crosses (12)))
	return false;

      bool saw_copy = false;
      bool saw_non_deleted = false;
      bool saw_non_deleted_move = false;

      if (CLASSTYPE_LAZY_MOVE_CTOR (t))
	saw_copy = saw_non_deleted = true;
      else if (CLASSTYPE_LAZY_COPY_CTOR (t))
	{
	  saw_copy = true;
	  if (classtype_has_move_assign_or_move_ctor_p (t, true))
	    /* [class.copy]/8 If the class definition declares a move
	       constructor or move assignment operator, the implicitly declared
	       copy constructor is defined as deleted.... */;
	  else
	    /* Any other reason the implicitly-declared function would be
	       deleted would also cause TYPE_HAS_COMPLEX_COPY_CTOR to be
	       set.  */
	    saw_non_deleted = true;
	}

      if (!saw_non_deleted)
	for (ovl_iterator iter (CLASSTYPE_CONSTRUCTORS (t)); iter; ++iter)
	  {
	    tree fn = *iter;
	    if (copy_fn_p (fn))
	      {
		saw_copy = true;
		if (!DECL_DELETED_FN (fn))
		  {
		    /* Not deleted, therefore trivial.  */
		    saw_non_deleted = true;
		    break;
		  }
	      }
	    else if (move_fn_p (fn))
	      if (!DECL_DELETED_FN (fn))
		saw_non_deleted_move = true;
	  }

      gcc_assert (saw_copy);

      /* ABI v12 buggily ignored move constructors.  */
      bool v11nontriv = false;
      bool v12nontriv = !saw_non_deleted;
      bool v13nontriv = !saw_non_deleted && !saw_non_deleted_move;
      bool nontriv = (abi_version_at_least (13) ? v13nontriv
		      : flag_abi_version == 12 ? v12nontriv
		      : v11nontriv);
      bool warn_nontriv = (warn_abi_version >= 13 ? v13nontriv
			   : warn_abi_version == 12 ? v12nontriv
			   : v11nontriv);
      if (nontriv != warn_nontriv)
	remember_deleted_copy (t);

      return nontriv;
    }
  else
    return 0;
}

/* Returns 1 iff type T is a trivially copyable type, as defined in
   [basic.types] and [class].  */

bool
trivially_copyable_p (const_tree t)
{
  t = strip_array_types (CONST_CAST_TREE (t));

  if (CLASS_TYPE_P (t))
    return ((!TYPE_HAS_COPY_CTOR (t)
	     || !TYPE_HAS_COMPLEX_COPY_CTOR (t))
	    && !TYPE_HAS_COMPLEX_MOVE_CTOR (t)
	    && (!TYPE_HAS_COPY_ASSIGN (t)
		|| !TYPE_HAS_COMPLEX_COPY_ASSIGN (t))
	    && !TYPE_HAS_COMPLEX_MOVE_ASSIGN (t)
	    && TYPE_HAS_TRIVIAL_DESTRUCTOR (t));
  else
    /* CWG 2094 makes volatile-qualified scalars trivially copyable again.  */
    return scalarish_type_p (t);
}

/* Returns 1 iff type T is a trivial type, as defined in [basic.types] and
   [class].  */

bool
trivial_type_p (const_tree t)
{
  t = strip_array_types (CONST_CAST_TREE (t));

  if (CLASS_TYPE_P (t))
    return (TYPE_HAS_TRIVIAL_DFLT (t)
	    && trivially_copyable_p (t));
  else
    return scalarish_type_p (t);
}

/* Returns 1 iff type T is a POD type, as defined in [basic.types].  */

bool
pod_type_p (const_tree t)
{
  /* This CONST_CAST is okay because strip_array_types returns its
     argument unmodified and we assign it to a const_tree.  */
  t = strip_array_types (CONST_CAST_TREE(t));

  if (!CLASS_TYPE_P (t))
    return scalarish_type_p (t);
  else if (cxx_dialect > cxx98)
    /* [class]/10: A POD struct is a class that is both a trivial class and a
       standard-layout class, and has no non-static data members of type
       non-POD struct, non-POD union (or array of such types).

       We don't need to check individual members because if a member is
       non-std-layout or non-trivial, the class will be too.  */
    return (std_layout_type_p (t) && trivial_type_p (t));
  else
    /* The C++98 definition of POD is different.  */
    return !CLASSTYPE_NON_LAYOUT_POD_P (t);
}

/* Returns true iff T is POD for the purpose of layout, as defined in the
   C++ ABI.  */

bool
layout_pod_type_p (const_tree t)
{
  t = strip_array_types (CONST_CAST_TREE (t));

  if (CLASS_TYPE_P (t))
    return !CLASSTYPE_NON_LAYOUT_POD_P (t);
  else
    return scalarish_type_p (t);
}

/* Returns true iff T is a standard-layout type, as defined in
   [basic.types].  */

bool
std_layout_type_p (const_tree t)
{
  t = strip_array_types (CONST_CAST_TREE (t));

  if (CLASS_TYPE_P (t))
    return !CLASSTYPE_NON_STD_LAYOUT (t);
  else
    return scalarish_type_p (t);
}

static bool record_has_unique_obj_representations (const_tree, const_tree);

/* Returns true iff T satisfies std::has_unique_object_representations<T>,
   as defined in [meta.unary.prop].  */

bool
type_has_unique_obj_representations (const_tree t)
{
  bool ret;

  t = strip_array_types (CONST_CAST_TREE (t));

  if (!trivially_copyable_p (t))
    return false;

  if (CLASS_TYPE_P (t) && CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS_SET (t))
    return CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS (t);

  switch (TREE_CODE (t))
    {
    case INTEGER_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* If some backend has any paddings in these types, we should add
	 a target hook for this and handle it there.  */
      return true;

    case BOOLEAN_TYPE:
      /* For bool values other than 0 and 1 should only appear with
	 undefined behavior.  */
      return true;

    case ENUMERAL_TYPE:
      return type_has_unique_obj_representations (ENUM_UNDERLYING_TYPE (t));

    case REAL_TYPE:
      /* XFmode certainly contains padding on x86, which the CPU doesn't store
	 when storing long double values, so for that we have to return false.
	 Other kinds of floating point values are questionable due to +.0/-.0
	 and NaNs, let's play safe for now.  */
      return false;

    case FIXED_POINT_TYPE:
      return false;

    case OFFSET_TYPE:
      return true;

    case COMPLEX_TYPE:
    case VECTOR_TYPE:
      return type_has_unique_obj_representations (TREE_TYPE (t));

    case RECORD_TYPE:
      ret = record_has_unique_obj_representations (t, TYPE_SIZE (t));
      if (CLASS_TYPE_P (t))
	{
	  CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS_SET (t) = 1;
	  CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS (t) = ret;
	}
      return ret;

    case UNION_TYPE:
      ret = true;
      bool any_fields;
      any_fields = false;
      for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
	if (TREE_CODE (field) == FIELD_DECL)
	  {
	    any_fields = true;
	    if (!type_has_unique_obj_representations (TREE_TYPE (field))
		|| simple_cst_equal (DECL_SIZE (field), TYPE_SIZE (t)) != 1)
	      {
		ret = false;
		break;
	      }
	  }
      if (!any_fields && !integer_zerop (TYPE_SIZE (t)))
	ret = false;
      if (CLASS_TYPE_P (t))
	{
	  CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS_SET (t) = 1;
	  CLASSTYPE_UNIQUE_OBJ_REPRESENTATIONS (t) = ret;
	}
      return ret;

    case NULLPTR_TYPE:
      return false;

    case ERROR_MARK:
      return false;

    default:
      gcc_unreachable ();
    }
}

/* Helper function for type_has_unique_obj_representations.  */

static bool
record_has_unique_obj_representations (const_tree t, const_tree sz)
{
  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
    if (TREE_CODE (field) != FIELD_DECL)
      ;
    /* For bases, can't use type_has_unique_obj_representations here, as in
	struct S { int i : 24; S (); };
	struct T : public S { int j : 8; T (); };
	S doesn't have unique obj representations, but T does.  */
    else if (DECL_FIELD_IS_BASE (field))
      {
	if (!record_has_unique_obj_representations (TREE_TYPE (field),
						    DECL_SIZE (field)))
	  return false;
      }
    else if (DECL_C_BIT_FIELD (field))
      {
	tree btype = DECL_BIT_FIELD_TYPE (field);
	if (!type_has_unique_obj_representations (btype))
	  return false;
      }
    else if (!type_has_unique_obj_representations (TREE_TYPE (field)))
      return false;

  offset_int cur = 0;
  for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
    if (TREE_CODE (field) == FIELD_DECL)
      {
	offset_int fld = wi::to_offset (DECL_FIELD_OFFSET (field));
	offset_int bitpos = wi::to_offset (DECL_FIELD_BIT_OFFSET (field));
	fld = fld * BITS_PER_UNIT + bitpos;
	if (cur != fld)
	  return false;
	if (DECL_SIZE (field))
	  {
	    offset_int size = wi::to_offset (DECL_SIZE (field));
	    cur += size;
	  }
      }
  if (cur != wi::to_offset (sz))
    return false;

  return true;
}

/* Nonzero iff type T is a class template implicit specialization.  */

bool
class_tmpl_impl_spec_p (const_tree t)
{
  return CLASS_TYPE_P (t) && CLASSTYPE_TEMPLATE_INSTANTIATION (t);
}

/* Returns 1 iff zero initialization of type T means actually storing
   zeros in it.  */

int
zero_init_p (const_tree t)
{
  /* This CONST_CAST is okay because strip_array_types returns its
     argument unmodified and we assign it to a const_tree.  */
  t = strip_array_types (CONST_CAST_TREE(t));

  if (t == error_mark_node)
    return 1;

  /* NULL pointers to data members are initialized with -1.  */
  if (TYPE_PTRDATAMEM_P (t))
    return 0;

  /* Classes that contain types that can't be zero-initialized, cannot
     be zero-initialized themselves.  */
  if (CLASS_TYPE_P (t) && CLASSTYPE_NON_ZERO_INIT_P (t))
    return 0;

  return 1;
}

/* Returns true if the expression or initializer T is the result of
   zero-initialization for its type, taking pointers to members
   into consideration.  */

bool
zero_init_expr_p (tree t)
{
  tree type = TREE_TYPE (t);
  if (!type || uses_template_parms (type))
    return false;
  if (TYPE_PTRMEM_P (type))
    return null_member_pointer_value_p (t);
  if (TREE_CODE (t) == CONSTRUCTOR)
    {
      if (COMPOUND_LITERAL_P (t)
	  || BRACE_ENCLOSED_INITIALIZER_P (t))
	/* Undigested, conversions might change the zeroness.  */
	return false;
      for (constructor_elt &elt : CONSTRUCTOR_ELTS (t))
	{
	  if (TREE_CODE (type) == UNION_TYPE
	      && elt.index != first_field (type))
	    return false;
	  if (!zero_init_expr_p (elt.value))
	    return false;
	}
      return true;
    }
  if (zero_init_p (type))
    return initializer_zerop (t);
  return false;
}

/* True IFF T is a C++20 structural type (P1907R1) that can be used as a
   non-type template parameter.  If EXPLAIN, explain why not.  */

bool
structural_type_p (tree t, bool explain)
{
  /* A structural type is one of the following: */

  /* a scalar type, or */
  if (SCALAR_TYPE_P (t))
    return true;
  /* an lvalue reference type, or */
  if (TYPE_REF_P (t) && !TYPE_REF_IS_RVALUE (t))
    return true;
  /* a literal class type with the following properties:
     - all base classes and non-static data members are public and non-mutable
       and
     - the types of all bases classes and non-static data members are
       structural types or (possibly multi-dimensional) array thereof.  */
  if (!CLASS_TYPE_P (t))
    return false;
  if (!literal_type_p (t))
    {
      if (explain)
	explain_non_literal_class (t);
      return false;
    }
  for (tree m = next_aggregate_field (TYPE_FIELDS (t)); m;
       m = next_aggregate_field (DECL_CHAIN (m)))
    {
      if (TREE_PRIVATE (m) || TREE_PROTECTED (m))
	{
	  if (explain)
	    {
	      if (DECL_FIELD_IS_BASE (m))
		inform (location_of (m), "base class %qT is not public",
			TREE_TYPE (m));
	      else
		inform (location_of (m), "%qD is not public", m);
	    }
	  return false;
	}
      if (DECL_MUTABLE_P (m))
	{
	  if (explain)
	    inform (location_of (m), "%qD is mutable", m);
	  return false;
	}
      tree mtype = strip_array_types (TREE_TYPE (m));
      if (!structural_type_p (mtype))
	{
	  if (explain)
	    {
	      inform (location_of (m), "%qD has a non-structural type", m);
	      structural_type_p (mtype, true);
	    }
	  return false;
	}
    }
  return true;
}

/* Handle the C++17 [[nodiscard]] attribute, which is similar to the GNU
   warn_unused_result attribute.  */

static tree
handle_nodiscard_attribute (tree *node, tree name, tree args,
			    int /*flags*/, bool *no_add_attrs)
{
  if (args && TREE_CODE (TREE_VALUE (args)) != STRING_CST)
    {
      error ("%qE attribute argument must be a string constant", name);
      *no_add_attrs = true;
    }
  if (TREE_CODE (*node) == FUNCTION_DECL)
    {
      if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))
	  && !DECL_CONSTRUCTOR_P (*node))
	warning_at (DECL_SOURCE_LOCATION (*node),
		    OPT_Wattributes, "%qE attribute applied to %qD with void "
		    "return type", name, *node);
    }
  else if (OVERLOAD_TYPE_P (*node))
    /* OK */;
  else
    {
      warning (OPT_Wattributes, "%qE attribute can only be applied to "
	       "functions or to class or enumeration types", name);
      *no_add_attrs = true;
    }
  return NULL_TREE;
}

/* Handle a C++20 "no_unique_address" attribute; arguments as in
   struct attribute_spec.handler.  */
static tree
handle_no_unique_addr_attribute (tree* node,
				 tree name,
				 tree /*args*/,
				 int /*flags*/,
				 bool* no_add_attrs)
{
  if (TREE_CODE (*node) != FIELD_DECL)
    {
      warning (OPT_Wattributes, "%qE attribute can only be applied to "
	       "non-static data members", name);
      *no_add_attrs = true;
    }
  else if (DECL_C_BIT_FIELD (*node))
    {
      warning (OPT_Wattributes, "%qE attribute cannot be applied to "
	       "a bit-field", name);
      *no_add_attrs = true;
    }

  return NULL_TREE;
}

/* The C++20 [[likely]] and [[unlikely]] attributes on labels map to the GNU
   hot/cold attributes.  */

static tree
handle_likeliness_attribute (tree *node, tree name, tree args,
			     int flags, bool *no_add_attrs)
{
  *no_add_attrs = true;
  if (TREE_CODE (*node) == LABEL_DECL
      || TREE_CODE (*node) == FUNCTION_DECL)
    {
      if (args)
	warning (OPT_Wattributes, "%qE attribute takes no arguments", name);
      tree bname = (is_attribute_p ("likely", name)
		    ? get_identifier ("hot") : get_identifier ("cold"));
      if (TREE_CODE (*node) == FUNCTION_DECL)
	warning (OPT_Wattributes, "ISO C++ %qE attribute does not apply to "
		 "functions; treating as %<[[gnu::%E]]%>", name, bname);
      tree battr = build_tree_list (bname, NULL_TREE);
      decl_attributes (node, battr, flags);
      return NULL_TREE;
    }
  else
    return error_mark_node;
}

/* Table of valid C++ attributes.  */
const struct attribute_spec cxx_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "init_priority",  1, 1, true,  false, false, false,
    handle_init_priority_attribute, NULL },
  { "abi_tag", 1, -1, false, false, false, true,
    handle_abi_tag_attribute, NULL },
  { NULL, 0, 0, false, false, false, false, NULL, NULL }
};

/* Table of C++ standard attributes.  */
const struct attribute_spec std_attribute_table[] =
{
  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
       affects_type_identity, handler, exclude } */
  { "maybe_unused", 0, 0, false, false, false, false,
    handle_unused_attribute, NULL },
  { "nodiscard", 0, 1, false, false, false, false,
    handle_nodiscard_attribute, NULL },
  { "no_unique_address", 0, 0, true, false, false, false,
    handle_no_unique_addr_attribute, NULL },
  { "likely", 0, 0, false, false, false, false,
    handle_likeliness_attribute, attr_cold_hot_exclusions },
  { "unlikely", 0, 0, false, false, false, false,
    handle_likeliness_attribute, attr_cold_hot_exclusions },
  { "noreturn", 0, 0, true, false, false, false,
    handle_noreturn_attribute, attr_noreturn_exclusions },
  { NULL, 0, 0, false, false, false, false, NULL, NULL }
};

/* Handle an "init_priority" attribute; arguments as in
   struct attribute_spec.handler.  */
static tree
handle_init_priority_attribute (tree* node,
				tree name,
				tree args,
				int /*flags*/,
				bool* no_add_attrs)
{
  tree initp_expr = TREE_VALUE (args);
  tree decl = *node;
  tree type = TREE_TYPE (decl);
  int pri;

  STRIP_NOPS (initp_expr);
  initp_expr = default_conversion (initp_expr);
  if (initp_expr)
    initp_expr = maybe_constant_value (initp_expr);

  if (!initp_expr || TREE_CODE (initp_expr) != INTEGER_CST)
    {
      error ("requested %<init_priority%> is not an integer constant");
      cxx_constant_value (initp_expr);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  pri = TREE_INT_CST_LOW (initp_expr);

  type = strip_array_types (type);

  if (decl == NULL_TREE
      || !VAR_P (decl)
      || !TREE_STATIC (decl)
      || DECL_EXTERNAL (decl)
      || (TREE_CODE (type) != RECORD_TYPE
	  && TREE_CODE (type) != UNION_TYPE)
      /* Static objects in functions are initialized the
	 first time control passes through that
	 function. This is not precise enough to pin down an
	 init_priority value, so don't allow it.  */
      || current_function_decl)
    {
      error ("can only use %qE attribute on file-scope definitions "
	     "of objects of class type", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  if (pri > MAX_INIT_PRIORITY || pri <= 0)
    {
      error ("requested %<init_priority%> %i is out of range [0, %i]",
	     pri, MAX_INIT_PRIORITY);
      *no_add_attrs = true;
      return NULL_TREE;
    }

  /* Check for init_priorities that are reserved for
     language and runtime support implementations.*/
  if (pri <= MAX_RESERVED_INIT_PRIORITY)
    {
      warning
	(0, "requested %<init_priority%> %i is reserved for internal use",
	 pri);
    }

  if (SUPPORTS_INIT_PRIORITY)
    {
      SET_DECL_INIT_PRIORITY (decl, pri);
      DECL_HAS_INIT_PRIORITY_P (decl) = 1;
      return NULL_TREE;
    }
  else
    {
      error ("%qE attribute is not supported on this platform", name);
      *no_add_attrs = true;
      return NULL_TREE;
    }
}

/* DECL is being redeclared; the old declaration had the abi tags in OLD,
   and the new one has the tags in NEW_.  Give an error if there are tags
   in NEW_ that weren't in OLD.  */

bool
check_abi_tag_redeclaration (const_tree decl, const_tree old, const_tree new_)
{
  if (old && TREE_CODE (TREE_VALUE (old)) == TREE_LIST)
    old = TREE_VALUE (old);
  if (new_ && TREE_CODE (TREE_VALUE (new_)) == TREE_LIST)
    new_ = TREE_VALUE (new_);
  bool err = false;
  for (const_tree t = new_; t; t = TREE_CHAIN (t))
    {
      tree str = TREE_VALUE (t);
      for (const_tree in = old; in; in = TREE_CHAIN (in))
	{
	  tree ostr = TREE_VALUE (in);
	  if (cp_tree_equal (str, ostr))
	    goto found;
	}
      error ("redeclaration of %qD adds abi tag %qE", decl, str);
      err = true;
    found:;
    }
  if (err)
    {
      inform (DECL_SOURCE_LOCATION (decl), "previous declaration here");
      return false;
    }
  return true;
}

/* The abi_tag attribute with the name NAME was given ARGS.  If they are
   ill-formed, give an error and return false; otherwise, return true.  */

bool
check_abi_tag_args (tree args, tree name)
{
  if (!args)
    {
      error ("the %qE attribute requires arguments", name);
      return false;
    }
  for (tree arg = args; arg; arg = TREE_CHAIN (arg))
    {
      tree elt = TREE_VALUE (arg);
      if (TREE_CODE (elt) != STRING_CST
	  || (!same_type_ignoring_top_level_qualifiers_p
	      (strip_array_types (TREE_TYPE (elt)),
	       char_type_node)))
	{
	  error ("arguments to the %qE attribute must be narrow string "
		 "literals", name);
	  return false;
	}
      const char *begin = TREE_STRING_POINTER (elt);
      const char *end = begin + TREE_STRING_LENGTH (elt);
      for (const char *p = begin; p != end; ++p)
	{
	  char c = *p;
	  if (p == begin)
	    {
	      if (!ISALPHA (c) && c != '_')
		{
		  error ("arguments to the %qE attribute must contain valid "
			 "identifiers", name);
		  inform (input_location, "%<%c%> is not a valid first "
			  "character for an identifier", c);
		  return false;
		}
	    }
	  else if (p == end - 1)
	    gcc_assert (c == 0);
	  else
	    {
	      if (!ISALNUM (c) && c != '_')
		{
		  error ("arguments to the %qE attribute must contain valid "
			 "identifiers", name);
		  inform (input_location, "%<%c%> is not a valid character "
			  "in an identifier", c);
		  return false;
		}
	    }
	}
    }
  return true;
}

/* Handle an "abi_tag" attribute; arguments as in
   struct attribute_spec.handler.  */

static tree
handle_abi_tag_attribute (tree* node, tree name, tree args,
			  int flags, bool* no_add_attrs)
{
  if (!check_abi_tag_args (args, name))
    goto fail;

  if (TYPE_P (*node))
    {
      if (!OVERLOAD_TYPE_P (*node))
	{
	  error ("%qE attribute applied to non-class, non-enum type %qT",
		 name, *node);
	  goto fail;
	}
      else if (!(flags & (int)ATTR_FLAG_TYPE_IN_PLACE))
	{
	  error ("%qE attribute applied to %qT after its definition",
		 name, *node);
	  goto fail;
	}
      else if (CLASS_TYPE_P (*node)
	       && CLASSTYPE_TEMPLATE_INSTANTIATION (*node))
	{
	  warning (OPT_Wattributes, "ignoring %qE attribute applied to "
		   "template instantiation %qT", name, *node);
	  goto fail;
	}
      else if (CLASS_TYPE_P (*node)
	       && CLASSTYPE_TEMPLATE_SPECIALIZATION (*node))
	{
	  warning (OPT_Wattributes, "ignoring %qE attribute applied to "
		   "template specialization %qT", name, *node);
	  goto fail;
	}

      tree attributes = TYPE_ATTRIBUTES (*node);
      tree decl = TYPE_NAME (*node);

      /* Make sure all declarations have the same abi tags.  */
      if (DECL_SOURCE_LOCATION (decl) != input_location)
	{
	  if (!check_abi_tag_redeclaration (decl,
					    lookup_attribute ("abi_tag",
							      attributes),
					    args))
	    goto fail;
	}
    }
  else
    {
      if (!VAR_OR_FUNCTION_DECL_P (*node))
	{
	  error ("%qE attribute applied to non-function, non-variable %qD",
		 name, *node);
	  goto fail;
	}
      else if (DECL_LANGUAGE (*node) == lang_c)
	{
	  error ("%qE attribute applied to extern \"C\" declaration %qD",
		 name, *node);
	  goto fail;
	}
    }

  return NULL_TREE;

 fail:
  *no_add_attrs = true;
  return NULL_TREE;
}

/* Return a new PTRMEM_CST of the indicated TYPE.  The MEMBER is the
   thing pointed to by the constant.  */

tree
make_ptrmem_cst (tree type, tree member)
{
  tree ptrmem_cst = make_node (PTRMEM_CST);
  TREE_TYPE (ptrmem_cst) = type;
  PTRMEM_CST_MEMBER (ptrmem_cst) = member;
  PTRMEM_CST_LOCATION (ptrmem_cst) = input_location;
  return ptrmem_cst;
}

/* Build a variant of TYPE that has the indicated ATTRIBUTES.  May
   return an existing type if an appropriate type already exists.  */

tree
cp_build_type_attribute_variant (tree type, tree attributes)
{
  tree new_type;

  new_type = build_type_attribute_variant (type, attributes);
  if (FUNC_OR_METHOD_TYPE_P (new_type))
    gcc_checking_assert (cxx_type_hash_eq (type, new_type));

  /* Making a new main variant of a class type is broken.  */
  gcc_assert (!CLASS_TYPE_P (type) || new_type == type);
    
  return new_type;
}

/* Return TRUE if TYPE1 and TYPE2 are identical for type hashing purposes.
   Called only after doing all language independent checks.  */

bool
cxx_type_hash_eq (const_tree typea, const_tree typeb)
{
  gcc_assert (FUNC_OR_METHOD_TYPE_P (typea));

  if (type_memfn_rqual (typea) != type_memfn_rqual (typeb))
    return false;
  if (TYPE_HAS_LATE_RETURN_TYPE (typea) != TYPE_HAS_LATE_RETURN_TYPE (typeb))
    return false;
  return comp_except_specs (TYPE_RAISES_EXCEPTIONS (typea),
			    TYPE_RAISES_EXCEPTIONS (typeb), ce_exact);
}

/* Copy the language-specific type variant modifiers from TYPEB to TYPEA.  For
   C++, these are the exception-specifier and ref-qualifier.  */

tree
cxx_copy_lang_qualifiers (const_tree typea, const_tree typeb)
{
  tree type = CONST_CAST_TREE (typea);
  if (FUNC_OR_METHOD_TYPE_P (type))
    type = build_cp_fntype_variant (type, type_memfn_rqual (typeb),
				    TYPE_RAISES_EXCEPTIONS (typeb),
				    TYPE_HAS_LATE_RETURN_TYPE (typeb));
  return type;
}

/* Apply FUNC to all language-specific sub-trees of TP in a pre-order
   traversal.  Called from walk_tree.  */

tree
cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
		  void *data, hash_set<tree> *pset)
{
  enum tree_code code = TREE_CODE (*tp);
  tree result;

#define WALK_SUBTREE(NODE)				\
  do							\
    {							\
      result = cp_walk_tree (&(NODE), func, data, pset);	\
      if (result) goto out;				\
    }							\
  while (0)

  if (TYPE_P (*tp))
    {
      /* If *WALK_SUBTREES_P is 1, we're interested in the syntactic form of
	 the argument, so don't look through typedefs, but do walk into
	 template arguments for alias templates (and non-typedefed classes).

	 If *WALK_SUBTREES_P > 1, we're interested in type identity or
	 equivalence, so look through typedefs, ignoring template arguments for
	 alias templates, and walk into template args of classes.

	 See find_abi_tags_r for an example of setting *WALK_SUBTREES_P to 2
	 when that's the behavior the walk_tree_fn wants.  */
      if (*walk_subtrees_p == 1 && typedef_variant_p (*tp))
	{
	  if (tree ti = TYPE_ALIAS_TEMPLATE_INFO (*tp))
	    WALK_SUBTREE (TI_ARGS (ti));
	  *walk_subtrees_p = 0;
	  return NULL_TREE;
	}

      if (tree ti = TYPE_TEMPLATE_INFO (*tp))
	WALK_SUBTREE (TI_ARGS (ti));
    }

  /* Not one of the easy cases.  We must explicitly go through the
     children.  */
  result = NULL_TREE;
  switch (code)
    {
    case TEMPLATE_TYPE_PARM:
      if (template_placeholder_p (*tp))
	WALK_SUBTREE (CLASS_PLACEHOLDER_TEMPLATE (*tp));
      /* Fall through.  */
    case DEFERRED_PARSE:
    case TEMPLATE_TEMPLATE_PARM:
    case BOUND_TEMPLATE_TEMPLATE_PARM:
    case UNBOUND_CLASS_TEMPLATE:
    case TEMPLATE_PARM_INDEX:
    case TYPEOF_TYPE:
    case UNDERLYING_TYPE:
      /* None of these have subtrees other than those already walked
	 above.  */
      *walk_subtrees_p = 0;
      break;

    case TYPENAME_TYPE:
      WALK_SUBTREE (TYPE_CONTEXT (*tp));
      WALK_SUBTREE (TYPENAME_TYPE_FULLNAME (*tp));
      *walk_subtrees_p = 0;
      break;

    case BASELINK:
      if (BASELINK_QUALIFIED_P (*tp))
	WALK_SUBTREE (BINFO_TYPE (BASELINK_ACCESS_BINFO (*tp)));
      WALK_SUBTREE (BASELINK_FUNCTIONS (*tp));
      *walk_subtrees_p = 0;
      break;

    case PTRMEM_CST:
      WALK_SUBTREE (TREE_TYPE (*tp));
      *walk_subtrees_p = 0;
      break;

    case TREE_LIST:
      WALK_SUBTREE (TREE_PURPOSE (*tp));
      break;

    case OVERLOAD:
      WALK_SUBTREE (OVL_FUNCTION (*tp));
      WALK_SUBTREE (OVL_CHAIN (*tp));
      *walk_subtrees_p = 0;
      break;

    case USING_DECL:
      WALK_SUBTREE (DECL_NAME (*tp));
      WALK_SUBTREE (USING_DECL_SCOPE (*tp));
      WALK_SUBTREE (USING_DECL_DECLS (*tp));
      *walk_subtrees_p = 0;
      break;

    case RECORD_TYPE:
      if (TYPE_PTRMEMFUNC_P (*tp))
	WALK_SUBTREE (TYPE_PTRMEMFUNC_FN_TYPE_RAW (*tp));
      break;

    case TYPE_ARGUMENT_PACK:
    case NONTYPE_ARGUMENT_PACK:
      {
        tree args = ARGUMENT_PACK_ARGS (*tp);
	for (tree arg : tree_vec_range (args))
	  WALK_SUBTREE (arg);
      }
      break;

    case TYPE_PACK_EXPANSION:
      WALK_SUBTREE (TREE_TYPE (*tp));
      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
      *walk_subtrees_p = 0;
      break;
      
    case EXPR_PACK_EXPANSION:
      WALK_SUBTREE (TREE_OPERAND (*tp, 0));
      WALK_SUBTREE (PACK_EXPANSION_EXTRA_ARGS (*tp));
      *walk_subtrees_p = 0;
      break;

    case CAST_EXPR:
    case REINTERPRET_CAST_EXPR:
    case STATIC_CAST_EXPR:
    case CONST_CAST_EXPR:
    case DYNAMIC_CAST_EXPR:
    case IMPLICIT_CONV_EXPR:
    case BIT_CAST_EXPR:
      if (TREE_TYPE (*tp))
	WALK_SUBTREE (TREE_TYPE (*tp));
      break;

    case CONSTRUCTOR:
      if (COMPOUND_LITERAL_P (*tp))
	WALK_SUBTREE (TREE_TYPE (*tp));
      break;

    case TRAIT_EXPR:
      WALK_SUBTREE (TRAIT_EXPR_TYPE1 (*tp));
      WALK_SUBTREE (TRAIT_EXPR_TYPE2 (*tp));
      *walk_subtrees_p = 0;
      break;

    case DECLTYPE_TYPE:
      ++cp_unevaluated_operand;
      /* We can't use WALK_SUBTREE here because of the goto.  */
      result = cp_walk_tree (&DECLTYPE_TYPE_EXPR (*tp), func, data, pset);
      --cp_unevaluated_operand;
      *walk_subtrees_p = 0;
      break;

    case ALIGNOF_EXPR:
    case SIZEOF_EXPR:
    case NOEXCEPT_EXPR:
      ++cp_unevaluated_operand;
      result = cp_walk_tree (&TREE_OPERAND (*tp, 0), func, data, pset);
      --cp_unevaluated_operand;
      *walk_subtrees_p = 0;
      break;
 
    case REQUIRES_EXPR:
      // Only recurse through the nested expression. Do not
      // walk the parameter list. Doing so causes false
      // positives in the pack expansion checker since the
      // requires parameters are introduced as pack expansions.
      ++cp_unevaluated_operand;
      result = cp_walk_tree (&REQUIRES_EXPR_REQS (*tp), func, data, pset);
      --cp_unevaluated_operand;
      *walk_subtrees_p = 0;
      break;

    case DECL_EXPR:
      /* User variables should be mentioned in BIND_EXPR_VARS
	 and their initializers and sizes walked when walking
	 the containing BIND_EXPR.  Compiler temporaries are
	 handled here.  And also normal variables in templates,
	 since do_poplevel doesn't build a BIND_EXPR then.  */
      if (VAR_P (TREE_OPERAND (*tp, 0))
	  && (processing_template_decl
	      || (DECL_ARTIFICIAL (TREE_OPERAND (*tp, 0))
		  && !TREE_STATIC (TREE_OPERAND (*tp, 0)))))
	{
	  tree decl = TREE_OPERAND (*tp, 0);
	  WALK_SUBTREE (DECL_INITIAL (decl));
	  WALK_SUBTREE (DECL_SIZE (decl));
	  WALK_SUBTREE (DECL_SIZE_UNIT (decl));
	}
      break;

    case LAMBDA_EXPR:
      /* Don't walk into the body of the lambda, but the capture initializers
	 are part of the enclosing context.  */
      for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (*tp); cap;
	   cap = TREE_CHAIN (cap))
	WALK_SUBTREE (TREE_VALUE (cap));
      break;

    case CO_YIELD_EXPR:
      if (TREE_OPERAND (*tp, 1))
	/* Operand 1 is the tree for the relevant co_await which has any
	   interesting sub-trees.  */
	WALK_SUBTREE (TREE_OPERAND (*tp, 1));
      break;

    case CO_AWAIT_EXPR:
      if (TREE_OPERAND (*tp, 1))
	/* Operand 1 is frame variable.  */
	WALK_SUBTREE (TREE_OPERAND (*tp, 1));
      if (TREE_OPERAND (*tp, 2))
	/* Operand 2 has the initialiser, and we need to walk any subtrees
	   there.  */
	WALK_SUBTREE (TREE_OPERAND (*tp, 2));
      break;

    case CO_RETURN_EXPR:
      if (TREE_OPERAND (*tp, 0))
	{
	  if (VOID_TYPE_P (TREE_OPERAND (*tp, 0)))
	    /* For void expressions, operand 1 is a trivial call, and any
	       interesting subtrees will be part of operand 0.  */
	    WALK_SUBTREE (TREE_OPERAND (*tp, 0));
	  else if (TREE_OPERAND (*tp, 1))
	    /* Interesting sub-trees will be in the return_value () call
	       arguments.  */
	    WALK_SUBTREE (TREE_OPERAND (*tp, 1));
	}
      break;

    case STATIC_ASSERT:
      WALK_SUBTREE (STATIC_ASSERT_CONDITION (*tp));
      WALK_SUBTREE (STATIC_ASSERT_MESSAGE (*tp));
      break;

    default:
      return NULL_TREE;
    }

  /* We didn't find what we were looking for.  */
 out:
  return result;

#undef WALK_SUBTREE
}

/* Like save_expr, but for C++.  */

tree
cp_save_expr (tree expr)
{
  /* There is no reason to create a SAVE_EXPR within a template; if
     needed, we can create the SAVE_EXPR when instantiating the
     template.  Furthermore, the middle-end cannot handle C++-specific
     tree codes.  */
  if (processing_template_decl)
    return expr;

  /* TARGET_EXPRs are only expanded once.  */
  if (TREE_CODE (expr) == TARGET_EXPR)
    return expr;

  return save_expr (expr);
}

/* Initialize tree.cc.  */

void
init_tree (void)
{
  list_hash_table = hash_table<list_hasher>::create_ggc (61);
  register_scoped_attributes (std_attribute_table, NULL);
}

/* Returns the kind of special function that DECL (a FUNCTION_DECL)
   is.  Note that sfk_none is zero, so this function can be used as a
   predicate to test whether or not DECL is a special function.  */

special_function_kind
special_function_p (const_tree decl)
{
  /* Rather than doing all this stuff with magic names, we should
     probably have a field of type `special_function_kind' in
     DECL_LANG_SPECIFIC.  */
  if (DECL_INHERITED_CTOR (decl))
    return sfk_inheriting_constructor;
  if (DECL_COPY_CONSTRUCTOR_P (decl))
    return sfk_copy_constructor;
  if (DECL_MOVE_CONSTRUCTOR_P (decl))
    return sfk_move_constructor;
  if (DECL_CONSTRUCTOR_P (decl))
    return sfk_constructor;
  if (DECL_ASSIGNMENT_OPERATOR_P (decl)
      && DECL_OVERLOADED_OPERATOR_IS (decl, NOP_EXPR))
    {
      if (copy_fn_p (decl))
	return sfk_copy_assignment;
      if (move_fn_p (decl))
	return sfk_move_assignment;
    }
  if (DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl))
    return sfk_destructor;
  if (DECL_COMPLETE_DESTRUCTOR_P (decl))
    return sfk_complete_destructor;
  if (DECL_BASE_DESTRUCTOR_P (decl))
    return sfk_base_destructor;
  if (DECL_DELETING_DESTRUCTOR_P (decl))
    return sfk_deleting_destructor;
  if (DECL_CONV_FN_P (decl))
    return sfk_conversion;
  if (deduction_guide_p (decl))
    return sfk_deduction_guide;
  if (DECL_OVERLOADED_OPERATOR_CODE_RAW (decl) >= OVL_OP_EQ_EXPR
      && DECL_OVERLOADED_OPERATOR_CODE_RAW (decl) <= OVL_OP_SPACESHIP_EXPR)
    return sfk_comparison;

  return sfk_none;
}

/* As above, but only if DECL is a special member function as per 11.3.3
   [special]: default/copy/move ctor, copy/move assignment, or destructor.  */

special_function_kind
special_memfn_p (const_tree decl)
{
  switch (special_function_kind sfk = special_function_p (decl))
    {
    case sfk_constructor:
      if (!default_ctor_p (decl))
	break;
      gcc_fallthrough();
    case sfk_copy_constructor:
    case sfk_copy_assignment:
    case sfk_move_assignment:
    case sfk_move_constructor:
    case sfk_destructor:
      return sfk;

    default:
      break;
    }
  return sfk_none;
}

/* Returns nonzero if TYPE is a character type, including wchar_t.  */

int
char_type_p (tree type)
{
  return (same_type_p (type, char_type_node)
	  || same_type_p (type, unsigned_char_type_node)
	  || same_type_p (type, signed_char_type_node)
	  || same_type_p (type, char8_type_node)
	  || same_type_p (type, char16_type_node)
	  || same_type_p (type, char32_type_node)
	  || same_type_p (type, wchar_type_node));
}

/* Returns the kind of linkage associated with the indicated DECL.  Th
   value returned is as specified by the language standard; it is
   independent of implementation details regarding template
   instantiation, etc.  For example, it is possible that a declaration
   to which this function assigns external linkage would not show up
   as a global symbol when you run `nm' on the resulting object file.  */

linkage_kind
decl_linkage (tree decl)
{
  /* This function doesn't attempt to calculate the linkage from first
     principles as given in [basic.link].  Instead, it makes use of
     the fact that we have already set TREE_PUBLIC appropriately, and
     then handles a few special cases.  Ideally, we would calculate
     linkage first, and then transform that into a concrete
     implementation.  */

  /* Things that don't have names have no linkage.  */
  if (!DECL_NAME (decl))
    return lk_none;

  /* Fields have no linkage.  */
  if (TREE_CODE (decl) == FIELD_DECL)
    return lk_none;

  /* Things in local scope do not have linkage.  */
  if (decl_function_context (decl))
    return lk_none;

  /* Things that are TREE_PUBLIC have external linkage.  */
  if (TREE_PUBLIC (decl))
    return lk_external;

  /* maybe_thunk_body clears TREE_PUBLIC on the maybe-in-charge 'tor variants,
     check one of the "clones" for the real linkage.  */
  if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)
      && DECL_CHAIN (decl)
      && DECL_CLONED_FUNCTION_P (DECL_CHAIN (decl)))
    return decl_linkage (DECL_CHAIN (decl));

  if (TREE_CODE (decl) == NAMESPACE_DECL)
    return lk_external;

  /* Linkage of a CONST_DECL depends on the linkage of the enumeration
     type.  */
  if (TREE_CODE (decl) == CONST_DECL)
    return decl_linkage (TYPE_NAME (DECL_CONTEXT (decl)));

  /* Members of the anonymous namespace also have TREE_PUBLIC unset, but
     are considered to have external linkage for language purposes, as do
     template instantiations on targets without weak symbols.  DECLs really
     meant to have internal linkage have DECL_THIS_STATIC set.  */
  if (TREE_CODE (decl) == TYPE_DECL)
    return lk_external;
  if (VAR_OR_FUNCTION_DECL_P (decl))
    {
      if (!DECL_THIS_STATIC (decl))
	return lk_external;

      /* Static data members and static member functions from classes
	 in anonymous namespace also don't have TREE_PUBLIC set.  */
      if (DECL_CLASS_CONTEXT (decl))
	return lk_external;
    }

  /* Everything else has internal linkage.  */
  return lk_internal;
}

/* Returns the storage duration of the object or reference associated with
   the indicated DECL, which should be a VAR_DECL or PARM_DECL.  */

duration_kind
decl_storage_duration (tree decl)
{
  if (TREE_CODE (decl) == PARM_DECL)
    return dk_auto;
  if (TREE_CODE (decl) == FUNCTION_DECL)
    return dk_static;
  gcc_assert (VAR_P (decl));
  if (!TREE_STATIC (decl)
      && !DECL_EXTERNAL (decl))
    return dk_auto;
  if (CP_DECL_THREAD_LOCAL_P (decl))
    return dk_thread;
  return dk_static;
}

/* EXP is an expression that we want to pre-evaluate.  Returns (in
   *INITP) an expression that will perform the pre-evaluation.  The
   value returned by this function is a side-effect free expression
   equivalent to the pre-evaluated expression.  Callers must ensure
   that *INITP is evaluated before EXP.  */

tree
stabilize_expr (tree exp, tree* initp)
{
  tree init_expr;

  if (!TREE_SIDE_EFFECTS (exp))
    init_expr = NULL_TREE;
  else if (VOID_TYPE_P (TREE_TYPE (exp)))
    {
      init_expr = exp;
      exp = void_node;
    }
  /* There are no expressions with REFERENCE_TYPE, but there can be call
     arguments with such a type; just treat it as a pointer.  */
  else if (TYPE_REF_P (TREE_TYPE (exp))
	   || SCALAR_TYPE_P (TREE_TYPE (exp))
	   || !glvalue_p (exp))
    {
      init_expr = get_target_expr (exp);
      exp = TARGET_EXPR_SLOT (init_expr);
      if (CLASS_TYPE_P (TREE_TYPE (exp)))
	exp = move (exp);
      else
	exp = rvalue (exp);
    }
  else
    {
      bool xval = !lvalue_p (exp);
      exp = cp_build_addr_expr (exp, tf_warning_or_error);
      init_expr = get_target_expr (exp);
      exp = TARGET_EXPR_SLOT (init_expr);
      exp = cp_build_fold_indirect_ref (exp);
      if (xval)
	exp = move (exp);
    }
  *initp = init_expr;

  gcc_assert (!TREE_SIDE_EFFECTS (exp));
  return exp;
}

/* Add NEW_EXPR, an expression whose value we don't care about, after the
   similar expression ORIG.  */

tree
add_stmt_to_compound (tree orig, tree new_expr)
{
  if (!new_expr || !TREE_SIDE_EFFECTS (new_expr))
    return orig;
  if (!orig || !TREE_SIDE_EFFECTS (orig))
    return new_expr;
  return build2 (COMPOUND_EXPR, void_type_node, orig, new_expr);
}

/* Like stabilize_expr, but for a call whose arguments we want to
   pre-evaluate.  CALL is modified in place to use the pre-evaluated
   arguments, while, upon return, *INITP contains an expression to
   compute the arguments.  */

void
stabilize_call (tree call, tree *initp)
{
  tree inits = NULL_TREE;
  int i;
  int nargs = call_expr_nargs (call);

  if (call == error_mark_node || processing_template_decl)
    {
      *initp = NULL_TREE;
      return;
    }

  gcc_assert (TREE_CODE (call) == CALL_EXPR);

  for (i = 0; i < nargs; i++)
    {
      tree init;
      CALL_EXPR_ARG (call, i) =
	stabilize_expr (CALL_EXPR_ARG (call, i), &init);
      inits = add_stmt_to_compound (inits, init);
    }

  *initp = inits;
}

/* Like stabilize_expr, but for an AGGR_INIT_EXPR whose arguments we want
   to pre-evaluate.  CALL is modified in place to use the pre-evaluated
   arguments, while, upon return, *INITP contains an expression to
   compute the arguments.  */

static void
stabilize_aggr_init (tree call, tree *initp)
{
  tree inits = NULL_TREE;
  int i;
  int nargs = aggr_init_expr_nargs (call);

  if (call == error_mark_node)
    return;

  gcc_assert (TREE_CODE (call) == AGGR_INIT_EXPR);

  for (i = 0; i < nargs; i++)
    {
      tree init;
      AGGR_INIT_EXPR_ARG (call, i) =
	stabilize_expr (AGGR_INIT_EXPR_ARG (call, i), &init);
      inits = add_stmt_to_compound (inits, init);
    }

  *initp = inits;
}

/* Like stabilize_expr, but for an initialization.  

   If the initialization is for an object of class type, this function
   takes care not to introduce additional temporaries.

   Returns TRUE iff the expression was successfully pre-evaluated,
   i.e., if INIT is now side-effect free, except for, possibly, a
   single call to a constructor.  */

bool
stabilize_init (tree init, tree *initp)
{
  tree t = init;

  *initp = NULL_TREE;

  if (t == error_mark_node || processing_template_decl)
    return true;

  if (TREE_CODE (t) == INIT_EXPR)
    t = TREE_OPERAND (t, 1);
  if (TREE_CODE (t) == TARGET_EXPR)
    t = TARGET_EXPR_INITIAL (t);

  /* If the RHS can be stabilized without breaking copy elision, stabilize
     it.  We specifically don't stabilize class prvalues here because that
     would mean an extra copy, but they might be stabilized below.  */
  if (TREE_CODE (init) == INIT_EXPR
      && TREE_CODE (t) != CONSTRUCTOR
      && TREE_CODE (t) != AGGR_INIT_EXPR
      && (SCALAR_TYPE_P (TREE_TYPE (t))
	  || glvalue_p (t)))
    {
      TREE_OPERAND (init, 1) = stabilize_expr (t, initp);
      return true;
    }

  if (TREE_CODE (t) == COMPOUND_EXPR
      && TREE_CODE (init) == INIT_EXPR)
    {
      tree last = expr_last (t);
      /* Handle stabilizing the EMPTY_CLASS_EXPR pattern.  */
      if (!TREE_SIDE_EFFECTS (last))
	{
	  *initp = t;
	  TREE_OPERAND (init, 1) = last;
	  return true;
	}
    }

  if (TREE_CODE (t) == CONSTRUCTOR)
    {
      /* Aggregate initialization: stabilize each of the field
	 initializers.  */
      unsigned i;
      constructor_elt *ce;
      bool good = true;
      vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
      for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
	{
	  tree type = TREE_TYPE (ce->value);
	  tree subinit;
	  if (TYPE_REF_P (type)
	      || SCALAR_TYPE_P (type))
	    ce->value = stabilize_expr (ce->value, &subinit);
	  else if (!stabilize_init (ce->value, &subinit))
	    good = false;
	  *initp = add_stmt_to_compound (*initp, subinit);
	}
      return good;
    }

  if (TREE_CODE (t) == CALL_EXPR)
    {
      stabilize_call (t, initp);
      return true;
    }

  if (TREE_CODE (t) == AGGR_INIT_EXPR)
    {
      stabilize_aggr_init (t, initp);
      return true;
    }

  /* The initialization is being performed via a bitwise copy -- and
     the item copied may have side effects.  */
  return !TREE_SIDE_EFFECTS (init);
}

/* Returns true if a cast to TYPE may appear in an integral constant
   expression.  */

bool
cast_valid_in_integral_constant_expression_p (tree type)
{
  return (INTEGRAL_OR_ENUMERATION_TYPE_P (type)
	  || cxx_dialect >= cxx11
	  || dependent_type_p (type)
	  || type == error_mark_node);
}

/* Return true if we need to fix linkage information of DECL.  */

static bool
cp_fix_function_decl_p (tree decl)
{
  /* Skip if DECL is not externally visible.  */
  if (!TREE_PUBLIC (decl))
    return false;

  /* We need to fix DECL if it a appears to be exported but with no
     function body.  Thunks do not have CFGs and we may need to
     handle them specially later.   */
  if (!gimple_has_body_p (decl)
      && !DECL_THUNK_P (decl)
      && !DECL_EXTERNAL (decl))
    {
      struct cgraph_node *node = cgraph_node::get (decl);

      /* Don't fix same_body aliases.  Although they don't have their own
	 CFG, they share it with what they alias to.  */
      if (!node || !node->alias || !node->num_references ())
	return true;
    }

  return false;
}

/* Clean the C++ specific parts of the tree T. */

void
cp_free_lang_data (tree t)
{
  if (FUNC_OR_METHOD_TYPE_P (t))
    {
      /* Default args are not interesting anymore.  */
      tree argtypes = TYPE_ARG_TYPES (t);
      while (argtypes)
        {
	  TREE_PURPOSE (argtypes) = 0;
	  argtypes = TREE_CHAIN (argtypes);
	}
    }
  else if (TREE_CODE (t) == FUNCTION_DECL
	   && cp_fix_function_decl_p (t))
    {
      /* If T is used in this translation unit at all,  the definition
	 must exist somewhere else since we have decided to not emit it
	 in this TU.  So make it an external reference.  */
      DECL_EXTERNAL (t) = 1;
      TREE_STATIC (t) = 0;
    }
  if (TREE_CODE (t) == NAMESPACE_DECL)
    /* We do not need the leftover chaining of namespaces from the
       binding level.  */
    DECL_CHAIN (t) = NULL_TREE;
}

/* Stub for c-common.  Please keep in sync with c-decl.cc.
   FIXME: If address space support is target specific, then this
   should be a C target hook.  But currently this is not possible,
   because this function is called via REGISTER_TARGET_PRAGMAS.  */
void
c_register_addr_space (const char * /*word*/, addr_space_t /*as*/)
{
}

/* Return the number of operands in T that we care about for things like
   mangling.  */

int
cp_tree_operand_length (const_tree t)
{
  enum tree_code code = TREE_CODE (t);

  if (TREE_CODE_CLASS (code) == tcc_vl_exp)
    return VL_EXP_OPERAND_LENGTH (t);

  return cp_tree_code_length (code);
}

/* Like cp_tree_operand_length, but takes a tree_code CODE.  */

int
cp_tree_code_length (enum tree_code code)
{
  gcc_assert (TREE_CODE_CLASS (code) != tcc_vl_exp);

  switch (code)
    {
    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      return 1;

    case ARRAY_REF:
      return 2;

    case EXPR_PACK_EXPANSION:
      return 1;

    default:
      return TREE_CODE_LENGTH (code);
    }
}

/* Like EXPR_LOCATION, but also handle some tcc_exceptional that have
   locations.  */

location_t
cp_expr_location (const_tree t_)
{
  tree t = CONST_CAST_TREE (t_);
  if (t == NULL_TREE)
    return UNKNOWN_LOCATION;
  switch (TREE_CODE (t))
    {
    case LAMBDA_EXPR:
      return LAMBDA_EXPR_LOCATION (t);
    case STATIC_ASSERT:
      return STATIC_ASSERT_SOURCE_LOCATION (t);
    case TRAIT_EXPR:
      return TRAIT_EXPR_LOCATION (t);
    case PTRMEM_CST:
      return PTRMEM_CST_LOCATION (t);
    default:
      return EXPR_LOCATION (t);
    }
}

/* Implement -Wzero_as_null_pointer_constant.  Return true if the
   conditions for the warning hold, false otherwise.  */
bool
maybe_warn_zero_as_null_pointer_constant (tree expr, location_t loc)
{
  if (c_inhibit_evaluation_warnings == 0
      && !null_node_p (expr) && !NULLPTR_TYPE_P (TREE_TYPE (expr)))
    {
      warning_at (loc, OPT_Wzero_as_null_pointer_constant,
		  "zero as null pointer constant");
      return true;
    }
  return false;
}

/* FNDECL is a function declaration whose type may have been altered by
   adding extra parameters such as this, in-charge, or VTT.  When this
   takes place, the positional arguments supplied by the user (as in the
   'format' attribute arguments) may refer to the wrong argument.  This
   function returns an integer indicating how many arguments should be
   skipped.  */

int
maybe_adjust_arg_pos_for_attribute (const_tree fndecl)
{
  if (!fndecl)
    return 0;
  int n = num_artificial_parms_for (fndecl);
  /* The manual states that it's the user's responsibility to account
     for the implicit this parameter.  */
  return n > 0 ? n - 1 : 0;
}


/* Release memory we no longer need after parsing.  */
void
cp_tree_c_finish_parsing ()
{
  if (previous_class_level)
    invalidate_class_lookup_cache ();
  deleted_copy_types = NULL;
}

#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
/* Complain that some language-specific thing hanging off a tree
   node has been accessed improperly.  */

void
lang_check_failed (const char* file, int line, const char* function)
{
  internal_error ("%<lang_*%> check: failed in %s, at %s:%d",
		  function, trim_filename (file), line);
}
#endif /* ENABLE_TREE_CHECKING */

#if CHECKING_P

namespace selftest {

/* Verify that lvalue_kind () works, for various expressions,
   and that location wrappers don't affect the results.  */

static void
test_lvalue_kind ()
{
  location_t loc = BUILTINS_LOCATION;

  /* Verify constants and parameters, without and with
     location wrappers.  */
  tree int_cst = build_int_cst (integer_type_node, 42);
  ASSERT_EQ (clk_none, lvalue_kind (int_cst));

  tree wrapped_int_cst = maybe_wrap_with_location (int_cst, loc);
  ASSERT_TRUE (location_wrapper_p (wrapped_int_cst));
  ASSERT_EQ (clk_none, lvalue_kind (wrapped_int_cst));

  tree string_lit = build_string (4, "foo");
  TREE_TYPE (string_lit) = char_array_type_node;
  string_lit = fix_string_type (string_lit);
  ASSERT_EQ (clk_ordinary, lvalue_kind (string_lit));

  tree wrapped_string_lit = maybe_wrap_with_location (string_lit, loc);
  ASSERT_TRUE (location_wrapper_p (wrapped_string_lit));
  ASSERT_EQ (clk_ordinary, lvalue_kind (wrapped_string_lit));

  tree parm = build_decl (UNKNOWN_LOCATION, PARM_DECL,
			  get_identifier ("some_parm"),
			  integer_type_node);
  ASSERT_EQ (clk_ordinary, lvalue_kind (parm));

  tree wrapped_parm = maybe_wrap_with_location (parm, loc);
  ASSERT_TRUE (location_wrapper_p (wrapped_parm));
  ASSERT_EQ (clk_ordinary, lvalue_kind (wrapped_parm));

  /* Verify that lvalue_kind of std::move on a parm isn't
     affected by location wrappers.  */
  tree rvalue_ref_of_parm = move (parm);
  ASSERT_EQ (clk_rvalueref, lvalue_kind (rvalue_ref_of_parm));
  tree rvalue_ref_of_wrapped_parm = move (wrapped_parm);
  ASSERT_EQ (clk_rvalueref, lvalue_kind (rvalue_ref_of_wrapped_parm));

  /* Verify lvalue_p.  */
  ASSERT_FALSE (lvalue_p (int_cst));
  ASSERT_FALSE (lvalue_p (wrapped_int_cst));
  ASSERT_TRUE (lvalue_p (parm));
  ASSERT_TRUE (lvalue_p (wrapped_parm));
  ASSERT_FALSE (lvalue_p (rvalue_ref_of_parm));
  ASSERT_FALSE (lvalue_p (rvalue_ref_of_wrapped_parm));
}

/* Run all of the selftests within this file.  */

void
cp_tree_cc_tests ()
{
  test_lvalue_kind ();
}

} // namespace selftest

#endif /* #if CHECKING_P */


#include "gt-cp-tree.h"
