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