/* Processing rules for constraints.
   Copyright (C) 2013-2022 Free Software Foundation, Inc.
   Contributed by Andrew Sutton (andrew.n.sutton@gmail.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 "tm.h"
#include "timevar.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"
#include "intl.h"
#include "flags.h"
#include "cp-tree.h"
#include "c-family/c-common.h"
#include "c-family/c-objc.h"
#include "cp-objcp-common.h"
#include "tree-inline.h"
#include "decl.h"
#include "toplev.h"
#include "type-utils.h"

static tree satisfaction_value (tree t);

/* When we're parsing or substuting a constraint expression, we have slightly
   different expression semantics.  In particular, we don't want to reduce a
   concept-id to a satisfaction value.  */

processing_constraint_expression_sentinel::
processing_constraint_expression_sentinel ()
{
  ++scope_chain->x_processing_constraint;
}

processing_constraint_expression_sentinel::
~processing_constraint_expression_sentinel ()
{
  --scope_chain->x_processing_constraint;
}

bool
processing_constraint_expression_p ()
{
  return scope_chain->x_processing_constraint != 0;
}

/*---------------------------------------------------------------------------
		       Constraint expressions
---------------------------------------------------------------------------*/

/* Information provided to substitution.  */

struct subst_info
{
  subst_info (tsubst_flags_t cmp, tree in)
    : complain (cmp), in_decl (in)
  { }

  /* True if we should not diagnose errors.  */
  bool quiet() const
  {
    return complain == tf_none;
  }

  /* True if we should diagnose errors.  */
  bool noisy() const
  {
    return !quiet ();
  }

  tsubst_flags_t complain;
  tree in_decl;
};

/* Provides additional context for satisfaction.

   During satisfaction:
    - The flag noisy() controls whether to diagnose ill-formed satisfaction,
      such as the satisfaction value of an atom being non-bool or non-constant.
    - The flag diagnose_unsatisfaction_p() controls whether to additionally
      explain why a constraint is not satisfied.
    - We enter satisfaction with noisy+unsat from diagnose_constraints.
    - We enter satisfaction with noisy-unsat from the replay inside
      constraint_satisfaction_value.
    - We enter satisfaction quietly (both flags cleared) from
      constraints_satisfied_p.

   During evaluation of a requires-expression:
    - The flag noisy() controls whether to diagnose ill-formed types and
      expressions inside its requirements.
    - The flag diagnose_unsatisfaction_p() controls whether to additionally
      explain why the requires-expression evaluates to false.
    - We enter tsubst_requires_expr with noisy+unsat from
      diagnose_atomic_constraint and potentially from
      satisfy_nondeclaration_constraints.
    - We enter tsubst_requires_expr with noisy-unsat from
      cp_parser_requires_expression when processing a requires-expression that
      appears outside a template.
    - We enter tsubst_requires_expr quietly (both flags cleared) when
      substituting through a requires-expression as part of template
      instantiation.  */

struct sat_info : subst_info
{
  sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false)
    : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat)
  {
    if (diagnose_unsatisfaction_p ())
      gcc_checking_assert (noisy ());
  }

  /* True if we should diagnose the cause of satisfaction failure.
     Implies noisy().  */
  bool
  diagnose_unsatisfaction_p () const
  {
    return diagnose_unsatisfaction;
  }

  bool diagnose_unsatisfaction;
};

static tree constraint_satisfaction_value (tree, tree, sat_info);

/* True if T is known to be some type other than bool. Note that this
   is false for dependent types and errors.  */

static inline bool
known_non_bool_p (tree t)
{
  return (t && !WILDCARD_TYPE_P (t) && TREE_CODE (t) != BOOLEAN_TYPE);
}

static bool
check_constraint_atom (cp_expr expr)
{
  if (known_non_bool_p (TREE_TYPE (expr)))
    {
      error_at (expr.get_location (),
		"constraint expression does not have type %<bool%>");
      return false;
    }

  /* Check that we're using function concepts correctly.  */
  if (concept_check_p (expr))
    {
      tree id = unpack_concept_check (expr);
      tree tmpl = TREE_OPERAND (id, 0);
      if (OVL_P (tmpl) && TREE_CODE (expr) == TEMPLATE_ID_EXPR)
        {
	  error_at (EXPR_LOC_OR_LOC (expr, input_location),
		    "function concept must be called");
	  return false;
	}
    }

  return true;
}

static bool
check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
{
  return check_constraint_atom (lhs) && check_constraint_atom (rhs);
}

/* Validate the semantic properties of the constraint expression.  */

static cp_expr
finish_constraint_binary_op (location_t loc,
			     tree_code code,
			     cp_expr lhs,
			     cp_expr rhs)
{
  gcc_assert (processing_constraint_expression_p ());
  if (lhs == error_mark_node || rhs == error_mark_node)
    return error_mark_node;
  if (!check_constraint_operands (loc, lhs, rhs))
    return error_mark_node;
  cp_expr expr
    = build_min_nt_loc (loc, code, lhs.get_value (), rhs.get_value ());
  expr.set_range (lhs.get_start (), rhs.get_finish ());
  return expr;
}

cp_expr
finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
{
  return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
}

cp_expr
finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
{
  return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
}

cp_expr
finish_constraint_primary_expr (cp_expr expr)
{
  if (expr == error_mark_node)
    return error_mark_node;
  if (!check_constraint_atom (expr))
    return cp_expr (error_mark_node, expr.get_location ());
  return expr;
}

/* Combine two constraint-expressions with a logical-and.  */

tree
combine_constraint_expressions (tree lhs, tree rhs)
{
  processing_constraint_expression_sentinel pce;
  if (!lhs)
    return rhs;
  if (!rhs)
    return lhs;
  return finish_constraint_and_expr (input_location, lhs, rhs);
}

/* Extract the template-id from a concept check. For standard and variable
   checks, this is simply T. For function concept checks, this is the
   called function.  */

tree
unpack_concept_check (tree t)
{
  gcc_assert (concept_check_p (t));

  if (TREE_CODE (t) == CALL_EXPR)
    t = CALL_EXPR_FN (t);

  gcc_assert (TREE_CODE (t) == TEMPLATE_ID_EXPR);
  return t;
}

/* Extract the TEMPLATE_DECL from a concept check.  */

tree
get_concept_check_template (tree t)
{
  tree id = unpack_concept_check (t);
  tree tmpl = TREE_OPERAND (id, 0);
  if (OVL_P (tmpl))
    tmpl = OVL_FIRST (tmpl);
  return tmpl;
}

/*---------------------------------------------------------------------------
                    Resolution of qualified concept names
---------------------------------------------------------------------------*/

/* This facility is used to resolve constraint checks from requirement
   expressions. A constraint check is a call to a function template declared
   with the keyword 'concept'.

   The result of resolution is a pair (a TREE_LIST) whose value is the
   matched declaration, and whose purpose contains the coerced template
   arguments that can be substituted into the call.  */

/* Given an overload set OVL, try to find a unique definition that can be
   instantiated by the template arguments ARGS.

   This function is not called for arbitrary call expressions. In particular,
   the call expression must be written with explicit template arguments
   and no function arguments. For example:

        f<T, U>()

   If a single match is found, this returns a TREE_LIST whose VALUE
   is the constraint function (not the template), and its PURPOSE is
   the complete set of arguments substituted into the parameter list.  */

static tree
resolve_function_concept_overload (tree ovl, tree args)
{
  int nerrs = 0;
  tree cands = NULL_TREE;
  for (lkp_iterator iter (ovl); iter; ++iter)
    {
      tree tmpl = *iter;
      if (TREE_CODE (tmpl) != TEMPLATE_DECL)
        continue;

      /* Don't try to deduce checks for non-concepts. We often end up trying
         to resolve constraints in functional casts as part of a
         postfix-expression. We can save time and headaches by not
         instantiating those declarations.

         NOTE: This masks a potential error, caused by instantiating
         non-deduced contexts using placeholder arguments. */
      tree fn = DECL_TEMPLATE_RESULT (tmpl);
      if (DECL_ARGUMENTS (fn))
        continue;
      if (!DECL_DECLARED_CONCEPT_P (fn))
        continue;

      /* Remember the candidate if we can deduce a substitution.  */
      ++processing_template_decl;
      tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
      if (tree subst = coerce_template_parms (parms, args, tmpl))
        {
          if (subst == error_mark_node)
            ++nerrs;
          else
	    cands = tree_cons (subst, fn, cands);
        }
      --processing_template_decl;
    }

  if (!cands)
    /* We either had no candidates or failed deductions.  */
    return nerrs ? error_mark_node : NULL_TREE;
  else if (TREE_CHAIN (cands))
    /* There are multiple candidates.  */
    return error_mark_node;

  return cands;
}

/* Determine if the call expression CALL is a constraint check, and
   return the concept declaration and arguments being checked. If CALL
   does not denote a constraint check, return NULL.  */

tree
resolve_function_concept_check (tree call)
{
  gcc_assert (TREE_CODE (call) == CALL_EXPR);

  /* A constraint check must be only a template-id expression.
     If it's a call to a base-link, its function(s) should be a
     template-id expression. If this is not a template-id, then
     it cannot be a concept-check.  */
  tree target = CALL_EXPR_FN (call);
  if (BASELINK_P (target))
    target = BASELINK_FUNCTIONS (target);
  if (TREE_CODE (target) != TEMPLATE_ID_EXPR)
    return NULL_TREE;

  /* Get the overload set and template arguments and try to
     resolve the target.  */
  tree ovl = TREE_OPERAND (target, 0);

  /* This is a function call of a variable concept... ill-formed.  */
  if (TREE_CODE (ovl) == TEMPLATE_DECL)
    {
      error_at (location_of (call),
		"function call of variable concept %qE", call);
      return error_mark_node;
    }

  tree args = TREE_OPERAND (target, 1);
  return resolve_function_concept_overload (ovl, args);
}

/* Returns a pair containing the checked concept and its associated
   prototype parameter. The result is a TREE_LIST whose TREE_VALUE
   is the concept (non-template) and whose TREE_PURPOSE contains
   the converted template arguments, including the deduced prototype
   parameter (in position 0). */

tree
resolve_concept_check (tree check)
{
  gcc_assert (concept_check_p (check));
  tree id = unpack_concept_check (check);
  tree tmpl = TREE_OPERAND (id, 0);

  /* If this is an overloaded function concept, perform overload
     resolution (this only happens when deducing prototype parameters
     and template introductions).  */
  if (TREE_CODE (tmpl) == OVERLOAD)
    {
      if (OVL_CHAIN (tmpl))
	return resolve_function_concept_check (check);
      tmpl = OVL_FIRST (tmpl);
    }

  tree args = TREE_OPERAND (id, 1);
  tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
  ++processing_template_decl;
  tree result = coerce_template_parms (parms, args, tmpl);
  --processing_template_decl;
  if (result == error_mark_node)
    return error_mark_node;
  return build_tree_list (result, DECL_TEMPLATE_RESULT (tmpl));
}

/* Given a call expression or template-id expression to a concept EXPR
   possibly including a wildcard, deduce the concept being checked and
   the prototype parameter. Returns true if the constraint and prototype
   can be deduced and false otherwise.  Note that the CHECK and PROTO
   arguments are set to NULL_TREE if this returns false.  */

bool
deduce_constrained_parameter (tree expr, tree& check, tree& proto)
{
  tree info = resolve_concept_check (expr);
  if (info && info != error_mark_node)
    {
      check = TREE_VALUE (info);
      tree arg = TREE_VEC_ELT (TREE_PURPOSE (info), 0);
      if (ARGUMENT_PACK_P (arg))
	arg = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0);
      proto = TREE_TYPE (arg);
      return true;
    }

  check = proto = NULL_TREE;
  return false;
}

/* Given a call expression or template-id expression to a concept, EXPR,
   deduce the concept being checked and return the template arguments.
   Returns NULL_TREE if deduction fails.  */
static tree
deduce_concept_introduction (tree check)
{
  tree info = resolve_concept_check (check);
  if (info && info != error_mark_node)
    return TREE_PURPOSE (info);
  return NULL_TREE;
}

/* Build a constrained placeholder type where SPEC is a type-constraint.
   SPEC can be anything were concept_definition_p is true.

   Returns a pair whose FIRST is the concept being checked and whose
   SECOND is the prototype parameter.  */

tree_pair
finish_type_constraints (tree spec, tree args, tsubst_flags_t complain)
{
  gcc_assert (concept_definition_p (spec));

  /* Build an initial concept check.  */
  tree check = build_type_constraint (spec, args, complain);
  if (check == error_mark_node)
    return std::make_pair (error_mark_node, NULL_TREE);

  /* Extract the concept and prototype parameter from the check. */
  tree con;
  tree proto;
  if (!deduce_constrained_parameter (check, con, proto))
    return std::make_pair (error_mark_node, NULL_TREE);

  return std::make_pair (con, proto);
}

/*---------------------------------------------------------------------------
                       Expansion of concept definitions
---------------------------------------------------------------------------*/

/* Returns the expression of a function concept. */

static tree
get_returned_expression (tree fn)
{
  /* Extract the body of the function minus the return expression.  */
  tree body = DECL_SAVED_TREE (fn);
  if (!body)
    return error_mark_node;
  if (TREE_CODE (body) == BIND_EXPR)
    body = BIND_EXPR_BODY (body);
  if (TREE_CODE (body) != RETURN_EXPR)
    return error_mark_node;

  return TREE_OPERAND (body, 0);
}

/* Returns the initializer of a variable concept. */

static tree
get_variable_initializer (tree var)
{
  tree init = DECL_INITIAL (var);
  if (!init)
    return error_mark_node;
  if (BRACE_ENCLOSED_INITIALIZER_P (init)
      && CONSTRUCTOR_NELTS (init) == 1)
    init = CONSTRUCTOR_ELT (init, 0)->value;
  return init;
}

/* Returns the definition of a variable or function concept.  */

static tree
get_concept_definition (tree decl)
{
  if (TREE_CODE (decl) == OVERLOAD)
    decl = OVL_FIRST (decl);

  if (TREE_CODE (decl) == TEMPLATE_DECL)
    decl = DECL_TEMPLATE_RESULT (decl);

  if (TREE_CODE (decl) == CONCEPT_DECL)
    return DECL_INITIAL (decl);
  if (VAR_P (decl))
    return get_variable_initializer (decl);
  if (TREE_CODE (decl) == FUNCTION_DECL)
    return get_returned_expression (decl);
  gcc_unreachable ();
}

