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 > >