On Tue, 15 Oct 2024, Patrick Palka wrote:

> This patch further cleans up the concepts code following the removal of
> Concepts TS support:
> 
>   * concept-ids are now the only kind of "concept check", so we can
>     simplify some code accordingly.  In particular resolve_concept_check
>     seems like a no-op and can be removed.
>   * In turn, deduce_constrained_parameter doesn't seem to do anything
>     interesting.
>   * In light of the above we might as well inline finish_type_constraints
>     into its only caller.  Note that the "prototype parameter" of a
>     concept is just the first template parameter which the caller can
>     easily obtain itself.
>   * placeholder_extract_concept_and_args is only ever called on a
>     concept-id, so it's simpler to inline it into its callers.
>   * There's no such thing as a template-template-parameter wtih a
>     type-constraint, so we can remove such handling from the parser.
>     This means is_constrained_parameter is currently equivalent to
>     declares_constrained_template_template_parameter, so let's prefer
>     to use the latter.
> 
> We might be able to remove WILDCARD_DECL and CONSTRAINED_PARM_PROTOTYPE
> now as well, but I left that as future work.
> 
> gcc/cp/ChangeLog:
> 
>       * constraint.cc (resolve_concept_check): Remove.
>       (deduce_constrained_parameter): Remove.
>       (finish_type_constraints): Inline into its only caller
>       cp_parser_placeholder_type_specifier and remove.
>       (build_concept_check_arguments): Coding style tweaks.
>       (build_standard_check): Inline into its only caller ...
>       (build_concept_check): ... here.
>       (finish_shorthand_constraint): Remove function concept
>       handling.
>       (placeholder_extract_concept_and_args): Inline into its
>       callers and remove.
>       (equivalent_placeholder_constraints): Adjust after
>       placeholder_extract_concept_and_args removal.
>       (iterative_hash_placeholder_constraint): Likewise.
>       * cp-tree.h (type_uses_auto_or_concept): Remove declaration
>       of nonexistent function.
>       (append_type_to_template_for_access_check): Likewise.
>       (finish_type_constraints): Remove declaration.
>       (placeholder_extract_concept_and_args): Remove declaration.
>       (deduce_constrained_parameter): Remove declaration.
>       (resolve_constraint_check): Remove declaration.
>       (valid_requirements_p): Remove declaration of nonexistent
>       function.
>       (finish_concept_name): Likewise.
>       * cxx-pretty-print.cc (pp_cxx_constrained_type_spec): Adjust
>       after placeholder_extract_concept_and_args.
>       * parser.cc (is_constrained_parameter): Inline into
>       declares_constrained_type_template_parameter and remove.
>       (cp_parser_check_constrained_type_parm): Declare static.
>       (finish_constrained_template_template_parm): Remove.
>       (cp_parser_constrained_template_template_parm): Remove.
>       (finish_constrained_parameter): Remove dead code guarded by
>       cp_parser_constrained_template_template_parm.
>       (declares_constrained_type_template_parameter): Adjust after
>       is_constrained_parameter removal.
>       (declares_constrained_template_template_parameter): Remove.
>       (cp_parser_placeholder_type_specifier): Adjust after
>       finish_type_constraints removal.
>       (cp_parser_parameter_declaration): Remove dead code guarded by
>       declares_constrained_template_template_parameter.
>       * pt.cc (make_constrained_placeholder_type): Remove function
>       concept handling.

Ping.