/*---------------------------------------------------------------------------
		      Normalization of expressions

This set of functions will transform an expression into a constraint
in a sequence of steps.
---------------------------------------------------------------------------*/

void
debug_parameter_mapping (tree map)
{
  for (tree p = map; p; p = TREE_CHAIN (p))
    {
      tree parm = TREE_VALUE (p);
      tree arg = TREE_PURPOSE (p);
      if (TYPE_P (parm))
	verbatim ("MAP %qD TO %qT", TEMPLATE_TYPE_DECL (parm), arg);
      else
	verbatim ("MAP %qD TO %qE", TEMPLATE_PARM_DECL (parm), arg);
      // debug_tree (parm);
      // debug_tree (arg);
    }
}

void
debug_argument_list (tree args)
{
  for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
    {
      tree arg = TREE_VEC_ELT (args, i);
      if (TYPE_P (arg))
	verbatim ("argument %qT", arg);
      else
	verbatim ("argument %qE", arg);
    }
}

/* Associate each parameter in PARMS with its corresponding template
   argument in ARGS.  */

static tree
map_arguments (tree parms, tree args)
{
  for (tree p = parms; p; p = TREE_CHAIN (p))
    if (args)
      {
	int level;
	int index;
	template_parm_level_and_index (TREE_VALUE (p), &level, &index);
	TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
      }
    else
      TREE_PURPOSE (p) = template_parm_to_arg (p);

  return parms;
}

/* Build the parameter mapping for EXPR using ARGS, where CTX_PARMS
   are the template parameters in scope for EXPR.  */

static tree
build_parameter_mapping (tree expr, tree args, tree ctx_parms)
{
  tree parms = find_template_parameters (expr, ctx_parms);
  tree map = map_arguments (parms, args);
  return map;
}

/* True if the parameter mappings of two atomic constraints formed
   from the same expression are equivalent.  */

static bool
parameter_mapping_equivalent_p (tree t1, tree t2)
{
  tree map1 = ATOMIC_CONSTR_MAP (t1);
  tree map2 = ATOMIC_CONSTR_MAP (t2);
  while (map1 && map2)
    {
      gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2));
      tree arg1 = TREE_PURPOSE (map1);
      tree arg2 = TREE_PURPOSE (map2);
      if (!template_args_equal (arg1, arg2))
        return false;
      map1 = TREE_CHAIN (map1);
      map2 = TREE_CHAIN (map2);
    }
  gcc_checking_assert (!map1 && !map2);
  return true;
}

/* Provides additional context for normalization.  */

struct norm_info : subst_info
{
  explicit norm_info (tsubst_flags_t cmp)
    : norm_info (NULL_TREE, cmp)
  {}

  /* Construct a top-level context for DECL.  */

  norm_info (tree in_decl, tsubst_flags_t complain)
    : subst_info (tf_warning_or_error | complain, in_decl)
  {
    if (in_decl)
      {
	initial_parms = DECL_TEMPLATE_PARMS (in_decl);
	if (generate_diagnostics ())
	  context = build_tree_list (NULL_TREE, in_decl);
      }
    else
      initial_parms = current_template_parms;
  }

  bool generate_diagnostics() const
  {
    return complain & tf_norm;
  }

  void update_context(tree expr, tree args)
  {
    if (generate_diagnostics ())
      {
	tree map = build_parameter_mapping (expr, args, ctx_parms ());
	context = tree_cons (map, expr, context);
      }
    in_decl = get_concept_check_template (expr);
  }

  /* Returns the template parameters that are in scope for the current
     normalization context.  */

  tree ctx_parms()
  {
    if (in_decl)
      return DECL_TEMPLATE_PARMS (in_decl);
    else
      return initial_parms;
  }

  /* Provides information about the source of a constraint. This is a
     TREE_LIST whose VALUE is either a concept check or a constrained
     declaration. The PURPOSE, for concept checks is a parameter mapping
     for that check.  */

  tree context = NULL_TREE;

  /* The declaration whose constraints we're normalizing.  The targets
     of the parameter mapping of each atom will be in terms of the
     template parameters of ORIG_DECL.  */

  tree initial_parms = NULL_TREE;
};

static tree normalize_expression (tree, tree, norm_info);

/* Transform a logical-or or logical-and expression into either
   a conjunction or disjunction. */

static tree
normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
{
  tree t0 = normalize_expression (TREE_OPERAND (t, 0), args, info);
  tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);

  /* Build a new info object for the constraint.  */
  tree ci = info.generate_diagnostics()
    ? build_tree_list (t, info.context)
    : NULL_TREE;

  return build2 (c, ci, t0, t1);
}

static tree
normalize_concept_check (tree check, tree args, norm_info info)
{
  tree id = unpack_concept_check (check);
  tree tmpl = TREE_OPERAND (id, 0);
  tree targs = TREE_OPERAND (id, 1);

  /* A function concept is wrapped in an overload.  */
  if (TREE_CODE (tmpl) == OVERLOAD)
    {
      /* TODO: Can we diagnose this error during parsing?  */
      if (TREE_CODE (check) == TEMPLATE_ID_EXPR)
	error_at (EXPR_LOC_OR_LOC (check, input_location),
		  "function concept must be called");
      tmpl = OVL_FIRST (tmpl);
    }

  /* Substitute through the arguments of the concept check. */
  if (args)
    targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
  if (targs == error_mark_node)
    return error_mark_node;

  /* Build the substitution for the concept definition.  */
  tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
  /* Turn on template processing; coercing non-type template arguments
     will automatically assume they're non-dependent.  */
  ++processing_template_decl;
  tree subst = coerce_template_parms (parms, targs, tmpl);
  --processing_template_decl;
  if (subst == error_mark_node)
    return error_mark_node;

  /* The concept may have been ill-formed.  */
  tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
  if (def == error_mark_node)
    return error_mark_node;

  info.update_context (check, args);
  return normalize_expression (def, subst, info);
}

/* Used by normalize_atom to cache ATOMIC_CONSTRs.  */

static GTY((deletable)) hash_table<atom_hasher> *atom_cache;

/* The normal form of an atom depends on the expression. The normal
   form of a function call to a function concept is a check constraint
   for that concept. The normal form of a reference to a variable
   concept is a check constraint for that concept. Otherwise, the
   constraint is a predicate constraint.  */

static tree
normalize_atom (tree t, tree args, norm_info info)
{
  /* Concept checks are not atomic.  */
  if (concept_check_p (t))
    return normalize_concept_check (t, args, info);

  /* Build the parameter mapping for the atom.  */
  tree map = build_parameter_mapping (t, args, info.ctx_parms ());

  /* Build a new info object for the atom.  */
  tree ci = build_tree_list (t, info.context);

  tree atom = build1 (ATOMIC_CONSTR, ci, map);

  /* Remember whether the expression of this atomic constraint belongs to
     a concept definition by inspecting in_decl, which should always be set
     in this case either by norm_info::update_context (when recursing into a
     concept-id during normalization) or by normalize_concept_definition
     (when starting out with a concept-id).  */
  if (info.in_decl && concept_definition_p (info.in_decl))
    ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (atom) = true;

  if (!info.generate_diagnostics ())
    {
      /* Cache the ATOMIC_CONSTRs that we return, so that sat_hasher::equal
	 later can cheaply compare two atoms using just pointer equality.  */
      if (!atom_cache)
	atom_cache = hash_table<atom_hasher>::create_ggc (31);
      tree *slot = atom_cache->find_slot (atom, INSERT);
      if (*slot)
	return *slot;

      /* Find all template parameters used in the targets of the parameter
	 mapping, and store a list of them in the TREE_TYPE of the mapping.
	 This list will be used by sat_hasher to determine the subset of
	 supplied template arguments that the satisfaction value of the atom
	 depends on.  */
      if (map)
	{
	  tree targets = make_tree_vec (list_length (map));
	  int i = 0;
	  for (tree node = map; node; node = TREE_CHAIN (node))
	    {
	      tree target = TREE_PURPOSE (node);
	      TREE_VEC_ELT (targets, i++) = target;
	    }
	  tree target_parms = find_template_parameters (targets,
							info.initial_parms);
	  TREE_TYPE (map) = target_parms;
	}

      *slot = atom;
    }
  return atom;
}

/* Returns the normal form of an expression. */

static tree
normalize_expression (tree t, tree args, norm_info info)
{
  if (!t)
    return NULL_TREE;

  if (t == error_mark_node)
    return error_mark_node;

  switch (TREE_CODE (t))
    {
    case TRUTH_ANDIF_EXPR:
      return normalize_logical_operation (t, args, CONJ_CONSTR, info);
    case TRUTH_ORIF_EXPR:
      return normalize_logical_operation (t, args, DISJ_CONSTR, info);
    default:
      return normalize_atom (t, args, info);
    }
}

/* Cache of the normalized form of constraints.  Marked as deletable because it
   can all be recalculated.  */
static GTY((deletable)) hash_map<tree,tree> *normalized_map;

static tree
get_normalized_constraints (tree t, norm_info info)
{
  auto_timevar time (TV_CONSTRAINT_NORM);
  return normalize_expression (t, NULL_TREE, info);
}

/* Returns the normalized constraints from a constraint-info object
   or NULL_TREE if the constraints are null. IN_DECL provides the
   declaration to which the constraints belong.  */

static tree
get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
{
  if (ci == NULL_TREE)
    return NULL_TREE;

  /* Substitution errors during normalization are fatal.  */
  ++processing_template_decl;
  norm_info info (in_decl, diag ? tf_norm : tf_none);
  tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci), info);
  --processing_template_decl;

  return t;
}

/* Returns the normalized constraints for the declaration D.  */

static tree
get_normalized_constraints_from_decl (tree d, bool diag = false)
{
  tree tmpl;
  tree decl;

  /* For inherited constructors, consider the original declaration;
     it has the correct template information attached. */
  d = strip_inheriting_ctors (d);

  if (regenerated_lambda_fn_p (d))
    {
      /* If this lambda was regenerated, DECL_TEMPLATE_PARMS doesn't contain
	 all in-scope template parameters, but the lambda from which it was
	 ultimately regenerated does, so use that instead.  */
      tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (d));
      lambda = most_general_lambda (lambda);
      d = lambda_function (lambda);
    }

  if (TREE_CODE (d) == TEMPLATE_DECL)
    {
      tmpl = d;
      decl = DECL_TEMPLATE_RESULT (tmpl);
    }
  else
    {
      if (tree ti = DECL_TEMPLATE_INFO (d))
	tmpl = TI_TEMPLATE (ti);
      else
	tmpl = NULL_TREE;
      decl = d;
    }

  /* Get the most general template for the declaration, and compute
     arguments from that. This ensures that the arguments used for
     normalization are always template parameters and not arguments
     used for outer specializations.  For example:

        template<typename T>
        struct S {
	  template<typename U> requires C<T, U> void f(U);
        };

        S<int>::f(0);

     When we normalize the requirements for S<int>::f, we want the
     arguments to be {T, U}, not {int, U}. One reason for this is that
     accepting the latter causes the template parameter level of U
     to be reduced in a way that makes it overly difficult substitute
     concrete arguments (i.e., eventually {int, int} during satisfaction.  */
  if (tmpl)
  {
    if (DECL_LANG_SPECIFIC(tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
      tmpl = most_general_template (tmpl);
  }

  d = tmpl ? tmpl : decl;

  /* If we're not diagnosing errors, use cached constraints, if any.  */
  if (!diag)
    if (tree *p = hash_map_safe_get (normalized_map, d))
      return *p;

  tree norm = NULL_TREE;
  if (tree ci = get_constraints (d))
    {
      push_access_scope_guard pas (decl);
      norm = get_normalized_constraints_from_info (ci, tmpl, diag);
    }

  if (!diag)
    hash_map_safe_put<hm_ggc> (normalized_map, d, norm);

  return norm;
}

/* Returns the normal form of TMPL's definition.  */

static tree
normalize_concept_definition (tree tmpl, bool diag = false)
{
  if (!diag)
    if (tree *p = hash_map_safe_get (normalized_map, tmpl))
      return *p;

  gcc_assert (concept_definition_p (tmpl));
  if (OVL_P (tmpl))
    tmpl = OVL_FIRST (tmpl);
  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
  tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
  ++processing_template_decl;
  norm_info info (tmpl, diag ? tf_norm : tf_none);
  tree norm = get_normalized_constraints (def, info);
  --processing_template_decl;

  if (!diag)
    hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);

  return norm;
}

/* Normalize an EXPR as a constraint.  */

static tree
normalize_constraint_expression (tree expr, norm_info info)
{
  if (!expr || expr == error_mark_node)
    return expr;

  if (!info.generate_diagnostics ())
    if (tree *p = hash_map_safe_get (normalized_map, expr))
      return *p;

  ++processing_template_decl;
  tree norm = get_normalized_constraints (expr, info);
  --processing_template_decl;

  if (!info.generate_diagnostics ())
    hash_map_safe_put<hm_ggc> (normalized_map, expr, norm);

  return norm;
}

/* 17.4.1.2p2. Two constraints are identical if they are formed
   from the same expression and the targets of the parameter mapping
   are equivalent.  */

bool
atomic_constraints_identical_p (tree t1, tree t2)
{
  gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR);
  gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR);

  if (ATOMIC_CONSTR_EXPR (t1) != ATOMIC_CONSTR_EXPR (t2))
    return false;

  if (!parameter_mapping_equivalent_p (t1, t2))
    return false;

  return true;
}

/* True if T1 and T2 are equivalent, meaning they have the same syntactic
   structure and all corresponding constraints are identical.  */

bool
constraints_equivalent_p (tree t1, tree t2)
{
  gcc_assert (CONSTR_P (t1));
  gcc_assert (CONSTR_P (t2));

  if (TREE_CODE (t1) != TREE_CODE (t2))
    return false;

  switch (TREE_CODE (t1))
  {
  case CONJ_CONSTR:
  case DISJ_CONSTR:
    if (!constraints_equivalent_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
      return false;
    if (!constraints_equivalent_p (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)))
      return false;
    break;
  case ATOMIC_CONSTR:
    if (!atomic_constraints_identical_p(t1, t2))
      return false;
    break;
  default:
    gcc_unreachable ();
  }
  return true;
}

