diff options
author | Patrick Palka <ppalka@redhat.com> | 2024-12-02 10:58:50 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2024-12-02 10:58:50 -0500 |
commit | 73e7f63ffaacf018b1fad331d2369bf891620e97 (patch) | |
tree | eebddc9787c52971170165f373c0e45df60cfc06 /gcc | |
parent | cec97549b781643f55bde34d025c3170309e3646 (diff) | |
download | gcc-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.cc | 185 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.cc | 1 | ||||
-rw-r--r-- | gcc/cp/cp-tree.def | 6 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 36 | ||||
-rw-r--r-- | gcc/cp/cxx-pretty-print.cc | 4 | ||||
-rw-r--r-- | gcc/cp/error.cc | 5 | ||||
-rw-r--r-- | gcc/cp/parser.cc | 114 | ||||
-rw-r--r-- | gcc/cp/pt.cc | 42 |
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; |