aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-12-02 10:58:50 -0500
committerPatrick Palka <ppalka@redhat.com>2024-12-02 10:58:50 -0500
commit73e7f63ffaacf018b1fad331d2369bf891620e97 (patch)
treeeebddc9787c52971170165f373c0e45df60cfc06 /gcc
parentcec97549b781643f55bde34d025c3170309e3646 (diff)
downloadgcc-73e7f63ffaacf018b1fad331d2369bf891620e97.zip
gcc-73e7f63ffaacf018b1fad331d2369bf891620e97.tar.gz
gcc-73e7f63ffaacf018b1fad331d2369bf891620e97.tar.bz2
c++: some further concepts cleanups
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. * Introduce and use a helper for obtaining the prototype parameter of a concept, i.e. its first template parameter. * 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 with a type-constraint, so we can remove such handling from the parser. This means is_constrained_parameter is currently equivalent to declares_constrained_type_template_parameter, so let's prefer to use the latter. * Remove WILDCARD_DECL and instead use the concept's prototype parameter as the dummy first argument of a type-constraint during template argument coercion. * Remove a redundant concept_definition_p overload. 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. (build_type_constraint): Use the prototype parameter as the first template argument. (finish_shorthand_constraint): Remove function concept handling. Use concept_prototype_parameter. (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-objcp-common.cc (cp_common_init_ts): Remove WILDCARD_DECL handling. * cp-tree.def (WILDCARD_DECL): Remove. * cp-tree.h (WILDCARD_PACK_P): Remove. (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. (concept_definition_p): Remove redundant overload. (concept_prototype_parameter): Define. * cxx-pretty-print.cc (pp_cxx_constrained_type_spec): Adjust after placeholder_extract_concept_and_args. * error.cc (dump_decl) <case WILDCARD_DECL>: Remove. (dump_expr) <case WILDCARD_DECL>: Likewise. * 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. Check the prototype parameter earlier, before build_type_constraint. Use concept_prototype_parameter. (cp_parser_parameter_declaration): Remove dead code guarded by declares_constrained_template_template_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. (make_constrained_placeholder_type): Remove function concept handling. (placeholder_type_constraint_dependent_p): Remove WILDCARD_DECL handling. Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/constraint.cc185
-rw-r--r--gcc/cp/cp-objcp-common.cc1
-rw-r--r--gcc/cp/cp-tree.def6
-rw-r--r--gcc/cp/cp-tree.h36
-rw-r--r--gcc/cp/cxx-pretty-print.cc4
-rw-r--r--gcc/cp/error.cc5
-rw-r--r--gcc/cp/parser.cc114
-rw-r--r--gcc/cp/pt.cc42
8 files changed, 77 insertions, 316 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index cf0e5d3..3389775 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -242,88 +242,6 @@ get_concept_check_template (tree t)
}
/*---------------------------------------------------------------------------
- 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. */
@@ -1252,9 +1154,9 @@ build_concept_id (tree expr)
tree
build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
{
- tree wildcard = build_nt (WILDCARD_DECL);
+ tree proto = template_parm_to_arg (concept_prototype_parameter (decl));
++processing_template_decl;
- tree check = build_concept_check (decl, wildcard, args, complain);
+ tree check = build_concept_check (decl, proto, args, complain);
--processing_template_decl;
return 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-objcp-common.cc b/gcc/cp/cp-objcp-common.cc
index 8bb9a90..1e7c205 100644
--- a/gcc/cp/cp-objcp-common.cc
+++ b/gcc/cp/cp-objcp-common.cc
@@ -628,7 +628,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 fa445ec..c4da702 100644
--- a/gcc/cp/cp-tree.def
+++ b/gcc/cp/cp-tree.def
@@ -495,12 +495,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 e70d215..0d6fce0 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)
@@ -4068,9 +4067,6 @@ struct GTY(()) lang_decl {
#define PACK_INDEX_PARENTHESIZED_P(NODE) \
TREE_LANG_FLAG_1 (TREE_CHECK (NODE, PACK_INDEX_EXPR))
-/* 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 \
@@ -7558,9 +7554,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);
@@ -8627,15 +8620,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);
@@ -8920,17 +8907,9 @@ 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. */
@@ -8943,6 +8922,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/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc
index 01a351c..4bbbb01 100644
--- a/gcc/cp/cxx-pretty-print.cc
+++ b/gcc/cp/cxx-pretty-print.cc
@@ -2349,8 +2349,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/error.cc b/gcc/cp/error.cc
index 934eb2f..10d7f46 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -1544,10 +1544,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);
@@ -2347,7 +2343,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 94069d7..e583649 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -18705,29 +18705,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)
{
@@ -18765,36 +18746,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. */
@@ -18828,9 +18779,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)
@@ -18844,24 +18792,26 @@ finish_constrained_parameter (cp_parser *parser,
return parm;
}
-/* Returns true if the parsed type actually represents the declaration
- of a type template-parameter. */
+/* Returns true if the TYPE would declare a constrained type
+ template-parameter. */
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. */
+/* Returns true if PARM declares a constrained type template-parameter. */
static bool
-declares_constrained_template_template_parameter (tree type)
+declares_constrained_type_template_parameter (cp_parameter_declarator *parm)
{
- return (is_constrained_parameter (type)
- && TREE_CODE (TREE_TYPE (type)) == TEMPLATE_TEMPLATE_PARM);
+ tree type = parm->decl_specifiers.type;
+ return declares_constrained_type_template_parameter (type);
}
/* Parse a default argument for a type template-parameter.
@@ -19034,7 +18984,7 @@ 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))
+ if (declares_constrained_type_template_parameter (parameter_declarator))
return finish_constrained_parameter (parser,
parameter_declarator,
is_non_type);
@@ -21123,13 +21073,26 @@ 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 = DECL_TEMPLATE_RESULT (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_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;
/* As per the standard, require auto or decltype(auto). */
@@ -21145,19 +21108,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)
@@ -26279,12 +26229,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 f6cb960..182f18d 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -8584,16 +8584,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. */
@@ -8648,10 +8638,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;
@@ -9033,16 +9019,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);
@@ -16559,13 +16535,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);
@@ -28734,8 +28703,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
@@ -29738,11 +29706,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)
@@ -29787,8 +29752,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;