/* Compute the hash value for T.  */

hashval_t
hash_atomic_constraint (tree t)
{
  gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);

  /* Hash the identity of the expression.  */
  hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t));

  /* Hash the targets of the parameter map.  */
  tree p = ATOMIC_CONSTR_MAP (t);
  while (p)
    {
      val = iterative_hash_template_arg (TREE_PURPOSE (p), val);
      p = TREE_CHAIN (p);
    }

  return val;
}

namespace inchash
{

static void
add_constraint (tree t, hash& h)
{
  h.add_int(TREE_CODE (t));
  switch (TREE_CODE (t))
  {
  case CONJ_CONSTR:
  case DISJ_CONSTR:
    add_constraint (TREE_OPERAND (t, 0), h);
    add_constraint (TREE_OPERAND (t, 1), h);
    break;
  case ATOMIC_CONSTR:
    h.merge_hash (hash_atomic_constraint (t));
    break;
  default:
    gcc_unreachable ();
  }
}

}

/* Computes a hash code for the constraint T.  */

hashval_t
iterative_hash_constraint (tree t, hashval_t val)
{
  gcc_assert (CONSTR_P (t));
  inchash::hash h (val);
  inchash::add_constraint (t, h);
  return h.end ();
}

// -------------------------------------------------------------------------- //
// Constraint Semantic Processing
//
// The following functions are called by the parser and substitution rules
// to create and evaluate constraint-related nodes.

// The constraints associated with the current template parameters.
tree
current_template_constraints (void)
{
  if (!current_template_parms)
    return NULL_TREE;
  tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
  return build_constraints (tmpl_constr, NULL_TREE);
}

/* If the recently parsed TYPE declares or defines a template or
   template specialization, get its corresponding constraints from the
   current template parameters and bind them to TYPE's declaration.  */

tree
associate_classtype_constraints (tree type)
{
  if (!type || type == error_mark_node || !CLASS_TYPE_P (type))
    return type;

  /* An explicit class template specialization has no template parameters.  */
  if (!current_template_parms)
    return type;

  if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
    {
      tree decl = TYPE_STUB_DECL (type);
      tree ci = current_template_constraints ();

      /* An implicitly instantiated member template declaration already
	 has associated constraints. If it is defined outside of its
	 class, then we need match these constraints against those of
	 original declaration.  */
      if (tree orig_ci = get_constraints (decl))
        {
	  if (int extra_levels = (TMPL_PARMS_DEPTH (current_template_parms)
				  - TMPL_ARGS_DEPTH (TYPE_TI_ARGS (type))))
	    {
	      /* If there is a discrepancy between the current template depth
		 and the template depth of the original declaration, then we
		 must be redeclaring a class template as part of a friend
		 declaration within another class template.  Before matching
		 constraints, we need to reduce the template parameter level
		 within the current constraints via substitution.  */
	      tree outer_gtargs = template_parms_to_args (current_template_parms);
	      TREE_VEC_LENGTH (outer_gtargs) = extra_levels;
	      ci = tsubst_constraint_info (ci, outer_gtargs, tf_none, NULL_TREE);
	    }
          if (!equivalent_constraints (ci, orig_ci))
            {
	      error ("%qT does not match original declaration", type);
	      tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
	      location_t loc = DECL_SOURCE_LOCATION (tmpl);
	      inform (loc, "original template declaration here");
	      /* Fall through, so that we define the type anyway.  */
            }
          return type;
        }
      set_constraints (decl, ci);
    }
  return type;
}

/* Create an empty constraint info block.  */

static inline tree_constraint_info*
build_constraint_info ()
{
  return (tree_constraint_info *)make_node (CONSTRAINT_INFO);
}

/* Build a constraint-info object that contains the associated constraints
   of a declaration.  This also includes the declaration's template
   requirements (TREQS) and any trailing requirements for a function
   declarator (DREQS).  Note that both TREQS and DREQS must be constraints.

   If the declaration has neither template nor declaration requirements
   this returns NULL_TREE, indicating an unconstrained declaration.  */

tree
build_constraints (tree tr, tree dr)
{
  if (!tr && !dr)
    return NULL_TREE;

  tree_constraint_info* ci = build_constraint_info ();
  ci->template_reqs = tr;
  ci->declarator_reqs = dr;
  ci->associated_constr = combine_constraint_expressions (tr, dr);

  return (tree)ci;
}

/* Add constraint RHS to the end of CONSTRAINT_INFO ci.  */

tree
append_constraint (tree ci, tree rhs)
{
  tree tr = ci ? CI_TEMPLATE_REQS (ci) : NULL_TREE;
  tree dr = ci ? CI_DECLARATOR_REQS (ci) : NULL_TREE;
  dr = combine_constraint_expressions (dr, rhs);
  if (ci)
    {
      CI_DECLARATOR_REQS (ci) = dr;
      tree ac = combine_constraint_expressions (tr, dr);
      CI_ASSOCIATED_CONSTRAINTS (ci) = ac;
    }
  else
    ci = build_constraints (tr, dr);
  return ci;
}

/* A mapping from declarations to constraint information.  */

static GTY ((cache)) decl_tree_cache_map *decl_constraints;

/* Returns the template constraints of declaration T. If T is not
   constrained, return NULL_TREE. Note that T must be non-null. */

tree
get_constraints (const_tree t)
{
  if (!flag_concepts)
    return NULL_TREE;
  if (!decl_constraints)
    return NULL_TREE;

  gcc_assert (DECL_P (t));
  if (TREE_CODE (t) == TEMPLATE_DECL)
    t = DECL_TEMPLATE_RESULT (t);
  tree* found = decl_constraints->get (CONST_CAST_TREE (t));
  if (found)
    return *found;
  else
    return NULL_TREE;
}

/* Associate the given constraint information CI with the declaration
   T. If T is a template, then the constraints are associated with
   its underlying declaration. Don't build associations if CI is
   NULL_TREE.  */

void
set_constraints (tree t, tree ci)
{
  if (!ci)
    return;
  gcc_assert (t && flag_concepts);
  if (TREE_CODE (t) == TEMPLATE_DECL)
    t = DECL_TEMPLATE_RESULT (t);
  bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
  gcc_assert (!found);
}

/* Remove the associated constraints of the declaration T.  */

void
remove_constraints (tree t)
{
  gcc_checking_assert (DECL_P (t));
  if (TREE_CODE (t) == TEMPLATE_DECL)
    t = DECL_TEMPLATE_RESULT (t);

  if (decl_constraints)
    decl_constraints->remove (t);
}

/* If DECL is a friend, substitute into REQS to produce requirements suitable
   for declaration matching.  */

tree
maybe_substitute_reqs_for (tree reqs, const_tree decl)
{
  if (reqs == NULL_TREE)
    return NULL_TREE;

  decl = STRIP_TEMPLATE (decl);
  if (DECL_UNIQUE_FRIEND_P (decl) && DECL_TEMPLATE_INFO (decl))
    {
      tree tmpl = DECL_TI_TEMPLATE (decl);
      tree gargs = generic_targs_for (tmpl);
      processing_template_decl_sentinel s;
      if (uses_template_parms (gargs))
	++processing_template_decl;
      reqs = tsubst_constraint (reqs, gargs,
				tf_warning_or_error, NULL_TREE);
    }
  return reqs;
}

/* Returns the trailing requires clause of the declarator of
   a template declaration T or NULL_TREE if none.  */

tree
get_trailing_function_requirements (tree t)
{
  tree ci = get_constraints (t);
  if (!ci)
    return NULL_TREE;
  return CI_DECLARATOR_REQS (ci);
}

/* Construct a sequence of template arguments by prepending
   ARG to REST. Either ARG or REST may be null. */
static tree
build_concept_check_arguments (tree arg, tree rest)
{
  gcc_assert (rest ? TREE_CODE (rest) == TREE_VEC : true);
  tree args;
  if (arg)
    {
      int n = rest ? TREE_VEC_LENGTH (rest) : 0;
      args = make_tree_vec (n + 1);
      TREE_VEC_ELT (args, 0) = arg;
      if (rest)
        for (int i = 0; i < n; ++i)
          TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i);
      int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0;
      SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
    }
  else
    {
      args = rest;
    }
  return args;
}

/* Builds an id-expression of the form `C<Args...>()` where C is a function
   concept.  */

static tree
build_function_check (tree tmpl, tree args, tsubst_flags_t /*complain*/)
{
  if (TREE_CODE (tmpl) == TEMPLATE_DECL)
    {
      /* If we just got a template, wrap it in an overload so it looks like any
	 other template-id. */
      tmpl = ovl_make (tmpl);
      TREE_TYPE (tmpl) = boolean_type_node;
    }

  /* Perform function concept resolution now so we always have a single
     function of the overload set (even if we started with only one; the
     resolution function converts template arguments). Note that we still
     wrap this in an overload set so we don't upset other parts of the
     compiler that expect template-ids referring to function concepts
     to have an overload set.  */
  tree info = resolve_function_concept_overload (tmpl, args);
  if (info == error_mark_node)
    return error_mark_node;
  if (!info)
    {
      error ("no matching concepts for %qE", tmpl);
      return error_mark_node;
    }
  args = TREE_PURPOSE (info);
  tmpl = DECL_TI_TEMPLATE (TREE_VALUE (info));

  /* Rebuild the singleton overload set; mark the type bool.  */
  tmpl = ovl_make (tmpl, NULL_TREE);
  TREE_TYPE (tmpl) = boolean_type_node;

  /* Build the id-expression around the overload set.  */
  tree id = build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);

  /* Finally, build the call expression around the overload.  */
  ++processing_template_decl;
  vec<tree, va_gc> *fargs = make_tree_vector ();
  tree call = build_min_nt_call_vec (id, fargs);
  TREE_TYPE (call) = boolean_type_node;
  release_tree_vector (fargs);
  --processing_template_decl;

  return call;
}

/* Builds an id-expression of the form `C<Args...>` where C is a variable
   concept.  */

static tree
build_variable_check (tree tmpl, tree args, tsubst_flags_t complain)
{
  gcc_assert (variable_concept_p (tmpl));
  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
  tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
  args = coerce_template_parms (parms, args, tmpl, complain);
  if (args == error_mark_node)
    return error_mark_node;
  return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
}

/* Builds an id-expression of the form `C<Args...>` where C is a standard
   concept.  */

static tree
build_standard_check (tree tmpl, tree args, tsubst_flags_t complain)
{
  gcc_assert (standard_concept_p (tmpl));
  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
  tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
  args = coerce_template_parms (parms, args, tmpl, complain);
  if (args == error_mark_node)
    return error_mark_node;
  return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
}

/* Construct an expression that checks TARGET using ARGS.  */

tree
build_concept_check (tree target, tree args, tsubst_flags_t complain)
{
  return build_concept_check (target, NULL_TREE, args, complain);
}

/* Construct an expression that checks the concept given by DECL. If
   concept_definition_p (DECL) is false, this returns null.  */

tree
build_concept_check (tree decl, tree arg, tree rest, tsubst_flags_t complain)
{
  tree args = build_concept_check_arguments (arg, rest);

  if (standard_concept_p (decl))
    return build_standard_check (decl, args, complain);
  if (variable_concept_p (decl))
    return build_variable_check (decl, args, complain);
  if (function_concept_p (decl))
    return build_function_check (decl, args, complain);

  return error_mark_node;
}

/* Build a template-id that can participate in a concept check.  */

static tree
build_concept_id (tree decl, tree args)
{
  tree check = build_concept_check (decl, args, tf_warning_or_error);
  if (check == error_mark_node)
    return error_mark_node;
  return unpack_concept_check (check);
}

/* Build a template-id that can participate in a concept check, preserving
   the source location of the original template-id.  */

tree
build_concept_id (tree expr)
{
  gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR);
  tree id = build_concept_id (TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
  protected_set_expr_location (id, cp_expr_location (expr));
  return id;
}

/* Build as template-id with a placeholder that can be used as a
   type constraint.

   Note that this will diagnose errors if the initial concept check
   cannot be built.  */

tree
build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
{
  tree wildcard = build_nt (WILDCARD_DECL);
  ++processing_template_decl;
  tree check = build_concept_check (decl, wildcard, args, complain);
  --processing_template_decl;
  if (check == error_mark_node)
    return error_mark_node;
  return unpack_concept_check (check);
}

/* Returns a TYPE_DECL that contains sufficient information to
   build a template parameter of the same kind as PROTO and
   constrained by the concept declaration CNC.  Note that PROTO
   is the first template parameter of CNC.

   If specified, ARGS provides additional arguments to the
   constraint check.  */
tree
build_constrained_parameter (tree cnc, tree proto, tree args)
{
  tree name = DECL_NAME (cnc);
  tree type = TREE_TYPE (proto);
  tree decl = build_decl (input_location, TYPE_DECL, name, type);
  CONSTRAINED_PARM_PROTOTYPE (decl) = proto;
  CONSTRAINED_PARM_CONCEPT (decl) = cnc;
  CONSTRAINED_PARM_EXTRA_ARGS (decl) = args;
  return decl;
}

/* Create a constraint expression for the given DECL that evaluates the
   requirements specified by CONSTR, a TYPE_DECL that contains all the
   information necessary to build the requirements (see finish_concept_name
   for the layout of that TYPE_DECL).

   Note that the constraints are neither reduced nor decomposed. That is
   done only after the requires clause has been parsed (or not).  */