> ---
>  gcc/cp/constraint.cc       | 181 ++++++-------------------------------
>  gcc/cp/cp-tree.h           |   9 --
>  gcc/cp/cxx-pretty-print.cc |   4 +-
>  gcc/cp/parser.cc           |  87 +++---------------
>  gcc/cp/pt.cc               |   5 +-
>  5 files changed, 42 insertions(+), 244 deletions(-)
> 
> diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
> index cf0e5d37571..35be9cc2b41 100644
> --- a/gcc/cp/constraint.cc
> +++ b/gcc/cp/constraint.cc
> @@ -241,88 +241,6 @@ get_concept_check_template (tree t)
>    return TREE_OPERAND (t, 0);
>  }
>  
> -/*---------------------------------------------------------------------------
> -                    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.  */
> -
> -/* 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 tmpl = TREE_OPERAND (check, 0);
> -  tree args = TREE_OPERAND (check, 1);
> -  tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
> -  ++processing_template_decl;
> -  tree result = coerce_template_parms (parms, args, tmpl, tf_none);
> -  --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;
> -}
> -
> -/* 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
>  ---------------------------------------------------------------------------*/
> @@ -1161,10 +1079,11 @@ get_trailing_function_requirements (tree t)
>  
>  /* 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);
> +  gcc_assert (!rest || TREE_CODE (rest) == TREE_VEC);
>    tree args;
>    if (arg)
>      {
> @@ -1178,49 +1097,32 @@ build_concept_check_arguments (tree arg, tree rest)
>        SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
>      }
>    else
> -    {
> -      args = rest;
> -    }
> +    args = rest;
>    return 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 (concept_definition_p (tmpl));
> -  gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
> -  if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl)))
> -    warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE);
> -  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.  */
> +/* Construct an expression that checks TMPL using ARGS.  */
>  
>  tree
> -build_concept_check (tree target, tree args, tsubst_flags_t complain)
> +build_concept_check (tree tmpl, tree args, tsubst_flags_t complain)
>  {
> -  return build_concept_check (target, NULL_TREE, args, complain);
> +  return build_concept_check (tmpl, NULL_TREE, args, complain);
>  }
>  
> -/* Construct an expression that checks the concept given by DECL.  If
> -   concept_definition_p (DECL) is false, this returns null.  */
> +/* Construct an expression that checks the concept given by TMPL.  */
>  
>  tree
> -build_concept_check (tree decl, tree arg, tree rest, tsubst_flags_t complain)
> +build_concept_check (tree tmpl, tree arg, tree rest, tsubst_flags_t complain)
>  {
> -  tree args = build_concept_check_arguments (arg, rest);
> -
> -  if (concept_definition_p (decl))
> -    return build_standard_check (decl, args, complain);
> +  if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl)))
> +    warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE);
>  
> -  return error_mark_node;
> +  tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
> +  tree args = build_concept_check_arguments (arg, rest);
> +  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);
>  }
>  
>  /* Build a template-id that can participate in a concept check.  */
> @@ -1312,10 +1214,7 @@ finish_shorthand_constraint (tree decl, tree constr)
>  
>    /* 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);
> +  tree check = build_concept_check (tmpl, arg, args, tf_warning_or_error);
>  
>    /* Make the check a fold-expression if needed.
>       Use UNKNOWN_LOCATION so write_template_args can tell the
> @@ -1345,32 +1244,6 @@ get_shorthand_constraints (tree parms)
>    return result;
>  }
>  
> -/* 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))
> -    {
> -      tmpl = TREE_OPERAND (t, 0);
> -      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.  */
>  
> @@ -1393,9 +1266,11 @@ equivalent_placeholder_constraints (tree c1, tree c2)
>         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);
> +  gcc_assert (concept_check_p (c1) && concept_check_p (c2));
> +  tree t1 = TREE_OPERAND (c1, 0);
> +  tree a1 = TREE_OPERAND (c1, 1);
> +  tree t2 = TREE_OPERAND (c2, 0);
> +  tree a2 = TREE_OPERAND (c2, 1);
>  
>    if (t1 != t2)
>      return false;
> @@ -1408,12 +1283,9 @@ equivalent_placeholder_constraints (tree c1, tree c2)
>    /* 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))
> +    if (!template_args_equal (TREE_VEC_ELT (a1, i),
> +                           TREE_VEC_ELT (a2, i)))
>        return false;
> -    }
>    return true;
>  }
>  
> @@ -1422,8 +1294,9 @@ equivalent_placeholder_constraints (tree c1, tree c2)
>  hashval_t
>  iterative_hash_placeholder_constraint (tree c, hashval_t val)
>  {
> -  tree t, a;
> -  placeholder_extract_concept_and_args (c, t, a);
> +  gcc_assert (concept_check_p (c));
> +  tree t = TREE_OPERAND (c, 0);
> +  tree a = TREE_OPERAND (c, 1);
>  
>    /* Like hash_tmpl_and_args, but skip the first argument.  */
>    val = iterative_hash_object (DECL_UID (t), val);
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 94ee550bd9c..1864ab205ae 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -7531,9 +7531,6 @@ extern tree do_auto_deduction                   (tree, 
> tree, tree,
>                                                int = LOOKUP_NORMAL,
>                                                tree = NULL_TREE);
>  extern tree type_uses_auto                   (tree);
> -extern tree type_uses_auto_or_concept                (tree);
> -extern void append_type_to_template_for_access_check (tree, tree, tree,
> -                                                   location_t);
>  extern tree convert_generic_types_to_packs   (tree, int, int);
>  extern tree splice_late_return_type          (tree, tree);
>  extern bool is_auto                          (const_tree);
> @@ -8598,15 +8595,9 @@ extern tree build_type_constraint              (tree, 
> tree, tsubst_flags_t);
>  extern tree build_concept_check                 (tree, tree, tsubst_flags_t);
>  extern tree build_concept_check                 (tree, tree, tree, 
> tsubst_flags_t);
>  
> -extern tree_pair finish_type_constraints     (tree, tree, tsubst_flags_t);
>  extern tree build_constrained_parameter         (tree, tree, tree = 
> NULL_TREE);
> -extern void placeholder_extract_concept_and_args (tree, tree&, tree&);
>  extern bool equivalent_placeholder_constraints  (tree, tree);
>  extern hashval_t iterative_hash_placeholder_constraint       (tree, 
> hashval_t);
> -extern bool deduce_constrained_parameter        (tree, tree&, tree&);
> -extern tree resolve_constraint_check            (tree);
> -extern bool valid_requirements_p                (tree);
> -extern tree finish_concept_name                 (tree);
>  extern tree finish_shorthand_constraint         (tree, tree);
>  extern tree finish_requires_expr                (location_t, tree, tree);
>  extern tree finish_simple_requirement           (location_t, tree);
> diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
> index 41e6bdfdda5..bf3772d5ac5 100644
> --- a/gcc/cp/cxx-pretty-print.cc
> +++ b/gcc/cp/cxx-pretty-print.cc
> @@ -2334,8 +2334,8 @@ pp_cxx_constrained_type_spec (cxx_pretty_printer *pp, 
> tree c)
>        pp_cxx_ws_string(pp, "<unsatisfied-type-constraint>");
>        return;
>      }
> -  tree t, a;
> -  placeholder_extract_concept_and_args (c, t, a);
> +  tree t = TREE_OPERAND (c, 0);
> +  tree a = TREE_OPERAND (c, 1);
>    pp->id_expression (t);
>    pp_cxx_begin_template_argument_list (pp);
>    pp_cxx_ws_string (pp, "<placeholder>");
> diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
> index 9d31a975dcf..856508e3e4f 100644
> --- a/gcc/cp/parser.cc
> +++ b/gcc/cp/parser.cc
> @@ -18572,29 +18572,10 @@ get_unqualified_id (cp_declarator *declarator)
>      return NULL_TREE;
>  }
>  
> -/* Returns true if TYPE would declare a constrained constrained-parameter.  
> */
> -
> -static inline bool
> -is_constrained_parameter (tree type)
> -{
> -  return (type
> -          && TREE_CODE (type) == TYPE_DECL
> -          && CONSTRAINED_PARM_CONCEPT (type)
> -          && DECL_P (CONSTRAINED_PARM_CONCEPT (type)));
> -}
> -
> -/* Returns true if PARM declares a constrained-parameter. */
> -
> -static inline bool
> -is_constrained_parameter (cp_parameter_declarator *parm)
> -{
> -  return is_constrained_parameter (parm->decl_specifiers.type);
> -}
> -
>  /* Check that the type parameter is only a declarator-id, and that its
>     type is not cv-qualified. */
>  
> -bool
> +static bool
>  cp_parser_check_constrained_type_parm (cp_parser *parser,
>                                      cp_parameter_declarator *parm)
>  {
> @@ -18632,36 +18613,6 @@ cp_parser_constrained_type_template_parm (cp_parser 
> *parser,
>      return error_mark_node;
>  }
>  
> -static tree
> -finish_constrained_template_template_parm (tree proto, tree id)
> -{
> -  /* FIXME: This should probably be copied, and we may need to adjust
> -     the template parameter depths.  */
> -  tree saved_parms = current_template_parms;
> -  begin_template_parm_list ();
> -  current_template_parms = DECL_TEMPLATE_PARMS (proto);
> -  end_template_parm_list ();
> -
> -  tree parm = finish_template_template_parm (class_type_node, id);
> -  current_template_parms = saved_parms;
> -
> -  return parm;
> -}
> -
> -/* Finish parsing/processing a template template parameter by borrowing
> -   the template parameter list from the prototype parameter.  */
> -
> -static tree
> -cp_parser_constrained_template_template_parm (cp_parser *parser,
> -                                              tree proto,
> -                                              tree id,
> -                                              cp_parameter_declarator 
> *parmdecl)
> -{
> -  if (!cp_parser_check_constrained_type_parm (parser, parmdecl))
> -    return error_mark_node;
> -  return finish_constrained_template_template_parm (proto, id);
> -}
> -
>  /* Create a new non-type template parameter from the given PARM
>     declarator.  */
>  
> @@ -18695,9 +18646,6 @@ finish_constrained_parameter (cp_parser *parser,
>    tree parm;
>    if (TREE_CODE (proto) == TYPE_DECL)
>      parm = cp_parser_constrained_type_template_parm (parser, id, parmdecl);
> -  else if (TREE_CODE (proto) == TEMPLATE_DECL)
> -    parm = cp_parser_constrained_template_template_parm (parser, proto, id,
> -                                                      parmdecl);
>    else
>      parm = cp_parser_constrained_non_type_template_parm (is_non_type, 
> parmdecl);
>    if (parm == error_mark_node)
> @@ -18717,20 +18665,13 @@ finish_constrained_parameter (cp_parser *parser,
>  static bool
>  declares_constrained_type_template_parameter (tree type)
>  {
> -  return (is_constrained_parameter (type)
> +  return (type
> +       && TREE_CODE (type) == TYPE_DECL
> +       && CONSTRAINED_PARM_CONCEPT (type)
> +       && DECL_P (CONSTRAINED_PARM_CONCEPT (type))
>         && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TYPE_PARM);
>  }
>  
> -/* Returns true if the parsed type actually represents the declaration of
> -   a template template-parameter.  */
> -
> -static bool
> -declares_constrained_template_template_parameter (tree type)
> -{
> -  return (is_constrained_parameter (type)
> -       && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TEMPLATE_PARM);
> -}
> -
>  /* Parse a default argument for a type template-parameter.
>     Note that diagnostics are handled in cp_parser_template_parameter.  */
>  
> @@ -18901,7 +18842,8 @@ cp_parser_template_parameter (cp_parser* parser, bool 
> *is_non_type,
>      }
>  
>    /* The parameter may have been constrained type parameter.  */
> -  if (is_constrained_parameter (parameter_declarator))
> +  tree type = parameter_declarator->decl_specifiers.type;
> +  if (declares_constrained_type_template_parameter (type))
>      return finish_constrained_parameter (parser,
>                                           parameter_declarator,
>                                           is_non_type);
> @@ -20987,11 +20929,12 @@ cp_parser_placeholder_type_specifier (cp_parser 
> *parser, location_t loc,
>    tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error;
>  
>    /* Get the concept and prototype parameter for the constraint.  */
> -  tree_pair info = finish_type_constraints (tmpl, args, complain);
> -  tree con = info.first;
> -  tree proto = info.second;
> -  if (con == error_mark_node)
> +  tree check = build_type_constraint (tmpl, args, complain);
> +  if (check == error_mark_node)
>      return error_mark_node;
> +  tree con = STRIP_TEMPLATE (tmpl);
> +  tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
> +  tree proto = TREE_VALUE (TREE_VEC_ELT (parms, 0));
>  
>    /* As per the standard, require auto or decltype(auto).  */
>    cp_token *placeholder = NULL, *close_paren = NULL;
> @@ -26130,12 +26073,6 @@ cp_parser_parameter_declaration (cp_parser *parser,
>          default_argument
>            = cp_parser_default_type_template_argument (parser);
>  
> -      /* A constrained-type-specifier may declare a
> -      template-template-parameter.  */
> -      else if (declares_constrained_template_template_parameter (type))
> -        default_argument
> -          = cp_parser_default_template_template_argument (parser);
> -
>        /* Outside of a class definition, we can just parse the
>        assignment-expression.  */
>        else
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index c0a37a51cba..3d037bd6948 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -29556,11 +29556,8 @@ make_constrained_placeholder_type (tree type, tree 
> con, tree args)
>  {
>    /* Build the constraint. */
>    tree tmpl = DECL_TI_TEMPLATE (con);
> -  tree expr = tmpl;
> -  if (TREE_CODE (con) == FUNCTION_DECL)
> -    expr = ovl_make (tmpl);
>    ++processing_template_decl;
> -  expr = build_concept_check (expr, type, args, tf_warning_or_error);
> +  tree expr = build_concept_check (tmpl, type, args, tf_warning_or_error);
>    --processing_template_decl;
>  
>    PLACEHOLDER_TYPE_CONSTRAINTS_INFO (type)
> -- 
> 2.47.0.72.gef8ce8f3d4
> 
> 

Reply via email to