[PATCH 3/2] c++: remove WILDCARD_DECL
Patrick Palka
ppalka@redhat.com
Wed Oct 23 20:30:26 GMT 2024
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk?
-- >8 --
This tree code was added as part of the initial Concepts TS
implementation to support type-constraints introducing any kind
of template-parameter, not just type template-parameters, e.g.
template<int N> concept C = ...;
template<template<class> class TT> concept D = ...;
template<C T, D U> void f(); // T is an NTTP of type int, U is a TTP
When resolving the type-constraint we would use WILDCARD_DECL as the
dummy first argument during template argument coercion that is a valid
argument for any kind of template parameter.
But Concepts TS support has been removed, and C++20 type-constraints are
restricted to only introduce type template-parameters, and so we don't
need this catch-all WILDCARD_DECL anymore; we can instead use an auto
as the dummy first argument.
In passing introduce a helper for returning the prototype parameter
(i.e. first template parameter) of a concept and use it. Also remove a
redundant concept_definition_p overload.
gcc/cp/ChangeLog:
* constraint.cc (build_type_constraint): Use an auto as the
first template argument.
(finish_shorthand_constraint): Use concept_prototype_parameter.
* cp-objcp-common.cc (cp_common_init_ts): Remove WILDCARD_DECL
handling.
* cp-tree.def (WILDCARD_DECL): Remove.
* cp-tree.h (WILDCARD_PACK_P): Remove.
(concept_definition_p): Remove redundant overload.
(concept_prototype_parameter): Define.
* error.cc (dump_decl) <case WILDCARD_DECL>: Remove.
(dump_expr) <case WILDCARD_DECL>: Likewise.
* parser.cc (cp_parser_placeholder_type_specifier): Check
the prototype parameter earlier, before build_type_constraint.
Use concept_prototype_parameter.
* pt.cc (convert_wildcard_argument): Remove.
(convert_template_argument): Remove WILDCARD_DECL handling.
(coerce_template_parameter_pack): Likewise.
(tsubst) <case TEMPLATE_TYPE_PARM>: Likewise.
(type_dependent_expression_p): Likewise.
(placeholder_type_constraint_dependent_p): Likewise.
---
gcc/cp/constraint.cc | 6 ++----
gcc/cp/cp-objcp-common.cc | 1 -
gcc/cp/cp-tree.def | 6 ------
gcc/cp/cp-tree.h | 27 ++++++++++++++-------------
gcc/cp/error.cc | 5 -----
gcc/cp/parser.cc | 31 +++++++++++++++----------------
gcc/cp/pt.cc | 37 ++-----------------------------------
7 files changed, 33 insertions(+), 80 deletions(-)
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 9394bea8835..d6a6ac03393 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1154,9 +1154,8 @@ build_concept_id (tree expr)
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);
+ tree check = build_concept_check (decl, make_auto (), args, complain);
--processing_template_decl;
return check;
}
@@ -1203,8 +1202,7 @@ finish_shorthand_constraint (tree decl, tree constr, bool is_non_type)
{
tree id = PLACEHOLDER_TYPE_CONSTRAINTS (constr);
tree tmpl = TREE_OPERAND (id, 0);
- tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
- proto = TREE_VALUE (TREE_VEC_ELT (parms, 0));
+ proto = concept_prototype_parameter (tmpl);
con = DECL_TEMPLATE_RESULT (tmpl);
args = TREE_OPERAND (id, 1);
}
diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index cd379514991..69eed72a5a2 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -624,7 +624,6 @@ cp_common_init_ts (void)
/* New decls. */
MARK_TS_DECL_COMMON (TEMPLATE_DECL);
- MARK_TS_DECL_COMMON (WILDCARD_DECL);
MARK_TS_DECL_NON_COMMON (USING_DECL);
diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def
index 18f75108c7b..53511a6d8cc 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -487,12 +487,6 @@ DEFTREECODE (OMP_DEPOBJ, "omp_depobj", tcc_statement, 2)
/* Used to represent information associated with constrained declarations. */
DEFTREECODE (CONSTRAINT_INFO, "constraint_info", tcc_exceptional, 0)
-/* A wildcard declaration is a placeholder for a template parameter
- used to resolve constrained-type-names in concepts. During
- resolution, the matching argument is saved as the TREE_TYPE
- of the wildcard. */
-DEFTREECODE (WILDCARD_DECL, "wildcard_decl", tcc_declaration, 0)
-
/* A requires-expr has three operands. The first operand is
its parameter list (possibly NULL). The second is a list of
requirements, which are denoted by the _REQ* tree codes
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6dcf32b178e..c25dafd5981 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -438,7 +438,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
TINFO_HAS_ACCESS_ERRORS (in TEMPLATE_INFO)
SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR)
COMPOUND_REQ_NOEXCEPT_P (in COMPOUND_REQ)
- WILDCARD_PACK_P (in WILDCARD_DECL)
BLOCK_OUTER_CURLY_BRACE_P (in BLOCK)
FOLD_EXPR_MODIFY_P (*_FOLD_EXPR)
IF_STMT_CONSTEXPR_P (IF_STMT)
@@ -4042,9 +4041,6 @@ struct GTY(()) lang_decl {
#define PACK_EXPANSION_FORCE_EXTRA_ARGS_P(NODE) \
TREE_LANG_FLAG_3 (PACK_EXPANSION_CHECK (NODE))
-/* True iff the wildcard can match a template parameter pack. */
-#define WILDCARD_PACK_P(NODE) TREE_LANG_FLAG_0 (NODE)
-
/* Determine if this is an argument pack. */
#define ARGUMENT_PACK_P(NODE) \
(TREE_CODE (NODE) == TYPE_ARGUMENT_PACK \
@@ -8879,18 +8875,10 @@ variable_template_p (tree t)
/* True iff T is a concept. */
-inline bool
-concept_definition_p (tree t)
-{
- return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL;
-}
-
-/* Same as above, but for const trees. */
-
inline bool
concept_definition_p (const_tree t)
{
- return concept_definition_p (const_cast<tree> (t));
+ return TREE_CODE (STRIP_TEMPLATE (t)) == CONCEPT_DECL;
}
/* True if t is an expression that checks a concept. */
@@ -8903,6 +8891,19 @@ concept_check_p (const_tree t)
return false;
}
+/* Return the prototype parameter of the concept T,
+ i.e. its first declared template parameter. */
+
+inline tree
+concept_prototype_parameter (const_tree t)
+{
+ gcc_checking_assert (concept_definition_p (t));
+ if (TREE_CODE (t) == CONCEPT_DECL)
+ t = DECL_TI_TEMPLATE (t);
+ tree parms = DECL_INNERMOST_TEMPLATE_PARMS (t);
+ return TREE_VALUE (TREE_VEC_ELT (parms, 0));
+}
+
/* Helpers for IMPLICIT_RVALUE_P to look through automatic dereference. */
inline bool
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 65f70c595cf..c5b256f3907 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -1542,10 +1542,6 @@ dump_decl (cxx_pretty_printer *pp, tree t, int flags)
dump_simple_decl (pp, t, TREE_TYPE (t), flags);
break;
- case WILDCARD_DECL:
- pp_string (pp, "<wildcard>");
- break;
-
case TEMPLATE_ID_EXPR:
{
tree name = TREE_OPERAND (t, 0);
@@ -2376,7 +2372,6 @@ dump_expr (cxx_pretty_printer *pp, tree t, int flags)
case TEMPLATE_DECL:
case NAMESPACE_DECL:
case LABEL_DECL:
- case WILDCARD_DECL:
case OVERLOAD:
case TYPE_DECL:
case USING_DECL:
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 0bad62978dc..16e05acd7b8 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -20918,15 +20918,27 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
/* A concept-name with no arguments can't be an expression. */
tentative = false;
+ tree con = STRIP_TEMPLATE (tmpl);
+ tree proto = concept_prototype_parameter (con);
tsubst_flags_t complain = tentative ? tf_none : tf_warning_or_error;
+ /* A type constraint constrains a contextually determined type or type
+ parameter pack. */
+ if (TREE_CODE (proto) != TYPE_DECL)
+ {
+ if (!tentative)
+ {
+ auto_diagnostic_group d;
+ error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
+ inform (DECL_SOURCE_LOCATION (con), "concept defined here");
+ }
+ return error_mark_node;
+ }
+
/* Get the concept and prototype parameter for the constraint. */
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;
@@ -20941,19 +20953,6 @@ cp_parser_placeholder_type_specifier (cp_parser *parser, location_t loc,
close_paren = parens.require_close (parser);
}
- /* A type constraint constrains a contextually determined type or type
- parameter pack. */
- if (TREE_CODE (proto) != TYPE_DECL)
- {
- if (!tentative)
- {
- auto_diagnostic_group d;
- error_at (loc, "%qE does not constrain a type", DECL_NAME (con));
- inform (DECL_SOURCE_LOCATION (con), "concept defined here");
- }
- return error_mark_node;
- }
-
/* In a template parameter list, a type-parameter can be introduced
by type-constraints alone. */
if (processing_template_parmlist && !placeholder)
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index ec4313090bd..9833b2bea5f 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -8539,16 +8539,6 @@ is_compatible_template_arg (tree parm, tree arg, tree args)
return ttp_subsumes (parm_cons, arg);
}
-// Convert a placeholder argument into a binding to the original
-// parameter. The original parameter is saved as the TREE_TYPE of
-// ARG.
-static inline tree
-convert_wildcard_argument (tree parm, tree arg)
-{
- TREE_TYPE (arg) = parm;
- return arg;
-}
-
/* We can't fully resolve ARG given as a non-type template argument to TYPE,
because one of them is dependent. But we need to represent the
conversion for the benefit of cp_tree_equal. */
@@ -8603,10 +8593,6 @@ convert_template_argument (tree parm,
if (parm == error_mark_node || error_operand_p (arg))
return error_mark_node;
- /* Trivially convert placeholders. */
- if (TREE_CODE (arg) == WILDCARD_DECL)
- return convert_wildcard_argument (parm, arg);
-
if (arg == any_targ_node)
return arg;
@@ -8988,16 +8974,6 @@ coerce_template_parameter_pack (tree parms,
packed_args = make_tree_vec (TREE_VEC_LENGTH (packed_parms));
}
- /* Check if we have a placeholder pack, which indicates we're
- in the context of a introduction list. In that case we want
- to match this pack to the single placeholder. */
- else if (arg_idx < nargs
- && TREE_CODE (TREE_VEC_ELT (inner_args, arg_idx)) == WILDCARD_DECL
- && WILDCARD_PACK_P (TREE_VEC_ELT (inner_args, arg_idx)))
- {
- nargs = arg_idx + 1;
- packed_args = make_tree_vec (1);
- }
else
packed_args = make_tree_vec (nargs - arg_idx);
@@ -16489,13 +16465,6 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
{
int quals;
- /* When building concept checks for the purpose of
- deducing placeholders, we can end up with wildcards
- where types are expected. Adjust this to the deduced
- value. */
- if (TREE_CODE (arg) == WILDCARD_DECL)
- arg = TREE_TYPE (TREE_TYPE (arg));
-
gcc_assert (TYPE_P (arg));
quals = cp_type_quals (arg) | cp_type_quals (t);
@@ -28559,8 +28528,7 @@ type_dependent_expression_p (tree expression)
/* An unresolved name is always dependent. */
if (identifier_p (expression)
- || TREE_CODE (expression) == USING_DECL
- || TREE_CODE (expression) == WILDCARD_DECL)
+ || TREE_CODE (expression) == USING_DECL)
return true;
/* A lambda-expression in template context is dependent. dependent_type_p is
@@ -29603,8 +29571,7 @@ placeholder_type_constraint_dependent_p (tree t)
args = expand_template_argument_pack (args);
first = TREE_VEC_ELT (args, 0);
}
- gcc_checking_assert (TREE_CODE (first) == WILDCARD_DECL
- || is_auto (first));
+ gcc_checking_assert (is_auto (first));
for (int i = 1; i < TREE_VEC_LENGTH (args); ++i)
if (dependent_template_arg_p (TREE_VEC_ELT (args, i)))
return true;
--
2.47.0.118.gfd3785337b
More information about the Gcc-patches
mailing list