tree
finish_shorthand_constraint (tree decl, tree constr)
{
  /* No requirements means no constraints.  */
  if (!constr)
    return NULL_TREE;

  if (error_operand_p (constr))
    return NULL_TREE;

  tree proto = CONSTRAINED_PARM_PROTOTYPE (constr);
  tree con = CONSTRAINED_PARM_CONCEPT (constr);
  tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr);

  /* The TS lets use shorthand to constrain a pack of arguments, but the
     standard does not.

     For the TS, consider:

	template<C... Ts> struct s;

     If C is variadic (and because Ts is a pack), we associate the
     constraint C<Ts...>. In all other cases, we associate
     the constraint (C<Ts> && ...).

     The standard behavior cannot be overridden by -fconcepts-ts.  */
  bool variadic_concept_p = template_parameter_pack_p (proto);
  bool declared_pack_p = template_parameter_pack_p (decl);
  bool apply_to_each_p = (cxx_dialect >= cxx20) ? true : !variadic_concept_p;

  /* Get the argument and overload used for the requirement
     and adjust it if we're going to expand later.  */
  tree arg = template_parm_to_arg (decl);
  if (apply_to_each_p && declared_pack_p)
    arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0));

  /* Build the concept constraint-expression.  */
  tree tmpl = DECL_TI_TEMPLATE (con);
  tree check = tmpl;
  if (TREE_CODE (con) == FUNCTION_DECL)
    check = ovl_make (tmpl);
  check = build_concept_check (check, arg, args, tf_warning_or_error);

  /* Make the check a fold-expression if needed.  */
  if (apply_to_each_p && declared_pack_p)
    check = finish_left_unary_fold_expr (check, TRUTH_ANDIF_EXPR);

  return check;
}

/* Returns a conjunction of shorthand requirements for the template
   parameter list PARMS. Note that the requirements are stored in
   the TYPE of each tree node. */

tree
get_shorthand_constraints (tree parms)
{
  tree result = NULL_TREE;
  parms = INNERMOST_TEMPLATE_PARMS (parms);
  for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
    {
      tree parm = TREE_VEC_ELT (parms, i);
      tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
      result = combine_constraint_expressions (result, constr);
    }
  return result;
}

/* Get the deduced wildcard from a DEDUCED placeholder.  If the deduced
   wildcard is a pack, return the first argument of that pack.  */

static tree
get_deduced_wildcard (tree wildcard)
{
  if (ARGUMENT_PACK_P (wildcard))
    wildcard = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (wildcard), 0);
  gcc_assert (TREE_CODE (wildcard) == WILDCARD_DECL);
  return wildcard;
}

/* Returns the prototype parameter for the nth deduced wildcard.  */

static tree
get_introduction_prototype (tree wildcards, int index)
{
  return TREE_TYPE (get_deduced_wildcard (TREE_VEC_ELT (wildcards, index)));
}

/* Introduce a type template parameter.  */

static tree
introduce_type_template_parameter (tree wildcard, bool& non_type_p)
{
  non_type_p = false;
  return finish_template_type_parm (class_type_node, DECL_NAME (wildcard));
}

/* Introduce a template template parameter.  */

static tree
introduce_template_template_parameter (tree wildcard, bool& non_type_p)
{
  non_type_p = false;
  begin_template_parm_list ();
  current_template_parms = DECL_TEMPLATE_PARMS (TREE_TYPE (wildcard));
  end_template_parm_list ();
  return finish_template_template_parm (class_type_node, DECL_NAME (wildcard));
}

/* Introduce a template non-type parameter.  */

static tree
introduce_nontype_template_parameter (tree wildcard, bool& non_type_p)
{
  non_type_p = true;
  tree parm = copy_decl (TREE_TYPE (wildcard));
  DECL_NAME (parm) = DECL_NAME (wildcard);
  return parm;
}

/* Introduce a single template parameter.  */

static tree
build_introduced_template_parameter (tree wildcard, bool& non_type_p)
{
  tree proto = TREE_TYPE (wildcard);

  tree parm;
  if (TREE_CODE (proto) == TYPE_DECL)
    parm = introduce_type_template_parameter (wildcard, non_type_p);
  else if (TREE_CODE (proto) == TEMPLATE_DECL)
    parm = introduce_template_template_parameter (wildcard, non_type_p);
  else
    parm = introduce_nontype_template_parameter (wildcard, non_type_p);

  /* Wrap in a TREE_LIST for process_template_parm. Note that introduced
     parameters do not retain the defaults from the source parameter.  */
  return build_tree_list (NULL_TREE, parm);
}

/* Introduce a single template parameter.  */

static tree
introduce_template_parameter (tree parms, tree wildcard)
{
  gcc_assert (!ARGUMENT_PACK_P (wildcard));
  tree proto = TREE_TYPE (wildcard);
  location_t loc = DECL_SOURCE_LOCATION (wildcard);

  /* Diagnose the case where we have C{...Args}.  */
  if (WILDCARD_PACK_P (wildcard))
    {
      tree id = DECL_NAME (wildcard);
      error_at (loc, "%qE cannot be introduced with an ellipsis %<...%>", id);
      inform (DECL_SOURCE_LOCATION (proto), "prototype declared here");
    }

  bool non_type_p;
  tree parm = build_introduced_template_parameter (wildcard, non_type_p);
  return process_template_parm (parms, loc, parm, non_type_p, false);
}

/* Introduce a template parameter pack.  */

static tree
introduce_template_parameter_pack (tree parms, tree wildcard)
{
  bool non_type_p;
  tree parm = build_introduced_template_parameter (wildcard, non_type_p);
  location_t loc = DECL_SOURCE_LOCATION (wildcard);
  return process_template_parm (parms, loc, parm, non_type_p, true);
}

/* Introduce the nth template parameter.  */

static tree
introduce_template_parameter (tree parms, tree wildcards, int& index)
{
  tree deduced = TREE_VEC_ELT (wildcards, index++);
  return introduce_template_parameter (parms, deduced);
}

/* Introduce either a template parameter pack or a list of template
   parameters.  */

static tree
introduce_template_parameters (tree parms, tree wildcards, int& index)
{
  /* If the prototype was a parameter, we better have deduced an
     argument pack, and that argument must be the last deduced value
     in the wildcard vector.  */
  tree deduced = TREE_VEC_ELT (wildcards, index++);
  gcc_assert (ARGUMENT_PACK_P (deduced));
  gcc_assert (index == TREE_VEC_LENGTH (wildcards));

  /* Introduce each element in the pack.  */
  tree args = ARGUMENT_PACK_ARGS (deduced);
  for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
    {
      tree arg = TREE_VEC_ELT (args, i);
      if (WILDCARD_PACK_P (arg))
	parms = introduce_template_parameter_pack (parms, arg);
      else
	parms = introduce_template_parameter (parms, arg);
    }

  return parms;
}

/* Builds the template parameter list PARMS by chaining introduced
   parameters from the WILDCARD vector.  INDEX is the position of
   the current parameter.  */

static tree
process_introduction_parms (tree parms, tree wildcards, int& index)
{
  tree proto = get_introduction_prototype (wildcards, index);
  if (template_parameter_pack_p (proto))
    return introduce_template_parameters (parms, wildcards, index);
  else
    return introduce_template_parameter (parms, wildcards, index);
}

/* Ensure that all template parameters have been introduced for the concept
   named in CHECK.  If not, emit a diagnostic.

   Note that implicitly introducing a parameter with a default argument
     creates a case where a parameter is declared, but unnamed, making
     it unusable in the definition.  */

static bool
check_introduction_list (tree intros, tree check)
{
  check = unpack_concept_check (check);
  tree tmpl = TREE_OPERAND (check, 0);
  if (OVL_P (tmpl))
    tmpl = OVL_FIRST (tmpl);

  tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
  if (TREE_VEC_LENGTH (intros) < TREE_VEC_LENGTH (parms))
    {
      error_at (input_location, "all template parameters of %qD must "
				"be introduced", tmpl);
      return false;
    }

   return true;
}

/* Associates a constraint check to the current template based on the
   introduction parameters.  INTRO_LIST must be a TREE_VEC of WILDCARD_DECLs
   containing a chained PARM_DECL which contains the identifier as well as
   the source location. TMPL_DECL is the decl for the concept being used.
   If we take a concept, C, this will form a check in the form of
   C<INTRO_LIST> filling in any extra arguments needed by the defaults
   deduced.

   Returns NULL_TREE if no concept could be matched and error_mark_node if
   an error occurred when matching.  */

tree
finish_template_introduction (tree tmpl_decl,
			      tree intro_list,
			      location_t intro_loc)
{
  /* Build a concept check to deduce the actual parameters.  */
  tree expr = build_concept_check (tmpl_decl, intro_list, tf_none);
  if (expr == error_mark_node)
    {
      error_at (intro_loc, "cannot deduce template parameters from "
			   "introduction list");
      return error_mark_node;
    }

  if (!check_introduction_list (intro_list, expr))
    return error_mark_node;

  tree parms = deduce_concept_introduction (expr);
  if (!parms)
    return NULL_TREE;

  /* Build template parameter scope for introduction.  */
  tree parm_list = NULL_TREE;
  begin_template_parm_list ();
  int nargs = MIN (TREE_VEC_LENGTH (parms), TREE_VEC_LENGTH (intro_list));
  for (int n = 0; n < nargs; )
    parm_list = process_introduction_parms (parm_list, parms, n);
  parm_list = end_template_parm_list (parm_list);

  /* Update the number of arguments to reflect the number of deduced
     template parameter introductions.  */
  nargs = TREE_VEC_LENGTH (parm_list);

  /* Determine if any errors occurred during matching.  */
  for (int i = 0; i < TREE_VEC_LENGTH (parm_list); ++i)
    if (TREE_VALUE (TREE_VEC_ELT (parm_list, i)) == error_mark_node)
      {
        end_template_decl ();
        return error_mark_node;
      }

  /* Build a concept check for our constraint.  */
  tree check_args = make_tree_vec (nargs);
  int n = 0;
  for (; n < TREE_VEC_LENGTH (parm_list); ++n)
    {
      tree parm = TREE_VEC_ELT (parm_list, n);
      TREE_VEC_ELT (check_args, n) = template_parm_to_arg (parm);
    }
  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (check_args, n);

  /* If the template expects more parameters we should be able
     to use the defaults from our deduced concept.  */
  for (; n < TREE_VEC_LENGTH (parms); ++n)
    TREE_VEC_ELT (check_args, n) = TREE_VEC_ELT (parms, n);

  /* Associate the constraint.  */
  tree check = build_concept_check (tmpl_decl,
				    check_args,
				    tf_warning_or_error);
  TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = check;

  return parm_list;
}


/* Given the concept check T from a constrained-type-specifier, extract
   its TMPL and ARGS.  FIXME why do we need two different forms of
   constrained-type-specifier?  */

void
placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args)
{
  if (concept_check_p (t))
    {
      t = unpack_concept_check (t);
      tmpl = TREE_OPERAND (t, 0);
      if (TREE_CODE (tmpl) == OVERLOAD)
        tmpl = OVL_FIRST (tmpl);
      args = TREE_OPERAND (t, 1);
      return;
    }

  if (TREE_CODE (t) == TYPE_DECL)
    {
      /* A constrained parameter.  Build a constraint check
         based on the prototype parameter and then extract the
         arguments from that.  */
      tree proto = CONSTRAINED_PARM_PROTOTYPE (t);
      tree check = finish_shorthand_constraint (proto, t);
      placeholder_extract_concept_and_args (check, tmpl, args);
      return;
    }
}

/* Returns true iff the placeholders C1 and C2 are equivalent.  C1
   and C2 can be either TEMPLATE_TYPE_PARM or template-ids.  */

bool
equivalent_placeholder_constraints (tree c1, tree c2)
{
  if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
    /* A constrained auto.  */
    c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
  if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
    c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);

  if (c1 == c2)
    return true;
  if (!c1 || !c2)
    return false;
  if (c1 == error_mark_node || c2 == error_mark_node)
    /* We get here during satisfaction; when a deduction constraint
       fails, substitution can produce an error_mark_node for the
       placeholder constraints.  */
    return false;

  tree t1, t2, a1, a2;
  placeholder_extract_concept_and_args (c1, t1, a1);
  placeholder_extract_concept_and_args (c2, t2, a2);

  if (t1 != t2)
    return false;

  int len1 = TREE_VEC_LENGTH (a1);
  int len2 = TREE_VEC_LENGTH (a2);
  if (len1 != len2)
    return false;

  /* Skip the first argument so we don't infinitely recurse.
     Also, they may differ in template parameter index.  */
  for (int i = 1; i < len1; ++i)
    {
      tree t1 = TREE_VEC_ELT (a1, i);
      tree t2 = TREE_VEC_ELT (a2, i);
      if (!template_args_equal (t1, t2))
      return false;
    }
  return true;
}

/* Return a hash value for the placeholder ATOMIC_CONSTR C.  */

hashval_t
hash_placeholder_constraint (tree c)
{
  tree t, a;
  placeholder_extract_concept_and_args (c, t, a);

  /* Like hash_tmpl_and_args, but skip the first argument.  */
  hashval_t val = iterative_hash_object (DECL_UID (t), 0);

  for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
    val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);

  return val;
}

/* Substitute through the expression of a simple requirement or
   compound requirement.  */

static tree
tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
{
  tree r = tsubst_expr (t, args, tf_none, info.in_decl, false);
  if (convert_to_void (r, ICV_STATEMENT, tf_none) != error_mark_node)
    return r;

  if (info.diagnose_unsatisfaction_p ())
    {
      location_t loc = cp_expr_loc_or_input_loc (t);
      if (diagnosing_failed_constraint::replay_errors_p ())
	{
	  inform (loc, "the required expression %qE is invalid, because", t);
	  if (r == error_mark_node)
	    tsubst_expr (t, args, info.complain, info.in_decl, false);
	  else
	    convert_to_void (r, ICV_STATEMENT, info.complain);
	}
      else
	inform (loc, "the required expression %qE is invalid", t);
    }
  else if (info.noisy ())
    {
      r = tsubst_expr (t, args, info.complain, info.in_decl, false);
      convert_to_void (r, ICV_STATEMENT, info.complain);
    }

  return error_mark_node;
}


/* Substitute through the simple requirement.  */

static tree
tsubst_simple_requirement (tree t, tree args, sat_info info)
{
  tree t0 = TREE_OPERAND (t, 0);
  tree expr = tsubst_valid_expression_requirement (t0, args, info);
  if (expr == error_mark_node)
    return error_mark_node;
  return boolean_true_node;
}

/* Subroutine of tsubst_type_requirement that performs the actual substitution
   and diagnosing.  Also used by tsubst_compound_requirement.  */

