diff mbox series

[1/2] c++: some further concepts cleanups

Message ID 20241015044536.1487876-1-ppalka@redhat.com
State New
Headers show
Series [1/2] c++: some further concepts cleanups | expand

Commit Message

Patrick Palka Oct. 15, 2024, 4:45 a.m. UTC
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.
---
 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 mbox series

Patch

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)