static tree
tsubst_type_requirement_1 (tree t, tree args, sat_info info, location_t loc)
{
  tree r = tsubst (t, args, tf_none, info.in_decl);
  if (r != error_mark_node)
    return r;

  if (info.diagnose_unsatisfaction_p ())
    {
      if (diagnosing_failed_constraint::replay_errors_p ())
	{
	  /* Replay the substitution error.  */
	  inform (loc, "the required type %qT is invalid, because", t);
	  tsubst (t, args, info.complain, info.in_decl);
	}
      else
	inform (loc, "the required type %qT is invalid", t);
    }
  else if (info.noisy ())
    tsubst (t, args, info.complain, info.in_decl);

  return error_mark_node;
}


/* Substitute through the type requirement.  */

static tree
tsubst_type_requirement (tree t, tree args, sat_info info)
{
  tree t0 = TREE_OPERAND (t, 0);
  tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t));
  if (type == error_mark_node)
    return error_mark_node;
  return boolean_true_node;
}

/* True if TYPE can be deduced from EXPR.  */

static bool
type_deducible_p (tree expr, tree type, tree placeholder, tree args,
                  subst_info info)
{
  /* Make sure deduction is performed against ( EXPR ), so that
     references are preserved in the result.  */
  expr = force_paren_expr_uneval (expr);

  tree deduced_type = do_auto_deduction (type, expr, placeholder,
					 info.complain, adc_requirement,
					 /*outer_targs=*/args);

  return deduced_type != error_mark_node;
}

/* True if EXPR can not be converted to TYPE.  */

static bool
expression_convertible_p (tree expr, tree type, subst_info info)
{
  tree conv =
    perform_direct_initialization_if_possible (type, expr, false,
					       info.complain);
  if (conv == error_mark_node)
    return false;
  if (conv == NULL_TREE)
    {
      if (info.complain & tf_error)
        {
          location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
          error_at (loc, "cannot convert %qE to %qT", expr, type);
        }
      return false;
    }
  return true;
}


/* Substitute through the compound requirement.  */

static tree
tsubst_compound_requirement (tree t, tree args, sat_info info)
{
  tree t0 = TREE_OPERAND (t, 0);
  tree t1 = TREE_OPERAND (t, 1);
  tree expr = tsubst_valid_expression_requirement (t0, args, info);
  if (expr == error_mark_node)
    return error_mark_node;

  location_t loc = cp_expr_loc_or_input_loc (expr);

  /* Check the noexcept condition.  */
  bool noexcept_p = COMPOUND_REQ_NOEXCEPT_P (t);
  if (noexcept_p && !expr_noexcept_p (expr, tf_none))
    {
      if (info.diagnose_unsatisfaction_p ())
	inform (loc, "%qE is not %<noexcept%>", expr);
      else
	return error_mark_node;
    }

  /* Substitute through the type expression, if any.  */
  tree type = tsubst_type_requirement_1 (t1, args, info, EXPR_LOCATION (t));
  if (type == error_mark_node)
    return error_mark_node;

  subst_info quiet (tf_none, info.in_decl);

  /* Check expression against the result type.  */
  if (type)
    {
      if (tree placeholder = type_uses_auto (type))
	{
	  if (!type_deducible_p (expr, type, placeholder, args, quiet))
	    {
	      if (info.diagnose_unsatisfaction_p ())
		{
		  if (diagnosing_failed_constraint::replay_errors_p ())
		    {
		      inform (loc,
			      "%qE does not satisfy return-type-requirement, "
			      "because", t0);
		      /* Further explain the reason for the error.  */
		      type_deducible_p (expr, type, placeholder, args, info);
		    }
		  else
		    inform (loc,
			    "%qE does not satisfy return-type-requirement", t0);
		}
	      return error_mark_node;
	    }
	}
      else if (!expression_convertible_p (expr, type, quiet))
	{
	  if (info.diagnose_unsatisfaction_p ())
	    {
	      if (diagnosing_failed_constraint::replay_errors_p ())
		{
		  inform (loc, "cannot convert %qE to %qT because", t0, type);
		  /* Further explain the reason for the error.  */
		  expression_convertible_p (expr, type, info);
		}
	      else
		inform (loc, "cannot convert %qE to %qT", t0, type);
	    }
	  return error_mark_node;
	}
    }

  return boolean_true_node;
}

/* Substitute through the nested requirement.  */

static tree
tsubst_nested_requirement (tree t, tree args, sat_info info)
{
  sat_info quiet (tf_none, info.in_decl);
  tree result = constraint_satisfaction_value (t, args, quiet);
  if (result == boolean_true_node)
    return boolean_true_node;

  if (result == boolean_false_node
      && info.diagnose_unsatisfaction_p ())
    {
      tree expr = TREE_OPERAND (t, 0);
      location_t loc = cp_expr_location (t);
      if (diagnosing_failed_constraint::replay_errors_p ())
	{
	  /* Replay the substitution error.  */
	  inform (loc, "nested requirement %qE is not satisfied, because", expr);
	  constraint_satisfaction_value (t, args, info);
	}
      else
	inform (loc, "nested requirement %qE is not satisfied", expr);
    }

  return error_mark_node;
}

/* Substitute ARGS into the requirement T.  */

static tree
tsubst_requirement (tree t, tree args, sat_info info)
{
  iloc_sentinel loc_s (cp_expr_location (t));
  switch (TREE_CODE (t))
    {
    case SIMPLE_REQ:
      return tsubst_simple_requirement (t, args, info);
    case TYPE_REQ:
      return tsubst_type_requirement (t, args, info);
    case COMPOUND_REQ:
      return tsubst_compound_requirement (t, args, info);
    case NESTED_REQ:
      return tsubst_nested_requirement (t, args, info);
    default:
      break;
    }
  gcc_unreachable ();
}

static tree
declare_constraint_vars (tree parms, tree vars)
{
  tree s = vars;
  for (tree t = parms; t; t = DECL_CHAIN (t))
    {
      if (DECL_PACK_P (t))
        {
          tree pack = extract_fnparm_pack (t, &s);
          register_local_specialization (pack, t);
        }
      else
        {
          register_local_specialization (s, t);
          s = DECL_CHAIN (s);
        }
    }
  return vars;
}

/* Substitute through as if checking function parameter types. This
   will diagnose common parameter type errors.  Returns error_mark_node
   if an error occurred.  */

static tree
check_constraint_variables (tree t, tree args, subst_info info)
{
  tree types = NULL_TREE;
  tree p = t;
  while (p && !VOID_TYPE_P (p))
    {
      types = tree_cons (NULL_TREE, TREE_TYPE (p), types);
      p = TREE_CHAIN (p);
    }
  types = chainon (nreverse (types), void_list_node);
  return tsubst_function_parms (types, args, info.complain, info.in_decl);
}

/* A subroutine of tsubst_parameterized_constraint. Substitute ARGS
   into the parameter list T, producing a sequence of constraint
   variables, declared in the current scope.

   Note that the caller must establish a local specialization stack
   prior to calling this function since this substitution will
   declare the substituted parameters. */

static tree
tsubst_constraint_variables (tree t, tree args, subst_info info)
{
  /* Perform a trial substitution to check for type errors.  */
  tree parms = check_constraint_variables (t, args, info);
  if (parms == error_mark_node)
    return error_mark_node;

  /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain
     of PARM_DECLs.  */
  int saved_unevaluated_operand = cp_unevaluated_operand;
  cp_unevaluated_operand = 0;
  tree vars = tsubst (t, args, info.complain, info.in_decl);
  cp_unevaluated_operand = saved_unevaluated_operand;
  if (vars == error_mark_node)
    return error_mark_node;
  return declare_constraint_vars (t, vars);
}

/* Substitute ARGS into the requires-expression T. [8.4.7]p6. The
   substitution of template arguments into a requires-expression
   may result in the formation of invalid types or expressions
   in its requirements ... In such cases, the expression evaluates
   to false; it does not cause the program to be ill-formed.

   When substituting through a REQUIRES_EXPR as part of template
   instantiation, we call this routine with info.quiet() true.

   When evaluating a REQUIRES_EXPR that appears outside a template in
   cp_parser_requires_expression, we call this routine with
   info.noisy() true.

   Finally, when diagnosing unsatisfaction from diagnose_atomic_constraint
   and when diagnosing a false REQUIRES_EXPR via diagnose_constraints,
   we call this routine with info.diagnose_unsatisfaction_p() true.  */

static tree
tsubst_requires_expr (tree t, tree args, sat_info info)
{
  local_specialization_stack stack (lss_copy);

  /* A requires-expression is an unevaluated context.  */
  cp_unevaluated u;

  args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args,
			 info.complain, info.in_decl);
  if (processing_template_decl)
    {
      /* We're partially instantiating a generic lambda.  Substituting into
	 this requires-expression now may cause its requirements to get
	 checked out of order, so instead just remember the template
	 arguments and wait until we can substitute them all at once.  */
      t = copy_node (t);
      REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain);
      return t;
    }

  if (tree parms = REQUIRES_EXPR_PARMS (t))
    {
      parms = tsubst_constraint_variables (parms, args, info);
      if (parms == error_mark_node)
	return boolean_false_node;
    }

  tree result = boolean_true_node;
  for (tree reqs = REQUIRES_EXPR_REQS (t); reqs; reqs = TREE_CHAIN (reqs))
    {
      tree req = TREE_VALUE (reqs);
      if (tsubst_requirement (req, args, info) == error_mark_node)
	{
	  result = boolean_false_node;
	  if (info.diagnose_unsatisfaction_p ())
	    /* Keep going so that we diagnose all failed requirements.  */;
	  else
	    break;
	}
    }
  return result;
}

/* Public wrapper for the above.  */

tree
tsubst_requires_expr (tree t, tree args,
		      tsubst_flags_t complain, tree in_decl)
{
  sat_info info (complain, in_decl);
  return tsubst_requires_expr (t, args, info);
}

/* Substitute ARGS into the constraint information CI, producing a new
   constraint record.  */

tree
tsubst_constraint_info (tree t, tree args,
                        tsubst_flags_t complain, tree in_decl)
{
  if (!t || t == error_mark_node || !check_constraint_info (t))
    return NULL_TREE;

  tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t), args, complain, in_decl);
  tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t), args, complain, in_decl);
  return build_constraints (tr, dr);
}

/* Substitute through a parameter mapping, in order to get the actual
   arguments used to instantiate an atomic constraint.  This may fail
   if the substitution into arguments produces something ill-formed.  */

static tree
tsubst_parameter_mapping (tree map, tree args, subst_info info)
{
  if (!map)
    return NULL_TREE;

  tsubst_flags_t complain = info.complain;
  tree in_decl = info.in_decl;

  tree result = NULL_TREE;
  for (tree p = map; p; p = TREE_CHAIN (p))
    {
      if (p == error_mark_node)
        return error_mark_node;
      tree parm = TREE_VALUE (p);
      tree arg = TREE_PURPOSE (p);
      tree new_arg;
      if (ARGUMENT_PACK_P (arg))
	new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
      else
	{
	  new_arg = tsubst_template_arg (arg, args, complain, in_decl);
	  if (TYPE_P (new_arg))
	    new_arg = canonicalize_type_argument (new_arg, complain);
	}
      if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
	{
	  tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
	  for (tree& pack_arg : tree_vec_range (pack_args))
	    if (TYPE_P (pack_arg))
	      pack_arg = canonicalize_type_argument (pack_arg, complain);
	}
      if (new_arg == error_mark_node)
	return error_mark_node;

      result = tree_cons (new_arg, parm, result);
    }
  return nreverse (result);
}

tree
tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_decl)
{
  return tsubst_parameter_mapping (map, args, subst_info (complain, in_decl));
}

/*---------------------------------------------------------------------------
                        Constraint satisfaction
---------------------------------------------------------------------------*/

/* True if we are currently satisfying a constraint.  */

static bool satisfying_constraint;

/* A vector of incomplete types (and of declarations with undeduced return type),
   appended to by note_failed_type_completion_for_satisfaction.  The
   satisfaction caches use this in order to keep track of "potentially unstable"
   satisfaction results.

   Since references to entries in this vector are stored only in the
   GC-deletable sat_cache, it's safe to make this deletable as well.  */

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

/* Called whenever a type completion (or return type deduction) failure occurs
   that definitely affects the meaning of the program, by e.g. inducing
   substitution failure.  */

void
note_failed_type_completion_for_satisfaction (tree t)
{
  if (satisfying_constraint)
    {
      gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))
			   || (DECL_P (t) && undeduced_auto_decl (t)));
      vec_safe_push (failed_type_completions, t);
    }
}

/* Returns true if the range [BEGIN, END) of elements within the
   failed_type_completions vector contains a complete type (or a
   declaration with a non-placeholder return type).  */

static bool
some_type_complete_p (int begin, int end)
{
  for (int i = begin; i < end; i++)
    {
      tree t = (*failed_type_completions)[i];
      if (TYPE_P (t) && COMPLETE_TYPE_P (t))
	return true;
      if (DECL_P (t) && !undeduced_auto_decl (t))
	return true;
    }
  return false;
}

/* Hash functions and data types for satisfaction cache entries.  */

struct GTY((for_user)) sat_entry
{
  /* The relevant ATOMIC_CONSTR.  */
  tree atom;

  /* The relevant template arguments.  */
  tree args;

  /* The result of satisfaction of ATOM+ARGS.
     This is either boolean_true_node, boolean_false_node or error_mark_node,
     where error_mark_node indicates ill-formed satisfaction.
     It's set to NULL_TREE while computing satisfaction of ATOM+ARGS for
     the first time.  */
  tree result;

  /* The value of input_location when satisfaction of ATOM+ARGS was first
     performed.  */
  location_t location;

  /* The range of elements appended to the failed_type_completions vector
     during computation of this satisfaction result, encoded as a begin/end
     pair of offsets.  */
  int ftc_begin, ftc_end;

  /* True if we want to diagnose the above instability when it's detected.
     We don't always want to do so, in order to avoid emitting duplicate
     diagnostics in some cases.  */
  bool diagnose_instability;

  /* True if we're in the middle of computing this satisfaction result.
     Used during both quiet and noisy satisfaction to detect self-recursive
     satisfaction.  */
  bool evaluating;
};

struct sat_hasher : ggc_ptr_hash<sat_entry>
{
  static hashval_t hash (sat_entry *e)
  {
    if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->atom))
      {
	/* Atoms with instantiated mappings are built during satisfaction.
	   They live only inside the sat_cache, and we build one to query
	   the cache with each time we instantiate a mapping.  */
	gcc_assert (!e->args);
	return hash_atomic_constraint (e->atom);
      }

    /* Atoms with uninstantiated mappings are built during normalization.
       Since normalize_atom caches the atoms it returns, we can assume
       pointer-based identity for fast hashing and comparison.  Even if this
       assumption is violated, that's okay, we'll just get a cache miss.  */
    hashval_t value = htab_hash_pointer (e->atom);

    if (tree map = ATOMIC_CONSTR_MAP (e->atom))
      /* Only the parameters that are used in the targets of the mapping
	 affect the satisfaction value of the atom.  So we consider only
	 the arguments for these parameters, and ignore the rest.  */
      for (tree target_parms = TREE_TYPE (map);
	   target_parms;
	   target_parms = TREE_CHAIN (target_parms))
	{
	  int level, index;
	  tree parm = TREE_VALUE (target_parms);
	  template_parm_level_and_index (parm, &level, &index);
	  tree arg = TMPL_ARG (e->args, level, index);
	  value = iterative_hash_template_arg (arg, value);
	}
    return value;
  }

  static bool equal (sat_entry *e1, sat_entry *e2)
  {
    if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)
	!= ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom))
      return false;

    /* See sat_hasher::hash.  */
    if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom))
      {
	gcc_assert (!e1->args && !e2->args);
	return atomic_constraints_identical_p (e1->atom, e2->atom);
      }

    if (e1->atom != e2->atom)
      return false;

    if (tree map = ATOMIC_CONSTR_MAP (e1->atom))
      for (tree target_parms = TREE_TYPE (map);
	   target_parms;
	   target_parms = TREE_CHAIN (target_parms))
	{
	  int level, index;
	  tree parm = TREE_VALUE (target_parms);
	  template_parm_level_and_index (parm, &level, &index);
	  tree arg1 = TMPL_ARG (e1->args, level, index);
	  tree arg2 = TMPL_ARG (e2->args, level, index);
	  if (!template_args_equal (arg1, arg2))
	    return false;
	}
    return true;
  }
};

/* Cache the result of satisfy_atom.  */
static GTY((deletable)) hash_table<sat_hasher> *sat_cache;

/* Cache the result of satisfy_declaration_constraints.  */
static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;

/* A tool used by satisfy_atom to help manage satisfaction caching and to
   diagnose "unstable" satisfaction values.  We insert into the cache only
   when performing satisfaction quietly.  */

struct satisfaction_cache
{
  satisfaction_cache (tree, tree, sat_info);
  tree get ();
  tree save (tree);

  sat_entry *entry;
  sat_info info;
  int ftc_begin;
};

/* Constructor for the satisfaction_cache class.  We're performing satisfaction
   of ATOM+ARGS according to INFO.  */

satisfaction_cache
::satisfaction_cache (tree atom, tree args, sat_info info)
  : entry(nullptr), info(info), ftc_begin(-1)
{
  if (!sat_cache)
    sat_cache = hash_table<sat_hasher>::create_ggc (31);

  /* When noisy, we query the satisfaction cache in order to diagnose
     "unstable" satisfaction values.  */
  if (info.noisy ())
    {
      /* When noisy, constraints have been re-normalized, and that breaks the
	 pointer-based identity assumption of sat_cache (for atoms with
	 uninstantiated mappings).  So undo this re-normalization by looking in
	 the atom_cache for the corresponding atom that was used during quiet
	 satisfaction.  */
      if (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
	{
	  if (tree found = atom_cache->find (atom))
	    atom = found;
	  else
	    /* The lookup should always succeed, but if it fails then let's
	       just leave 'entry' empty, effectively disabling the cache.  */
	    return;
	}
    }

  /* Look up or create the corresponding satisfaction entry.  */
  sat_entry elt;
  elt.atom = atom;
  elt.args = args;
  sat_entry **slot = sat_cache->find_slot (&elt, INSERT);
  if (*slot)
    entry = *slot;
  else if (info.quiet ())
    {
      entry = ggc_alloc<sat_entry> ();
      entry->atom = atom;
      entry->args = args;
      entry->result = NULL_TREE;
      entry->location = input_location;
      entry->ftc_begin = entry->ftc_end = -1;
      entry->diagnose_instability = false;
      if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
	/* We always want to diagnose instability of an atom with an
	   instantiated parameter mapping.  For atoms with an uninstantiated
	   mapping, we set this flag (in satisfy_atom) only if substitution
	   into its mapping previously failed.  */
	entry->diagnose_instability = true;
      entry->evaluating = false;
      *slot = entry;
    }
  else
    /* We shouldn't get here, but if we do, let's just leave 'entry'
       empty, effectively disabling the cache.  */
    return;
}

/* Returns the cached satisfaction result if we have one and we're not
   recomputing the satisfaction result from scratch.  Otherwise returns
   NULL_TREE.  */

tree
satisfaction_cache::get ()
{
  if (!entry)
    return NULL_TREE;

  if (entry->evaluating)
    {
      /* If we get here, it means satisfaction is self-recursive.  */
      gcc_checking_assert (!entry->result);
      if (info.noisy ())
	error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom)),
		  "satisfaction of atomic constraint %qE depends on itself",
		  entry->atom);
      return error_mark_node;
    }

  /* This satisfaction result is "potentially unstable" if a type for which
     type completion failed during its earlier computation is now complete.  */
  bool maybe_unstable = some_type_complete_p (entry->ftc_begin,
					      entry->ftc_end);

  if (info.noisy () || maybe_unstable || !entry->result)
    {
      /* We're computing the satisfaction result from scratch.  */
      entry->evaluating = true;
      ftc_begin = vec_safe_length (failed_type_completions);
      return NULL_TREE;
    }
  else
    return entry->result;
}

/* RESULT is the computed satisfaction result.  If RESULT differs from the
   previously cached result, this routine issues an appropriate error.
   Otherwise, when evaluating quietly, updates the cache appropriately.  */

tree
satisfaction_cache::save (tree result)
{
  if (!entry)
    return result;

  gcc_checking_assert (entry->evaluating);
  entry->evaluating = false;

  if (entry->result && result != entry->result)
    {
      if (info.quiet ())
	/* Return error_mark_node to force satisfaction to get replayed
	   noisily.  */
	return error_mark_node;
      else
	{
	  if (entry->diagnose_instability)
	    {
	      auto_diagnostic_group d;
	      error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom)),
			"satisfaction value of atomic constraint %qE changed "
			"from %qE to %qE", entry->atom, entry->result, result);
	      inform (entry->location,
		      "satisfaction value first evaluated to %qE from here",
		      entry->result);
	    }
	  /* For sake of error recovery, allow this latest satisfaction result
	     to prevail.  */
	  entry->result = result;
	  return result;
	}
    }

  if (info.quiet ())
    {
      entry->result = result;
      /* Store into this entry the list of relevant failed type completions
	 that occurred during (re)computation of the satisfaction result.  */
      gcc_checking_assert (ftc_begin != -1);
      entry->ftc_begin = ftc_begin;
      entry->ftc_end = vec_safe_length (failed_type_completions);
    }

  return result;
}

/* Substitute ARGS into constraint-expression T during instantiation of
   a member of a class template.  */

tree
tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
  /* We also don't want to evaluate concept-checks when substituting the
     constraint-expressions of a declaration.  */
  processing_constraint_expression_sentinel s;
  cp_unevaluated u;
  tree expr = tsubst_expr (t, args, complain, in_decl, false);
  return expr;
}

static tree satisfy_constraint_r (tree, tree, sat_info info);

/* Compute the satisfaction of a conjunction.  */

static tree
satisfy_conjunction (tree t, tree args, sat_info info)
{
  tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
  if (lhs == error_mark_node || lhs == boolean_false_node)
    return lhs;
  return satisfy_constraint_r (TREE_OPERAND (t, 1), args, info);
}

/* The current depth at which we're replaying an error during recursive
   diagnosis of a constraint satisfaction failure.  */

static int current_constraint_diagnosis_depth;

/* Whether CURRENT_CONSTRAINT_DIAGNOSIS_DEPTH has ever exceeded
   CONCEPTS_DIAGNOSTICS_MAX_DEPTH during recursive diagnosis of a constraint
   satisfaction error.  */

static bool concepts_diagnostics_max_depth_exceeded_p;

/* Recursive subroutine of collect_operands_of_disjunction.  T is a normalized
   subexpression of a constraint (composed of CONJ_CONSTRs and DISJ_CONSTRs)
   and E is the corresponding unnormalized subexpression (composed of
   TRUTH_ANDIF_EXPRs and TRUTH_ORIF_EXPRs).  */

static void
collect_operands_of_disjunction_r (tree t, tree e,
				   auto_vec<tree_pair> *operands)
{
  if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
    {
      collect_operands_of_disjunction_r (TREE_OPERAND (t, 0),
					 TREE_OPERAND (e, 0), operands);
      collect_operands_of_disjunction_r (TREE_OPERAND (t, 1),
					 TREE_OPERAND (e, 1), operands);
    }
  else
    {
      tree_pair p = std::make_pair (t, e);
      operands->safe_push (p);
    }
}

/* Recursively collect the normalized and unnormalized operands of the
   disjunction T and append them to OPERANDS in order.  */

static void
collect_operands_of_disjunction (tree t, auto_vec<tree_pair> *operands)
{
  collect_operands_of_disjunction_r (t, CONSTR_EXPR (t), operands);
}

/* Compute the satisfaction of a disjunction.  */

static tree
satisfy_disjunction (tree t, tree args, sat_info info)
{
  /* Evaluate each operand with unsatisfaction diagnostics disabled.  */
  sat_info sub = info;
  sub.diagnose_unsatisfaction = false;

  tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, sub);
  if (lhs == boolean_true_node || lhs == error_mark_node)
    return lhs;

  tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, sub);
  if (rhs == boolean_true_node || rhs == error_mark_node)
    return rhs;

  /* Both branches evaluated to false.  Explain the satisfaction failure in
     each branch.  */
  if (info.diagnose_unsatisfaction_p ())
    {
      diagnosing_failed_constraint failure (t, args, info.noisy ());
      cp_expr disj_expr = CONSTR_EXPR (t);
      inform (disj_expr.get_location (),
	      "no operand of the disjunction is satisfied");
      if (diagnosing_failed_constraint::replay_errors_p ())
	{
	  /* Replay the error in each branch of the disjunction.  */
	  auto_vec<tree_pair> operands;
	  collect_operands_of_disjunction (t, &operands);
	  for (unsigned i = 0; i < operands.length (); i++)
	    {
	      tree norm_op = operands[i].first;
	      tree op = operands[i].second;
	      location_t loc = make_location (cp_expr_location (op),
					      disj_expr.get_start (),
					      disj_expr.get_finish ());
	      inform (loc, "the operand %qE is unsatisfied because", op);
	      satisfy_constraint_r (norm_op, args, info);
	    }
	}
    }

  return boolean_false_node;
}

/* Ensures that T is a truth value and not (accidentally, as sometimes
   happens) an integer value.  */

tree
satisfaction_value (tree t)
{
  if (t == error_mark_node || t == boolean_true_node || t == boolean_false_node)
    return t;

  gcc_assert (TREE_CODE (t) == INTEGER_CST
	      && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t),
							    boolean_type_node));
  if (integer_zerop (t))
    return boolean_false_node;
  else
    return boolean_true_node;
}

/* Build a new template argument vector corresponding to the parameter
   mapping of the atomic constraint T, using arguments from ARGS.  */

static tree
get_mapped_args (tree t, tree args)
{
  tree map = ATOMIC_CONSTR_MAP (t);

  /* No map, no arguments.  */
  if (!map)
    return NULL_TREE;

  /* Determine the depth of the resulting argument vector.  */
  int depth;
  if (ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (t))
    /* The expression of this atomic constraint comes from a concept definition,
       whose template depth is always one, so the resulting argument vector
       will also have depth one.  */
    depth = 1;
  else
    /* Otherwise, the expression of this atomic constraint comes from
       the context of the constrained entity, whose template depth is that
       of ARGS.  */
    depth = TMPL_ARGS_DEPTH (args);

  /* Place each argument at its corresponding position in the argument
     list. Note that the list will be sparse (not all arguments supplied),
     but instantiation is guaranteed to only use the parameters in the
     mapping, so null arguments would never be used.  */
  auto_vec< vec<tree> > lists (depth);
  lists.quick_grow_cleared (depth);
  for (tree p = map; p; p = TREE_CHAIN (p))
    {
      int level;
      int index;
      template_parm_level_and_index (TREE_VALUE (p), &level, &index);

      /* Insert the argument into its corresponding position.  */
      vec<tree> &list = lists[level - 1];
      if (index >= (int)list.length ())
	list.safe_grow_cleared (index + 1, /*exact=*/false);
      list[index] = TREE_PURPOSE (p);
    }

  /* Build the new argument list.  */
  args = make_tree_vec (lists.length ());
  for (unsigned i = 0; i != lists.length (); ++i)
    {
      vec<tree> &list = lists[i];
      tree level = make_tree_vec (list.length ());
      for (unsigned j = 0; j < list.length(); ++j)
	TREE_VEC_ELT (level, j) = list[j];
      SET_TMPL_ARGS_LEVEL (args, i + 1, level);
      list.release ();
    }
  SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0);

  if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)
      && TMPL_ARGS_DEPTH (args) == 1)
    {
      /* Get rid of the redundant outer TREE_VEC.  */
      tree level = TMPL_ARGS_LEVEL (args, 1);
      ggc_free (args);
      args = level;
    }

  return args;
}

static void diagnose_atomic_constraint (tree, tree, tree, sat_info);

/* Compute the satisfaction of an atomic constraint.  */

static tree
satisfy_atom (tree t, tree args, sat_info info)
{
  /* In case there is a diagnostic, we want to establish the context
     prior to printing errors.  If no errors occur, this context is
     removed before returning.  */
  diagnosing_failed_constraint failure (t, args, info.noisy ());

  satisfaction_cache cache (t, args, info);
  if (tree r = cache.get ())
    return r;

  /* Perform substitution quietly.  */
  subst_info quiet (tf_none, NULL_TREE);

  /* Instantiate the parameter mapping.  */
  tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet);
  if (map == error_mark_node)
    {
      /* If instantiation of the parameter mapping fails, the constraint is
	 not satisfied.  Replay the substitution.  */
      if (info.diagnose_unsatisfaction_p ())
	tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info);
      if (info.quiet ())
	/* Since instantiation of the parameter mapping failed, we
	   want to diagnose potential instability of this satisfaction
	   result.  */
	cache.entry->diagnose_instability = true;
      return cache.save (boolean_false_node);
    }

  /* Now build a new atom using the instantiated mapping.  We use
     this atom as a second key to the satisfaction cache, and we
     also pass it to diagnose_atomic_constraint so that diagnostics
     which refer to the atom display the instantiated mapping.  */
  t = copy_node (t);
  ATOMIC_CONSTR_MAP (t) = map;
  gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t));
  ATOMIC_CONSTR_MAP_INSTANTIATED_P (t) = true;
  satisfaction_cache inst_cache (t, /*args=*/NULL_TREE, info);
  if (tree r = inst_cache.get ())
    {
      cache.entry->location = inst_cache.entry->location;
      return cache.save (r);
    }

  /* Rebuild the argument vector from the parameter mapping.  */
  args = get_mapped_args (t, args);

  /* Apply the parameter mapping (i.e., just substitute).  */
  tree expr = ATOMIC_CONSTR_EXPR (t);
  tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl, false);
  if (result == error_mark_node)
    {
      /* If substitution results in an invalid type or expression, the constraint
	 is not satisfied. Replay the substitution.  */
      if (info.diagnose_unsatisfaction_p ())
	tsubst_expr (expr, args, info.complain, info.in_decl, false);
      return cache.save (inst_cache.save (boolean_false_node));
    }

  /* [17.4.1.2] ... lvalue-to-rvalue conversion is performed as necessary,
     and EXPR shall be a constant expression of type bool.  */
  result = force_rvalue (result, info.complain);
  if (result == error_mark_node)
    return cache.save (inst_cache.save (error_mark_node));
  if (!same_type_p (TREE_TYPE (result), boolean_type_node))
    {
      if (info.noisy ())
	diagnose_atomic_constraint (t, args, result, info);
      return cache.save (inst_cache.save (error_mark_node));
    }

  /* Compute the value of the constraint.  */
  if (info.noisy ())
    {
      iloc_sentinel ils (EXPR_LOCATION (result));
      result = cxx_constant_value (result);
    }
  else
    {
      result = maybe_constant_value (result, NULL_TREE,
				     /*manifestly_const_eval=*/true);
      if (!TREE_CONSTANT (result))
	result = error_mark_node;
    }
  result = satisfaction_value (result);
  if (result == boolean_false_node && info.diagnose_unsatisfaction_p ())
    diagnose_atomic_constraint (t, args, result, info);

  return cache.save (inst_cache.save (result));
}

/* Determine if the normalized constraint T is satisfied.
   Returns boolean_true_node if the expression/constraint is
   satisfied, boolean_false_node if not, and error_mark_node
   if the there was an error evaluating the constraint.

   The parameter mapping of atomic constraints is simply the
   set of template arguments that will be substituted into
   the expression, regardless of template parameters appearing
   withing. Whether a template argument is used in the atomic
   constraint only matters for subsumption.  */

static tree
satisfy_constraint_r (tree t, tree args, sat_info info)
{
  if (t == error_mark_node)
    return error_mark_node;

  switch (TREE_CODE (t))
    {
    case CONJ_CONSTR:
      return satisfy_conjunction (t, args, info);
    case DISJ_CONSTR:
      return satisfy_disjunction (t, args, info);
    case ATOMIC_CONSTR:
      return satisfy_atom (t, args, info);
    default:
      gcc_unreachable ();
    }
}

/* Check that the normalized constraint T is satisfied for ARGS.  */

static tree
satisfy_normalized_constraints (tree t, tree args, sat_info info)
{
  auto_timevar time (TV_CONSTRAINT_SAT);

  auto ovr = make_temp_override (satisfying_constraint, true);

  /* Turn off template processing. Constraint satisfaction only applies
     to non-dependent terms, so we want to ensure full checking here.  */
  processing_template_decl_sentinel proc (true);

  /* We need to check access during satisfaction.  */
  deferring_access_check_sentinel acs (dk_no_deferred);

  /* Constraints are unevaluated operands.  */
  cp_unevaluated u;

  return satisfy_constraint_r (t, args, info);
}

/* Return the normal form of the constraints on the placeholder 'auto'
   type T.  */

static tree
normalize_placeholder_type_constraints (tree t, bool diag)
{
  gcc_assert (is_auto (t));
  tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
  if (!ci)
    return NULL_TREE;

  tree constr = TREE_VALUE (ci);
  /* The TREE_PURPOSE contains the set of template parameters that were in
     scope for this placeholder type; use them as the initial template
     parameters for normalization.  */
  tree initial_parms = TREE_PURPOSE (ci);

  /* The 'auto' itself is used as the first argument in its own constraints,
     and its level is one greater than its template depth.  So in order to
     capture all used template parameters, we need to add an extra level of
     template parameters to the context; a dummy level suffices.  */
  initial_parms
    = tree_cons (size_int (initial_parms
			   ? TMPL_PARMS_DEPTH (initial_parms) + 1 : 1),
		 make_tree_vec (0), initial_parms);

  norm_info info (diag ? tf_norm : tf_none);
  info.initial_parms = initial_parms;
  return normalize_constraint_expression (constr, info);
}

/* Evaluate the constraints of T using ARGS, returning a satisfaction value.
   Here, T can be a concept-id, nested-requirement, placeholder 'auto', or
   requires-expression.  */

static tree
satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
{
  if (t == error_mark_node)
    return error_mark_node;

  /* Handle REQUIRES_EXPR directly, bypassing satisfaction.  */
  if (TREE_CODE (t) == REQUIRES_EXPR)
    {
      auto ovr = make_temp_override (current_constraint_diagnosis_depth);
      if (info.noisy ())
	++current_constraint_diagnosis_depth;
      return tsubst_requires_expr (t, args, info);
    }

  /* Get the normalized constraints.  */
  tree norm;
  if (concept_check_p (t))
    {
      gcc_assert (!args);
      tree id = unpack_concept_check (t);
      args = TREE_OPERAND (id, 1);
      tree tmpl = get_concept_check_template (id);
      norm = normalize_concept_definition (tmpl, info.noisy ());
    }
  else if (TREE_CODE (t) == NESTED_REQ)
    {
      norm_info ninfo (info.noisy () ? tf_norm : tf_none);
      /* The TREE_TYPE contains the set of template parameters that were in
	 scope for this nested requirement; use them as the initial template
	 parameters for normalization.  */
      ninfo.initial_parms = TREE_TYPE (t);
      norm = normalize_constraint_expression (TREE_OPERAND (t, 0), ninfo);
    }
  else if (is_auto (t))
    {
      norm = normalize_placeholder_type_constraints (t, info.noisy ());
      if (!norm)
	return boolean_true_node;
    }
  else
    gcc_unreachable ();

  /* Perform satisfaction.  */
  return satisfy_normalized_constraints (norm, args, info);
}

/* Evaluate the associated constraints of the template specialization T
   according to INFO, returning a satisfaction value.  */

static tree
satisfy_declaration_constraints (tree t, sat_info info)
{
  gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL);
  const tree saved_t = t;

  /* For inherited constructors, consider the original declaration;
     it has the correct template information attached. */
  t = strip_inheriting_ctors (t);
  tree inh_ctor_targs = NULL_TREE;
  if (t != saved_t)
    if (tree ti = DECL_TEMPLATE_INFO (saved_t))
      /* The inherited constructor points to an instantiation of a constructor
	 template; remember its template arguments.  */
      inh_ctor_targs = TI_ARGS (ti);

  /* Update the declaration for diagnostics.  */
  info.in_decl = t;

  if (info.quiet ())
    if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
      return *result;

  tree args = NULL_TREE;
  if (tree ti = DECL_TEMPLATE_INFO (t))
    {
      /* The initial parameter mapping is the complete set of
	 template arguments substituted into the declaration.  */
      args = TI_ARGS (ti);
      if (inh_ctor_targs)
	args = add_outermost_template_args (args, inh_ctor_targs);
    }

  if (regenerated_lambda_fn_p (t))
    {
      /* The TI_ARGS of a regenerated lambda contains only the innermost
	 set of template arguments.  Augment this with the outer template
	 arguments that were used to regenerate the lambda.  */
      gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
      tree regen_args = lambda_regenerating_args (t);
      if (args)
	args = add_to_template_args (regen_args, args);
      else
	args = regen_args;
    }

  /* If any arguments depend on template parameters, we can't
     check constraints. Pretend they're satisfied for now.  */
  if (uses_template_parms (args))
    return boolean_true_node;

  /* Get the normalized constraints.  */
  tree norm = get_normalized_constraints_from_decl (t, info.noisy ());

  unsigned ftc_count = vec_safe_length (failed_type_completions);

  tree result = boolean_true_node;
  if (norm)
    {
      if (!push_tinst_level (t))
	return result;
      push_to_top_level ();
      push_access_scope (t);
      result = satisfy_normalized_constraints (norm, args, info);
      pop_access_scope (t);
      pop_from_top_level ();
      pop_tinst_level ();
    }

  /* True if this satisfaction is (heuristically) potentially unstable, i.e.
     if its result may depend on where in the program it was performed.  */
  bool maybe_unstable_satisfaction = false;
  if (ftc_count != vec_safe_length (failed_type_completions))
    /* Type completion failure occurred during satisfaction.  The satisfaction
       result may (or may not) materially depend on the completeness of a type,
       so we consider it potentially unstable.   */
    maybe_unstable_satisfaction = true;

  if (maybe_unstable_satisfaction)
    /* Don't cache potentially unstable satisfaction, to allow satisfy_atom
       to check the stability the next time around.  */;
  else if (info.quiet ())
    hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);

  return result;
}

/* Evaluate the associated constraints of the template T using ARGS as the
   innermost set of template arguments and according to INFO, returning a
   satisfaction value.  */

static tree
satisfy_declaration_constraints (tree t, tree args, sat_info info)
{
  /* Update the declaration for diagnostics.  */
  info.in_decl = t;

  gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);

  if (regenerated_lambda_fn_p (t))
    {
      /* As in the two-parameter version of this function.  */
      gcc_assert (TMPL_ARGS_DEPTH (args) == 1);
      tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
      tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
      args = add_to_template_args (outer_args, args);
    }
  else
    args = add_outermost_template_args (t, args);

  /* If any arguments depend on template parameters, we can't
     check constraints. Pretend they're satisfied for now.  */
  if (uses_template_parms (args))
    return boolean_true_node;

  tree result = boolean_true_node;
  if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
    {
      if (!push_tinst_level (t, args))
	return result;
      tree pattern = DECL_TEMPLATE_RESULT (t);
      push_to_top_level ();
      push_access_scope (pattern);
      result = satisfy_normalized_constraints (norm, args, info);
      pop_access_scope (pattern);
      pop_from_top_level ();
      pop_tinst_level ();
    }

  return result;
}

/* A wrapper around satisfy_declaration_constraints and
   satisfy_nondeclaration_constraints which additionally replays
   quiet ill-formed satisfaction noisily, so that ill-formed
   satisfaction always gets diagnosed.  */

static tree
constraint_satisfaction_value (tree t, tree args, sat_info info)
{
  tree r;
  if (DECL_P (t))
    {
      if (args)
	r = satisfy_declaration_constraints (t, args, info);
      else
	r = satisfy_declaration_constraints (t, info);
    }
  else
    r = satisfy_nondeclaration_constraints (t, args, info);
  if (r == error_mark_node && info.quiet ()
      && !(DECL_P (t) && warning_suppressed_p (t)))
    {
      /* Replay the error noisily.  */
      sat_info noisy (tf_warning_or_error, info.in_decl);
      constraint_satisfaction_value (t, args, noisy);
      if (DECL_P (t) && !args)
	/* Avoid giving these errors again.  */
	suppress_warning (t);
    }
  return r;
}

/* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
   and false otherwise, even in the case of errors.

   Here, T can be:
     - a template declaration
     - a template specialization (in which case ARGS must be empty)
     - a concept-id (in which case ARGS must be empty)
     - a nested-requirement
     - a placeholder 'auto'
     - a requires-expression.  */

bool
constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
{
  if (!flag_concepts)
    return true;

  sat_info quiet (tf_none, NULL_TREE);
  return constraint_satisfaction_value (t, args, quiet) == boolean_true_node;
}

/* Evaluate a concept check of the form C<ARGS>. This is only used for the
   evaluation of template-ids as id-expressions.  */

tree
evaluate_concept_check (tree check)
{
  if (check == error_mark_node)
    return error_mark_node;

  gcc_assert (concept_check_p (check));

  /* Check for satisfaction without diagnostics.  */
  sat_info quiet (tf_none, NULL_TREE);
  return constraint_satisfaction_value (check, /*args=*/NULL_TREE, quiet);
}

/* Evaluate the requires-expression T, returning either boolean_true_node
   or boolean_false_node.  This is used during folding and constexpr
   evaluation.  */

tree
evaluate_requires_expr (tree t)
{
  gcc_assert (TREE_CODE (t) == REQUIRES_EXPR);
  sat_info quiet (tf_none, NULL_TREE);
  return constraint_satisfaction_value (t, /*args=*/NULL_TREE, quiet);
}

/*---------------------------------------------------------------------------
                Semantic analysis of requires-expressions
---------------------------------------------------------------------------*/

/* Finish a requires expression for the given PARMS (possibly
   null) and the non-empty sequence of requirements.  */

tree
finish_requires_expr (location_t loc, tree parms, tree reqs)
{
  /* Build the node. */
  tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs, NULL_TREE);
  TREE_SIDE_EFFECTS (r) = false;
  TREE_CONSTANT (r) = true;
  SET_EXPR_LOCATION (r, loc);
  return r;
}

/* Construct a requirement for the validity of EXPR.   */

tree
finish_simple_requirement (location_t loc, tree expr)
{
  tree r = build_nt (SIMPLE_REQ, expr);
  SET_EXPR_LOCATION (r, loc);
  return r;
}

/* Construct a requirement for the validity of TYPE.  */

tree
finish_type_requirement (location_t loc, tree type)
{
  tree r = build_nt (TYPE_REQ, type);
  SET_EXPR_LOCATION (r, loc);
  return r;
}

/* Construct a requirement for the validity of EXPR, along with
   its properties. if TYPE is non-null, then it specifies either
   an implicit conversion or argument deduction constraint,
   depending on whether any placeholders occur in the type name.
   NOEXCEPT_P is true iff the noexcept keyword was specified.  */

tree
finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept_p)
{
  tree req = build_nt (COMPOUND_REQ, expr, type);
  SET_EXPR_LOCATION (req, loc);
  COMPOUND_REQ_NOEXCEPT_P (req) = noexcept_p;
  return req;
}

/* Finish a nested requirement.  */

tree
finish_nested_requirement (location_t loc, tree expr)
{
  /* Build the requirement, saving the set of in-scope template
     parameters as its type.  */
  tree r = build1 (NESTED_REQ, current_template_parms, expr);
  SET_EXPR_LOCATION (r, loc);
  return r;
}

/* Check that FN satisfies the structural requirements of a
   function concept definition.  */
tree
check_function_concept (tree fn)
{
  /* Check that the function is comprised of only a return statement.  */
  tree body = DECL_SAVED_TREE (fn);
  if (TREE_CODE (body) == BIND_EXPR)
    body = BIND_EXPR_BODY (body);

  /* Sometimes a function call results in the creation of clean up
     points. Allow these to be preserved in the body of the
     constraint, as we might actually need them for some constexpr
     evaluations.  */
  if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
    body = TREE_OPERAND (body, 0);

  /* Check that the definition is written correctly.  */
  if (TREE_CODE (body) != RETURN_EXPR)
    {
      location_t loc = DECL_SOURCE_LOCATION (fn);
      if (TREE_CODE (body) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body))
	{
	  if (seen_error ())
	    /* The definition was probably erroneous, not empty.  */;
	  else
	    error_at (loc, "definition of concept %qD is empty", fn);
	}
      else
        error_at (loc, "definition of concept %qD has multiple statements", fn);
    }

  return NULL_TREE;
}

/*---------------------------------------------------------------------------
                        Equivalence of constraints
---------------------------------------------------------------------------*/

/* Returns true when A and B are equivalent constraints.  */
bool
equivalent_constraints (tree a, tree b)
{
  gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
  gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
  return cp_tree_equal (a, b);
}

/* Returns true if the template declarations A and B have equivalent
   constraints. This is the case when A's constraints subsume B's and
   when B's also constrain A's.  */
bool
equivalently_constrained (tree d1, tree d2)
{
  gcc_assert (TREE_CODE (d1) == TREE_CODE (d2));
  return equivalent_constraints (get_constraints (d1), get_constraints (d2));
}

/*---------------------------------------------------------------------------
                     Partial ordering of constraints
---------------------------------------------------------------------------*/

/* Returns true when the constraints in CI strictly subsume
   the associated constraints of TMPL.  */

bool
strictly_subsumes (tree ci, tree tmpl)
{
  tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
  tree n2 = get_normalized_constraints_from_decl (tmpl);

  return subsumes (n1, n2) && !subsumes (n2, n1);
}

/* Returns true when the constraints in CI subsume the
   associated constraints of TMPL.  */

bool
weakly_subsumes (tree ci, tree tmpl)
{
  tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
  tree n2 = get_normalized_constraints_from_decl (tmpl);

  return subsumes (n1, n2);
}

/* Determines which of the declarations, A or B, is more constrained.
   That is, which declaration's constraints subsume but are not subsumed
   by the other's?

   Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
   than D1, and 0 otherwise. */

int
more_constrained (tree d1, tree d2)
{
  tree n1 = get_normalized_constraints_from_decl (d1);
  tree n2 = get_normalized_constraints_from_decl (d2);

  int winner = 0;
  if (subsumes (n1, n2))
    ++winner;
  if (subsumes (n2, n1))
    --winner;
  return winner;
}

/* Return whether D1 is at least as constrained as D2.  */

bool
at_least_as_constrained (tree d1, tree d2)
{
  tree n1 = get_normalized_constraints_from_decl (d1);
  tree n2 = get_normalized_constraints_from_decl (d2);

  return subsumes (n1, n2);
}

/*---------------------------------------------------------------------------
                        Constraint diagnostics
---------------------------------------------------------------------------*/

/* Returns the best location to diagnose a constraint error.  */

static location_t
get_constraint_error_location (tree t)
{
  if (location_t loc = cp_expr_location (t))
    return loc;

  /* If we have a specific location give it.  */
  tree expr = CONSTR_EXPR (t);
  if (location_t loc = cp_expr_location (expr))
    return loc;

  /* If the constraint is normalized from a requires-clause, give
     the location as that of the constrained declaration.  */
  tree cxt = CONSTR_CONTEXT (t);
  tree src = cxt ? TREE_VALUE (cxt) : NULL_TREE;
  if (!src)
    /* TODO: This only happens for constrained non-template declarations.  */
    ;
  else if (DECL_P (src))
    return DECL_SOURCE_LOCATION (src);
  /* Otherwise, give the location as the defining concept.  */
  else if (concept_check_p (src))
    {
      tree id = unpack_concept_check (src);
      tree tmpl = TREE_OPERAND (id, 0);
      if (OVL_P (tmpl))
	tmpl = OVL_FIRST (tmpl);
      return DECL_SOURCE_LOCATION (tmpl);
    }

  return input_location;
}

/* Emit a diagnostic for a failed trait.  */

static void
diagnose_trait_expr (tree expr, tree args)
{
  location_t loc = cp_expr_location (expr);

  /* Build a "fake" version of the instantiated trait, so we can
     get the instantiated types from result.  */
  ++processing_template_decl;
  expr = tsubst_expr (expr, args, tf_none, NULL_TREE, false);
  --processing_template_decl;

  tree t1 = TRAIT_EXPR_TYPE1 (expr);
  tree t2 = TRAIT_EXPR_TYPE2 (expr);
  switch (TRAIT_EXPR_KIND (expr))
    {
    case CPTK_HAS_NOTHROW_ASSIGN:
      inform (loc, "  %qT is not %<nothrow%> copy assignable", t1);
      break;
    case CPTK_HAS_NOTHROW_CONSTRUCTOR:
      inform (loc, "  %qT is not %<nothrow%> default constructible", t1);
      break;
    case CPTK_HAS_NOTHROW_COPY:
      inform (loc, "  %qT is not %<nothrow%> copy constructible", t1);
      break;
    case CPTK_HAS_TRIVIAL_ASSIGN:
      inform (loc, "  %qT is not trivially copy assignable", t1);
      break;
    case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
      inform (loc, "  %qT is not trivially default constructible", t1);
      break;
    case CPTK_HAS_TRIVIAL_COPY:
      inform (loc, "  %qT is not trivially copy constructible", t1);
      break;
    case CPTK_HAS_TRIVIAL_DESTRUCTOR:
      inform (loc, "  %qT is not trivially destructible", t1);
      break;
    case CPTK_HAS_VIRTUAL_DESTRUCTOR:
      inform (loc, "  %qT does not have a virtual destructor", t1);
      break;
    case CPTK_IS_ABSTRACT:
      inform (loc, "  %qT is not an abstract class", t1);
      break;
    case CPTK_IS_BASE_OF:
      inform (loc, "  %qT is not a base of %qT", t1, t2);
      break;
    case CPTK_IS_CLASS:
      inform (loc, "  %qT is not a class", t1);
      break;
    case CPTK_IS_EMPTY:
      inform (loc, "  %qT is not an empty class", t1);
      break;
    case CPTK_IS_ENUM:
      inform (loc, "  %qT is not an enum", t1);
      break;
    case CPTK_IS_FINAL:
      inform (loc, "  %qT is not a final class", t1);
      break;
    case CPTK_IS_LAYOUT_COMPATIBLE:
      inform (loc, "  %qT is not layout compatible with %qT", t1, t2);
      break;
    case CPTK_IS_LITERAL_TYPE:
      inform (loc, "  %qT is not a literal type", t1);
      break;
    case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
      inform (loc, "  %qT is not pointer-interconvertible base of %qT",
	      t1, t2);
      break;
    case CPTK_IS_POD:
      inform (loc, "  %qT is not a POD type", t1);
      break;
    case CPTK_IS_POLYMORPHIC:
      inform (loc, "  %qT is not a polymorphic type", t1);
      break;
    case CPTK_IS_SAME_AS:
      inform (loc, "  %qT is not the same as %qT", t1, t2);
      break;
    case CPTK_IS_STD_LAYOUT:
      inform (loc, "  %qT is not an standard layout type", t1);
      break;
    case CPTK_IS_TRIVIAL:
      inform (loc, "  %qT is not a trivial type", t1);
      break;
    case CPTK_IS_UNION:
      inform (loc, "  %qT is not a union", t1);
      break;
    case CPTK_IS_AGGREGATE:
      inform (loc, "  %qT is not an aggregate", t1);
      break;
    case CPTK_IS_TRIVIALLY_COPYABLE:
      inform (loc, "  %qT is not trivially copyable", t1);
      break;
    case CPTK_IS_ASSIGNABLE:
      inform (loc, "  %qT is not assignable from %qT", t1, t2);
      break;
    case CPTK_IS_TRIVIALLY_ASSIGNABLE:
      inform (loc, "  %qT is not trivially assignable from %qT", t1, t2);
      break;
    case CPTK_IS_NOTHROW_ASSIGNABLE:
      inform (loc, "  %qT is not %<nothrow%> assignable from %qT", t1, t2);
      break;
    case CPTK_IS_CONSTRUCTIBLE:
      if (!t2)
	inform (loc, "  %qT is not default constructible", t1);
      else
	inform (loc, "  %qT is not constructible from %qE", t1, t2);
      break;
    case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
      if (!t2)
	inform (loc, "  %qT is not trivially default constructible", t1);
      else
	inform (loc, "  %qT is not trivially constructible from %qE", t1, t2);
      break;
    case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
      if (!t2)
	inform (loc, "  %qT is not %<nothrow%> default constructible", t1);
      else
	inform (loc, "  %qT is not %<nothrow%> constructible from %qE", t1, t2);
      break;
    case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
      inform (loc, "  %qT does not have unique object representations", t1);
      break;
    case CPTK_BASES:
    case CPTK_DIRECT_BASES:
    case CPTK_UNDERLYING_TYPE:
      /* We shouldn't see these non-expression traits.  */
      gcc_unreachable ();
    /* We deliberately omit the default case so that when adding a new
       trait we'll get reminded (by way of a warning) to handle it here.  */
    }
}

/* Diagnose a substitution failure in the atomic constraint T using ARGS.  */

static void
diagnose_atomic_constraint (tree t, tree args, tree result, sat_info info)
{
  /* If the constraint is already ill-formed, we've previously diagnosed
     the reason. We should still say why the constraints aren't satisfied.  */
  if (t == error_mark_node)
    {
      location_t loc;
      if (info.in_decl)
        loc = DECL_SOURCE_LOCATION (info.in_decl);
      else
        loc = input_location;
      inform (loc, "invalid constraints");
      return;
    }

  location_t loc = get_constraint_error_location (t);
  iloc_sentinel loc_s (loc);

  /* Generate better diagnostics for certain kinds of expressions.  */
  tree expr = ATOMIC_CONSTR_EXPR (t);
  STRIP_ANY_LOCATION_WRAPPER (expr);
  switch (TREE_CODE (expr))
    {
    case TRAIT_EXPR:
      diagnose_trait_expr (expr, args);
      break;
    case REQUIRES_EXPR:
      gcc_checking_assert (info.diagnose_unsatisfaction_p ());
      /* Clear in_decl before replaying the substitution to avoid emitting
	 seemingly unhelpful "in declaration ..." notes that follow some
	 substitution failure error messages.  */
      info.in_decl = NULL_TREE;
      tsubst_requires_expr (expr, args, info);
      break;
    default:
      if (!same_type_p (TREE_TYPE (result), boolean_type_node))
	error_at (loc, "constraint %qE has type %qT, not %<bool%>",
		  t, TREE_TYPE (result));
      else
	inform (loc, "the expression %qE evaluated to %<false%>", t);
    }
}

GTY(()) tree current_failed_constraint;

diagnosing_failed_constraint::
diagnosing_failed_constraint (tree t, tree args, bool diag)
  : diagnosing_error (diag)
{
  if (diagnosing_error)
    {
      current_failed_constraint
	= tree_cons (args, t, current_failed_constraint);
      ++current_constraint_diagnosis_depth;
    }
}

diagnosing_failed_constraint::
~diagnosing_failed_constraint ()
{
  if (diagnosing_error)
    {
      --current_constraint_diagnosis_depth;
      if (current_failed_constraint)
	current_failed_constraint = TREE_CHAIN (current_failed_constraint);
    }

}

/* Whether we are allowed to replay an error that underlies a constraint failure
   at the current diagnosis depth.  */

bool
diagnosing_failed_constraint::replay_errors_p ()
{
  if (current_constraint_diagnosis_depth >= concepts_diagnostics_max_depth)
    {
      concepts_diagnostics_max_depth_exceeded_p = true;
      return false;
    }
  else
    return true;
}

/* Emit diagnostics detailing the failure ARGS to satisfy the constraints
   of T.  Here, T and ARGS are as in constraints_satisfied_p.  */

void
diagnose_constraints (location_t loc, tree t, tree args)
{
  inform (loc, "constraints not satisfied");

  if (concepts_diagnostics_max_depth == 0)
    return;

  /* Replay satisfaction, but diagnose unsatisfaction.  */
  sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
  constraint_satisfaction_value (t, args, noisy);

  static bool suggested_p;
  if (concepts_diagnostics_max_depth_exceeded_p
      && current_constraint_diagnosis_depth == 0
      && !suggested_p)
    {
      inform (UNKNOWN_LOCATION,
	      "set %qs to at least %d for more detail",
	      "-fconcepts-diagnostics-depth=",
	      concepts_diagnostics_max_depth + 1);
      suggested_p = true;
    }
}

#include "gt-cp-constraint.h"
