diff options
author | Jason Merrill <jason@gcc.gnu.org> | 2019-10-09 13:20:32 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2019-10-09 13:20:32 -0400 |
commit | cb57504a550158913258e5be8ddb991376475efb (patch) | |
tree | d1f7676666e845ba7e77b45fcc3d6e5e0a2acb82 /gcc/cp/cp-tree.h | |
parent | 8cb6a77590957942e124b34e0bb0827d1404f341 (diff) | |
download | gcc-cb57504a550158913258e5be8ddb991376475efb.zip gcc-cb57504a550158913258e5be8ddb991376475efb.tar.gz gcc-cb57504a550158913258e5be8ddb991376475efb.tar.bz2 |
Update the concepts implementation to conform to C++20.
gcc/c-family/
* c-cppbuiltin.c (c_cpp_builtins): Use new feature test values for
concepts when -std=c++2a. Bump __cpp_concepts to 201907.
* c.opt: Add -Wconcepts-ts.
* c-opts.c (c_common_post_options): Warn when -fconcepts is used
with -std=c++2a. Disable warning for -fconcepts in C++20 mode.
(set_std_cxx2a): Enable concepts by default.
gcc/cp/
* call.c (build_new_function_call): Don't evaluate concepts here.
(constraint_failure): Don't record the template.
(print_z_candidate): Don't extract the template.
* class.c (add_method): When overloading, hide ineligible special
member fns.
(check_methods): Set TYPE_HAS_COMPLEX_* here.
* constexpr.c (cxx_eval_constant_expression): Evaluate concepts.
(maybe_initialize_fundef_copies_table): Remove.
(get_fundef_copy): Use hash_map_safe_get_or_insert.
(clear_cv_and_fold_caches): Clear the satisfaction cache.
* constraint.cc (known_non_bool_p): New.
(parsing_constraint_expression_sentinel): Renamed from
expanding_constraint_sentinel.
(check_constraint_operands): New.
(check_constraint_atom): New.
(finish_constraint_binary_op): New.
(finish_constraint_or_expr): Likewise.
(finish_constraint_and_expr): Likewise.
(finish_constraint_primary_expr): Likewise.
(combine_constraint_expressions): New.
(finish_requires_expr): Add location parm.
(get_concept_definition): Return the initializer of concept definitions.
(get_template_head_requirements): New.
(get_trailing_function_requirements): New.
(deduce_constrained_parameter): Check if the identifier or template-id
is a concept definition.
(resolve_concept_definition_check): Removed.
(resolve_variable_concept_check): Removed.
(resolve_concept_check): New.
(resolve_constraint_check): Handle concept definitions.
converting arguments.
(function_concept_check_p): Removed.
(variable_concept_check_p): Removed.
(unpack_concept_check): New.
(get_concept_check_template): New.
(build_call_check): Moved and renamed to build_function_check.
(build_concept_check_arguments): make static.
(build_function_check): Always do overload resolution
in order to force conversion of template arguments (i.e., actually
check that the use of a concept is valid).
(build_standard_check): Renamed from build_real_concept_check.
(build_real_concept_check): Build checks for C++2a concepts by
(build_wildcard_concept_check): New.
(build_concept_check): Use build_real_concept_check. New overload.
(build_constraints): Save expressions, not normalized constraints.
(build_concept_id): New. Pass tf_warning_or_error.
(build_type_constraint): New.
(finish_type_constraints): New.
(associate_classtype_constraints): Also add constraints to union
types. Note the original declaration in errors. Don't return
error_mark_node in order to avoid an assertion later.
(push_down_pack_expansion): Remove.
(finish_shorthand_constraint): Make fold expressions, not naked
parameter packs. Always apply the constraint to each template argument.
(check_introduction_list): New. Fail if not enough
names are introduced.
(finish_template_introduction): Don't normalize constraints. Pass
tsubst flags. Check for insufficient introductions.
(placeholder_extract_concept_and_args): Handle the template-id case.
Unpack function concept checks correctly.
(tsubst_simple_requirement): Return errors if they occur. Don't
process as a template.
(tsubst_type_requirement): Likewise.
(type_deducible_p): New. Wrap the input expression in parens for the
purpose of deduction.
(expression_convertible_t): New.
(tsubst_compound_requirement): Use new deduction, conversion predicates.
(tsubst_nested_requirement): Return errors if they occur. Don't
process as a template. Instantiate and evaluate the nested requirement.
(tsubst_valid_expression_requirement): New.
(tsubst_simple_requirement): Use tsubst_valid_expression_requirement.
(tsubst_compound_requirement): Use tsubst_valid_expression_requirement.
(check_constaint_variables): New.
(tsubst_constraint_variables): Check that type substitutions are valid.
(tsubst_requires_expr): Likewise. Produce new requires-exprs during
template substitution. Copy the previous local specialization stack,
so references to non-local parameters can be found. Use cp_unevaluated.
(tsubst_constraint): New. Don't evaluate concept checks.
(subst_info): New.
(norm_info): New. Used to build a normalization tree for concept check
diagnostics.
(debug_parameter_mapping): New.
(debug_argument_list): New.
(expand_concept): Removed.
(normalize_logical_operation): Pass subst_info through call.
(normalize_pack_expansion): Remove.
(normalize_simple_requirement): Removed
(normalize_type_requirement): Removed
(normalize_compound_requirement): Removed
(normalize_nested_requirement): Removed
(normalize_requirement): Removed
(normalize_requirements): Removed
(normalize_requires_expression): Removed
(normalize_variable_concept_check): Removed.
(normalize_function_concept_check): Removed.
(normalize_concept_check): Merged all normalize_*_check here.
Substitute through written template arguments before normalizing the
definition. Only substitute the innermost template arguments.
(check_for_logical_overloads): Delete.
(map_arguments): New. Associate template parameters with arguments.
(build_parameter_mapping): New. Extract used parameters.
(normalize_expression): Rewrite.
(normalize_conjunction): Removed
(normalize_disjunction): Removed
(normalize_predicate_constraint): Removed
(normalize_parameterized_constraint): Removed
(normalized_map): New variable.
(get_normalized_constraints): New entry point for normalization.
Establishes a timer.
(get_normalized_constraints_from_info): New.
(get_normalized_constraints_from_decl): New. Turn on template processing
prior to normalization. Handle inheriting ctors. Build the
normalization arguments from the full set of template parameters of the
most general template. This guarantees that we have no concrete arguments
in the parameter mapping (e.g., from template members of class
templates). Cache normalizations.
(normalize_concept_definition): New. Cache normalizations.
(normalize_template_requirements): New.
(normalize_nontemplate_requirements): New.
(normalize_constraint_expression): New.
(tsubst_parameter_mapping): New.
(get_mapped_args): New.
(parameter_mapping_equivalent_p): New. Use template_args_equal.
(atomic_constraints_identical_p): New.
(hash_atomic_constraint): New.
(satisfying_constraint_p): New. Guard against recursive evaluation of
constraints during satisfaction.
(satisfy_conjunction): New.
(satisfy_disjunction): New.
(sat_entry): New class for hashing satisfaction results.
(sat_hasher): New hash traits.
(sat_cache): New.
(get_satisfaction): New. Returns cached satisfaction result.
(save_satisfaction): New. Caches a satisfaction result.
(clear_satisfaction_cache): New.
(satisfaction_cache): New. Helps manage satisfaction cache requests.
(decl_satisfied_cache): New.
(satisfy_atom): New.
(satisfy_constraint_r): New.
(satisfy_constraint): Use new satisfaction algorithm.
(evaluate_concept_check): New.
(evaluate_concept): Removed.
(evaluate_function_concept): Removed.
(evaluate_variable_concept): Removed.
(satisfy_constraint_expression): New.
(constraint_expression_satisfied_p): New.
(constraints_satisfied_p): Use strip_inheriting_ctors. Use
push_/pop_access_scope.
(more_constrained): Normalize before calling out to subsumption. Allow
classes as arguments.
(strictly_subsumes): Allow non-templates as arguments. Accept a new
template argument.
(weakly_subsumes): New.
(at_least_as_constrained): Removed.
(diagnose_other_expression): Removed.
(diagnose_predicate_constraint): Removed.
(diagnose_pack_expansion): Removed.
(diagnose_check_constraint): Removed.
(diagnose_logical_constraint): Removed.
(diagnose_expression_constraint): Removed.
(diagnose_type_constraint): Removed.
(diagnose_implicit_conversion_constraint): Removed.
(diagnose_argument_deduction_constraint): Removed.
(diagnose_exception_constraint): Removed.
(diagnose_parameterized_constraint): Removed.
(diagnose_argument_deduction_constraint): Removed.
(diagnose_argument_deduction_constraint): Removed.
(diagnose_argument_deduction_constraint): Removed.
(diagnose_trait_expr): New.
(diagnose_requires_expr): New.
(diagnose_atomic_constraint): New.
(diagnose_valid_expression) Stop wrongly diagnosing valid expressions.
Don't substitute as if in template decls. This causes substitution
to generate expressions that aren't suitable for use with the noexcept
routines.
(diagnose_valid_type) Likewise.
(diagnose_compound_requirement) Actually emit diagnostics for
the causes of errors.Call force_paren_expr_uneval.
(diagnose_declaration_constraints): Turn on template processing to
suppress certain analyses.
* cp-objcp-common.c (cp_common_init_ts): Make concepts typed.
(cp_get_debug_type): Use hash_map_safe_*.
* cp-tree.h: New function declarations for semantic actions, other
facilities. Remove declaration no longer used or needed. Remove
unused _CONSTR macros.
(LANG_DECL_HAS_MIN): Add CONCEPT_DECL.
(template_info_decl_check): Factor macro check into an inline function.
(DECL_TEMPLATE_INFO): Use new check facility.
(finish_concept_definition): New. Don't invalid concept declarations
with invalid initializers.
(find_template_parameters): New.
(concept_definition_p): New.
(concept_check_p): New.
(variable_concept_check_p): New.
(force_paren_expr_uneval): New.
(ovl_iterator::using_p): A USING_DECL by itself was also
introduced by a using-declaration.
(struct tree_template_info): Use tree_base instead of
tree_common. Add tmpl and args fields.
(TI_TEMPLATE, TI_ARGS): Adjust.
(DECLTYPE_FOR_INIT_CAPTURE): Remove.
(CONSTR_CHECK, CONSTR_INFO, CONSTR_EXPR, CONSTR_CONTEXT): New.
(ATOMIC_CONSTR_MAP, TRAIT_EXPR_LOCATION): New.
(struct tree_trait_expr): Add locus field.
(enum tsubst_flags): Add tf_norm as a hint to generate normalization
context when diagnosing constraint failure.
* cp-tree.def: Remove unused _CONSTR nodes and rename PRED_CONSTR
to ATOMIC_CONSTR.
(CONCEPT_DECL): New.
* cxx-pretty-print.c: Remove constraint printing code.
(pp_cxx_concept_definition): New.
(pp_cxx_template_declaration): Print concept definitions.
(pp_cxx_check_constraint): Update printing for concept definitions.
(pp_cxx_nested_name_specifier): Fix a weird
case where we're printing '::::' for concepts.
(simple_type_specifier): Print requirements for placeholder types.
(pp_cxx_constrained_type_spec): Print the associated requirements of
a placeholder type.
(pp_cxx_compound_requirement): Add space before the '->'.
(pp_cxx_parameter_mapping): Print the parameter mapping.
(pp_cxx_atomic_constraint): Use the function above.
* decl.c (redeclaration_error_message): New error for concepts.
(grokdeclarator): Check for and disallow decltype(auto) in parameter
declarations.
(grokfndecl): Don't normalize constraints. Add check for constraints
on declaration.
(grokvardecl): Don't normalize constraints.
(grok_special_member_properties): Don't set TYPE_HAS_COMPLEX_*.
(function_requirements_equivalent_p): New. Compare trailing
requires clauses. Compare combined constraints in pre-C++20 mode.
(decls_match): Compare trailing requires clauses. Compare template
heads for function templates. Remove old constraint comparison.
Simplify comparison of functions, function templates.
(duplicate_function_template_decls): New. Refactor a nasty if
condition into a single predicate.
(require_deduced_type): Don't complain if we already complained about
deduction failure.
(finish_function): Perform auto deduction to ensure that constraints
are checked even when functions contain no return statements. Only do
auto deduction if we haven't previously seen any return statements.
This prevents multiple diagnostics of the same error.
(store_decomp_type): Remove.
(cp_finish_decomp): Use hash_map_safe_put.
* error.c: Remove constraint printing code.
(dump_decl): Dump concept definitions. Handle wildcard declarations.
(dump_template_decl): Likewise.
(dump_type): Print associated requirements for placeholder
types.
(rebuild_concept_check): New.
(maybe_print_single_constraint_context): New.
(maybe_print_constraint_context): Recursively print nested contexts.
* init.c (get_nsdmi): Use hash_map_safe_*.
* lambda.c (maybe_add_lambda_conv_op): Bail if deduction failed.
(add_capture): Copy parameter packs from init.
(lambda_capture_field_type): Always use auto for init-capture.
* logic.cc: Completely rewrite.
(constraint_hash): New.
(clause/ctor): Save atoms in the hash table.
(replace): Save atoms during replacement.
(insert): Save atoms during insertion.
(contains): Only search the hash table for containment.
(clause): Keep a hash of atomic constraints.
(clause::clause): Explicitly copy the hash table when copying.
(disjunction_p, conjunction_p, atomic_p, dnf_size, cnf_size): New.
(diagnose_constraint_size): New.
(subsumes_constraints_nonnull): Compare the sizes of normalized formula
to determine the cheapest decomposition.
* name-lookup.c (diagnose_name_conflict): Diagnose name issues with
concepts.
(matching_fn_p): Check constraints.
(push_class_level_binding_1): Move overloaded functions case down,
accept FUNCTION_DECL as target_decl.
* parser.c (enum required_token): New required token for auto.
(make_location): Add overload taking lexer as last parm.
(cp_parser_required_error): Diagnose missing auto.
(cp_parser_diagnose_ungrouped_constraint_plain): New.
(cp_parser_diagnose_ungrouped_constraint_plain): New.
(cp_parser_constraint_primary_expression): New. Tentatively parse the
primary expression. If that fails tentatively parse a lower
precedence expression in order to diagnose the error.
(cp_parser_check_non_logical_constraint): New. Performs a trial
parse of the right-hand-side of non-logical operators in order to
generate good diagnostics.
(cp_parser_constraint_logical_and_expression): New.
(cp_parser_constraint_logical_or_expression): New.
(cp_parser_requires_clause_expression): New.
(cp_parser_requires_clause): Renamed to cp_parser_constraint_expression.
(cp_parser_requires_clause_opt): Parse the requires-clause differently
in -fconcepts and -std=c++2a modes.
(cp_parser_requirement_list): Rename to cp_parser_requirement_seq.
Rewrite so that semicolons are parsed
along with requirements, not the sequence.
(cp_parser_simple_requirement): Expect a semicolon at end.
(cp_parser_compound_requirement): Expect a semicolon at end. Only
allow trailing-return-type with -fconcepts-ts.
(cp_parser_nested_requirement): Expect a semicolon at end. Parse
constraint-expressions.
(cp_parser_concept_definition): New. Don't fail parsing the concept
definition if the initializer is ill-formed. Don't declare the concept
before parsing the initializer.
(cp_parser_constraint_expression): Declare earlier.
(cp_parser_type_requirement): Current scope is not valid.
(cp_parser_requires_expression): Commit to the tentative parse.
(cp_parser_decl_specifier_seq): Warn when concept appears to be used
as a decl-specifier.
(cp_parser_template_declaration_after_parameters): Parse concept
definitions.
(cp_parser_template_id): Don't try to resolve a concept template-id yet.
(cp_parser_template_id_expr): Resolve it as a concept check.
(cp_parser_decl_specifier_seq): Warn on 'concept bool'.
(cp_parser_type_parameter): Combine expressions not
constraints.
(cp_parser_explicit_template_declaration): Combine expressions not
constraints.
(cp_parser_maybe_concept_name): Removed.
(cp_parser_simple_type_specifier): Handle an error condition of
a bad constrained type specifier. Expect auto or decltype after
a concept name. Also handle the case where we have a template-id
as a concept check.
(cp_parser_template_introduction): Diagnose errors on invalid
introductions. Give up if it doesn't start with a concept name.
Pedwarn if not -fconcepts-ts.
(synthesize_implicit_template_parm): Don't do consistent binding.
Use a new flag for constrained parameters. Combine expressions,
not constraints. Fail if we get a placeholder in block scope.
Placeholders that do not constrain types are not allowed in parameter
declarations, so don't handle them.
(cp_parser_placeholder_type_specifier): New. Implement parsing of
placeholder type specifiers following a concept name or partial
concept check. Disallow decltype(auto) parameters.
(cp_parser_nested_name_specifier_opt): If the token is already
CPP_NESTED_NAME_SPECIFIER, leave it alone.
(cp_parser_id_expression, cp_parser_unqualified_id): Call
cp_parser_template_id_expr.
(cp_parser_placeholder_type_specifier): Add tentative parm. Don't
expect a WILDCARD_DECL.
(cp_parser_trait_expr): Pass trait_loc down.
(cp_parser_postfix_expression): Do set location of dependent member
call.
* pt.c (finish_concept_definition): New.
(push_template_decl_real): Handle concept definitions.
(start_concept_definition): Let push_template_decl_real handle the
creation of the template.
(get_constraints): Return null if the table hasn't been initialized.
(tsubst_copy_and_build): Build template-id expressions for concept
checks.
[TRAIT_EXPR]: Pass trait_loc down.
(lookup_template_class_1): Add the template name to the constraint
failure diagnostic.
(lookup_and_finish_template_variable): Build concept checks
with the correct arguments.
(tsubst_function_decl): Don't substitute through constraints.
Always associate constraints with functions.
(template_parm_level_and_index): Make non-static.
(for_each_template_parm_r): Handle requires expressions.
(keep_template_parm): New.
(find_template_parameters): New.
(more_specialized_fn): Change how winners and losers are chosen.
(make_constrained_auto): Don't normalize constraints.
(template_parameters_equivalent_p): New. Compare template
parameters. Add a comparison for implicitly vs. explicitly declared
parameters.
(template_parameter_lists_equivalent_p): New. Compare template
parameter lists.
(template_requirements_equivalent_p): New.
(template_heads_equivalent_p): New. Compare template heads.
(template_parameter_constraints_equivalent_p): New.
(is_compatible_template_arg): Use weakly_subsumes.
(maybe_new_partial_specialization): Use new constraint comparison
for finding specializations.
(process_partial_specialization): Pass main template as argument.
(more_specialized_partial_spec): Don't immediately return when
detecting a winner.
(make_constrained_auto): Handle concept definitions.
(do_auto_deduction): Update auto deduction for new concept model.
Extract the function concept correctly; rename constr to check to
reflect the kind of node.
(tsubst): Adjust wildcard argument during substitution.
[DECLTYPE_TYPE]: Remove init-capture handling.
(tsubst_copy_and_build): Build concept checks, not template ids.
Defer checks of function concepts. Handle concepts before variable
templates. Handle calls to function concepts explicitly.
(coerce_template_parms): Use concept_definition_p. Handle a deduction
error where a potentially empty pack can be supplied after the last
parameter of a concept.
(finish_template_variable): Don't process concepts here.
(instantiation_dependent_r): Use concept_check_p.
(tsubst_template_args): Make non-static.
(make_constrained_placeholder_type): New. Refactored from
make_constrained_auto.
(make_constrained_auto) Use make_constrained_placeholder_type.
(make_constrained_decltype_auto) New.
(tsubst_function_parms): New.
(value_dependent_expression_p) [TEMPLATE_ID_EXPR]: Use
concept_definition_p.
(push_access_scope, pop_access_scope): No longer static.
(tsubst_template_parm): Substitute TEMPLATE_PARM_CONSTRAINTS.
(tsubst_friend_function): Use tsubst_constraint. Use generic_targs_for.
(get_underlying_template) Use generic_targs_for.
(uses_parameter_packs): Return tree.
(gen_elem_of_pack_expansion_instantiation): Don't push
local_specialization_stack.
(prepend_one_capture): New.
(tsubst_lambda_expr): Use prepend_one_capture. Don't touch
local_specializations.
(template_parms_level_to_args): No longer static.
(add_outermost_template_args): Likewise.
(find_template_parameter_info): New. Provide context for finding
template parameters.
(keep_template_parm): Don't keep parameters declared at depth levels
greater than those of the template parameters of the source declaration.
Don't propagate cv-qualified types. Return 0, so we find all template
parameters, not the just first.
(any_template_parm_r): New. Handle cases that are mishandled by
for_each_template_parm_r.
(generic_targs_for): Factor out of coerce_template_args_for_ttp.
(tsubst_argument_pack): Factor out of tsubst_template_args.
(constraint_sat_entry): Removed.
(constraint_sat_hasher): Removed.
(concept_spec_entry): Removed.
(concept_spec_hasher): Removed.
(constraint_memos): Removed.
(concept_memos): Removed.
(lookup_constraint_satisfaction): Removed.
(memoize_constraint_satisfaction): Removed.
(lookup_concept_satisfaction): Removed.
(memoize_concept_satisfaction): Removed.
(concept_expansions): Removed.
(get_concept_expansion): Removed.
(save_concept_expansion): Removed.
(init_constraint_processing): Remove initialization of non-existing
resources.
(find_template_requirement): New. Search for the sub-requirement
within the associated constraints.
(convert_generic_types_to_packs): Also transform the associated
constraint and update the current template requirements.
(store_defaulted_ttp, lookup_defaulted_ttp): Remove.
(add_defaults_to_ttp): Use hash_map_safe_*.
* semantics.c (finish_call_expr): Diagnose calls to concepts.
Handle concept checks explicitly.
(finish_id_expression): Evaluate variable concepts as part of
id-expression processing. Don't treat variable concepts as variables,
and don't process function concepts as plain id-expressions.
(force_paren_expr): Add even_uneval parm.
(finish_trait_expr): Add location parm.
* tree.c (special_memfn_p): New.
(cp_expr_location): Handle TRAIT_EXPR.
* typeck.c (check_return_expr): Actually use the diagnostic kind
when performing return-type deduction.
* typeck2.c (build_functional_cast): Don't rely on the location of
'auto'.
gcc/testsuite/
* lib/target-supports.exp (check_effective_target_concepts): Check
for std=c++2a.
gcc/
* doc/invoke.texi: Document -fconcepts-ts.
From-SVN: r276764
Diffstat (limited to 'gcc/cp/cp-tree.h')
-rw-r--r-- | gcc/cp/cp-tree.h | 358 |
1 files changed, 241 insertions, 117 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index b82b580..9ff617b 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -1522,9 +1522,37 @@ check_constraint_info (tree t) #define PLACEHOLDER_TYPE_CONSTRAINTS(NODE) \ DECL_SIZE_UNIT (TYPE_NAME (NODE)) -/* The expression evaluated by the predicate constraint. */ -#define PRED_CONSTR_EXPR(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, PRED_CONSTR), 0) +/* Valid for any normalized constraint. */ +#define CONSTR_CHECK(NODE) \ + TREE_CHECK3 (NODE, ATOMIC_CONSTR, CONJ_CONSTR, DISJ_CONSTR) + +/* The CONSTR_INFO stores normalization data for a constraint. It refers to + the original expression and the expression or declaration + from which the constraint was normalized. + + This is TREE_LIST whose TREE_PURPOSE is the original expression and whose + TREE_VALUE is a list of contexts. */ +#define CONSTR_INFO(NODE) \ + TREE_TYPE (CONSTR_CHECK (NODE)) + +/* The expression evaluated by the constraint. */ +#define CONSTR_EXPR(NODE) \ + TREE_PURPOSE (CONSTR_INFO (NODE)) + +/* The expression or declaration from which this constraint was normalized. + This is a TREE_LIST whose TREE_VALUE is either a template-id expression + denoting a concept check or the declaration introducing the constraint. + These are chained to other context objects. */ +#define CONSTR_CONTEXT(NODE) \ + TREE_VALUE (CONSTR_INFO (NODE)) + +/* The parameter mapping for an atomic constraint. */ +#define ATOMIC_CONSTR_MAP(NODE) \ + TREE_OPERAND (TREE_CHECK (NODE, ATOMIC_CONSTR), 0) + +/* The expression of an atomic constraint. */ +#define ATOMIC_CONSTR_EXPR(NODE) \ + CONSTR_EXPR (ATOMIC_CONSTR_CHECK (NODE)) /* The concept of a concept check. */ #define CHECK_CONSTR_CONCEPT(NODE) \ @@ -1534,46 +1562,6 @@ check_constraint_info (tree t) #define CHECK_CONSTR_ARGS(NODE) \ TREE_OPERAND (TREE_CHECK (NODE, CHECK_CONSTR), 1) -/* The expression validated by the predicate constraint. */ -#define EXPR_CONSTR_EXPR(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, EXPR_CONSTR), 0) - -/* The type validated by the predicate constraint. */ -#define TYPE_CONSTR_TYPE(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, TYPE_CONSTR), 0) - -/* In an implicit conversion constraint, the source expression. */ -#define ICONV_CONSTR_EXPR(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, ICONV_CONSTR), 0) - -/* In an implicit conversion constraint, the target type. */ -#define ICONV_CONSTR_TYPE(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, ICONV_CONSTR), 1) - -/* In an argument deduction constraint, the source expression. */ -#define DEDUCT_CONSTR_EXPR(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, DEDUCT_CONSTR), 0) - -/* In an argument deduction constraint, the target type pattern. */ -#define DEDUCT_CONSTR_PATTERN(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, DEDUCT_CONSTR), 1) - -/* In an argument deduction constraint, the list of placeholder nodes. */ -#define DEDUCT_CONSTR_PLACEHOLDER(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, DEDUCT_CONSTR), 2) - -/* The expression of an exception constraint. */ -#define EXCEPT_CONSTR_EXPR(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, EXCEPT_CONSTR), 0) - -/* In a parameterized constraint, the local parameters. */ -#define PARM_CONSTR_PARMS(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, PARM_CONSTR), 0) - -/* In a parameterized constraint, the operand. */ -#define PARM_CONSTR_OPERAND(NODE) \ - TREE_OPERAND (TREE_CHECK (NODE, PARM_CONSTR), 1) - /* Whether a PARM_DECL represents a local parameter in a requires-expression. */ #define CONSTRAINT_VAR_P(NODE) \ @@ -1663,6 +1651,7 @@ struct GTY(()) saved_scope { int x_processing_template_decl; int x_processing_specialization; + int x_processing_constraint; int suppress_location_wrappers; BOOL_BITFIELD x_processing_explicit_instantiation : 1; BOOL_BITFIELD need_pop_function_context : 1; @@ -2627,7 +2616,8 @@ struct GTY(()) lang_decl_base { || TREE_CODE (NODE) == CONST_DECL \ || TREE_CODE (NODE) == TYPE_DECL \ || TREE_CODE (NODE) == TEMPLATE_DECL \ - || TREE_CODE (NODE) == USING_DECL) + || TREE_CODE (NODE) == USING_DECL \ + || TREE_CODE (NODE) == CONCEPT_DECL) /* DECL_LANG_SPECIFIC for the above codes. */ @@ -3358,6 +3348,33 @@ struct GTY(()) lang_decl { #define TEMPLATE_DECL_COMPLEX_ALIAS_P(NODE) \ DECL_LANG_FLAG_2 (TEMPLATE_DECL_CHECK (NODE)) +/* Returns t iff the node can have a TEMPLATE_INFO field. */ + +inline tree +template_info_decl_check (const_tree t, const char* f, int l, const char* fn) +{ + switch (TREE_CODE (t)) + { + case VAR_DECL: + case FUNCTION_DECL: + case FIELD_DECL: + case TYPE_DECL: + case CONCEPT_DECL: + case TEMPLATE_DECL: + return const_cast<tree>(t); + default: + break; + } + tree_check_failed (t, f, l, fn, + VAR_DECL, FUNCTION_DECL, FIELD_DECL, TYPE_DECL, + CONCEPT_DECL, TEMPLATE_DECL, 0); + gcc_unreachable (); +} + + +#define TEMPLATE_INFO_DECL_CHECK(NODE) \ + template_info_decl_check ((NODE), __FILE__, __LINE__, __FUNCTION__) + /* Nonzero for a type which is an alias for another type; i.e, a type which declaration was written 'using name-of-type = another-type'. */ @@ -3367,8 +3384,8 @@ struct GTY(()) lang_decl { && TREE_CODE (TYPE_NAME (NODE)) == TYPE_DECL \ && TYPE_DECL_ALIAS_P (TYPE_NAME (NODE))) -/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL or - TEMPLATE_DECL, the entity is either a template specialization (if +/* If non-NULL for a VAR_DECL, FUNCTION_DECL, TYPE_DECL, TEMPLATE_DECL, + or CONCEPT_DECL, the entity is either a template specialization (if DECL_USE_TEMPLATE is nonzero) or the abstract instance of the template itself. @@ -3387,7 +3404,7 @@ struct GTY(()) lang_decl { global function f. In this case, DECL_TEMPLATE_INFO for S<int>::f will be non-NULL, but DECL_USE_TEMPLATE will be zero. */ #define DECL_TEMPLATE_INFO(NODE) \ - (DECL_LANG_SPECIFIC (VAR_TEMPL_TYPE_FIELD_OR_FUNCTION_DECL_CHECK (NODE)) \ + (DECL_LANG_SPECIFIC (TEMPLATE_INFO_DECL_CHECK (NODE)) \ ->u.min.template_info) /* For a lambda capture proxy, its captured variable. */ @@ -5222,6 +5239,8 @@ enum tsubst_flags { declaration. */ tf_no_cleanup = 1 << 10, /* Do not build a cleanup (build_target_expr and friends) */ + tf_norm = 1 << 11, /* Build diagnostic information during + constraint normalization. */ /* Convenient substitution flags combinations. */ tf_warning_or_error = tf_warning | tf_error }; @@ -6121,43 +6140,6 @@ class_of_this_parm (const_tree fntype) return TREE_TYPE (type_of_this_parm (fntype)); } -/* True iff T is a variable template declaration. */ -inline bool -variable_template_p (tree t) -{ - if (TREE_CODE (t) != TEMPLATE_DECL) - return false; - if (!PRIMARY_TEMPLATE_P (t)) - return false; - if (tree r = DECL_TEMPLATE_RESULT (t)) - return VAR_P (r); - return false; -} - -/* True iff T is a variable concept definition. That is, T is - a variable template declared with the concept specifier. */ -inline bool -variable_concept_p (tree t) -{ - if (TREE_CODE (t) != TEMPLATE_DECL) - return false; - if (tree r = DECL_TEMPLATE_RESULT (t)) - return VAR_P (r) && DECL_DECLARED_CONCEPT_P (r); - return false; -} - -/* True iff T is a concept definition. That is, T is a variable or function - template declared with the concept specifier. */ -inline bool -concept_template_p (tree t) -{ - if (TREE_CODE (t) != TEMPLATE_DECL) - return false; - if (tree r = DECL_TEMPLATE_RESULT (t)) - return VAR_OR_FUNCTION_DECL_P (r) && DECL_DECLARED_CONCEPT_P (r); - return false; -} - /* A parameter list indicating for a function with no parameters, e.g "int f(void)". */ extern cp_parameter_declarator *no_parameters; @@ -6614,6 +6596,9 @@ extern void finish_eh_spec_block (tree, tree); extern tree build_eh_type_type (tree); extern tree cp_protect_cleanup_actions (void); extern tree create_try_catch_expr (tree, tree); +extern tree template_parms_to_args (tree); +extern tree template_parms_level_to_args (tree); +extern tree generic_targs_for (tree); /* in expr.c */ extern tree cplus_expand_constant (tree); @@ -6747,6 +6732,8 @@ extern void maybe_show_extern_c_location (void); extern bool literal_integer_zerop (const_tree); /* in pt.c */ +extern void push_access_scope (tree); +extern void pop_access_scope (tree); extern bool check_template_shadow (tree); extern bool check_auto_in_tmpl_args (tree, tree); extern tree get_innermost_template_args (tree, int); @@ -6766,6 +6753,8 @@ extern int num_template_headers_for_class (tree); extern void check_template_variable (tree); extern tree make_auto (void); extern tree make_decltype_auto (void); +extern tree make_constrained_auto (tree, tree); +extern tree make_constrained_decltype_auto (tree, tree); extern tree make_template_placeholder (tree); extern bool template_placeholder_p (tree); extern tree do_auto_deduction (tree, tree, tree, @@ -6792,6 +6781,7 @@ extern bool check_default_tmpl_args (tree, tree, bool, bool, int); extern tree push_template_decl (tree); extern tree push_template_decl_real (tree, bool); extern tree add_inherited_template_parms (tree, tree); +extern void template_parm_level_and_index (tree, int*, int*); extern bool redeclare_class_template (tree, tree, tree); extern tree lookup_template_class (tree, tree, tree, tree, int, tsubst_flags_t); @@ -6816,6 +6806,7 @@ extern bool always_instantiate_p (tree); extern bool maybe_instantiate_noexcept (tree, tsubst_flags_t = tf_warning_or_error); extern tree instantiate_decl (tree, bool, bool); extern int comp_template_parms (const_tree, const_tree); +extern bool template_heads_equivalent_p (const_tree, const_tree); extern bool builtin_pack_fn_p (tree); extern tree uses_parameter_packs (tree); extern bool template_parameter_pack_p (const_tree); @@ -6844,7 +6835,11 @@ extern tree tsubst_copy_and_build (tree, tree, tsubst_flags_t, tree, bool, bool); extern tree tsubst_expr (tree, tree, tsubst_flags_t, tree, bool); -extern tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree); +extern tree tsubst_pack_expansion (tree, tree, tsubst_flags_t, tree); +extern tree tsubst_argument_pack (tree, tree, tsubst_flags_t, tree); +extern tree tsubst_template_args (tree, tree, tsubst_flags_t, tree); +extern tree tsubst_template_arg (tree, tree, tsubst_flags_t, tree); +extern tree tsubst_function_parms (tree, tree, tsubst_flags_t, tree); extern tree most_general_template (tree); extern tree get_mostly_instantiated_function_type (tree); extern bool problematic_instantiation_changed (void); @@ -6913,6 +6908,7 @@ extern bool deduction_guide_p (const_tree); extern bool copy_guide_p (const_tree); extern bool template_guide_p (const_tree); extern void store_explicit_specifier (tree, tree); +extern tree add_outermost_template_args (tree, tree); /* in rtti.c */ /* A vector of all tinfo decls that haven't been emitted yet. */ @@ -7077,7 +7073,9 @@ extern tree finish_asm_stmt (location_t, int, tree, tree, extern tree finish_label_stmt (tree); extern void finish_label_decl (tree); extern cp_expr finish_parenthesized_expr (cp_expr); -extern tree force_paren_expr (tree); +extern tree force_paren_expr (tree, bool = false); +inline tree force_paren_expr_uneval (tree t) +{ return force_paren_expr (t, true); } extern tree maybe_undo_parenthesized_ref (tree); extern tree maybe_strip_ref_conversion (tree); extern tree finish_non_static_data_member (tree, tree, tree); @@ -7661,69 +7659,97 @@ typedef void cp_binding_oracle_function (enum cp_oracle_request, tree identifier extern cp_binding_oracle_function *cp_binding_oracle; +/* Set during diagnostics to record the failed constraint. This is a + TREE_LIST whose VALUE is the constraint and whose PURPOSE are the + instantiation arguments Defined in pt.c. */ + +extern tree current_failed_constraint; + +/* An RAII class to manage the failed constraint. */ + +struct diagnosing_failed_constraint +{ + diagnosing_failed_constraint (tree, tree, bool); + ~diagnosing_failed_constraint (); + + bool diagnosing_error; +}; + /* in constraint.cc */ -extern void init_constraint_processing (); -extern bool constraint_p (tree); -extern tree conjoin_constraints (tree, tree); -extern tree conjoin_constraints (tree); + +extern void init_constraint_processing (); +extern cp_expr finish_constraint_or_expr (location_t, cp_expr, cp_expr); +extern cp_expr finish_constraint_and_expr (location_t, cp_expr, cp_expr); +extern cp_expr finish_constraint_primary_expr (cp_expr); +extern tree finish_concept_definition (cp_expr, tree); +extern tree combine_constraint_expressions (tree, tree); extern tree get_constraints (tree); extern void set_constraints (tree, tree); extern void remove_constraints (tree); extern tree current_template_constraints (void); extern tree associate_classtype_constraints (tree); extern tree build_constraints (tree, tree); +extern tree get_template_head_requirements (tree); +extern tree get_trailing_function_requirements (tree); extern tree get_shorthand_constraints (tree); -extern tree build_concept_check (tree, tree, tree = NULL_TREE); + +extern tree build_concept_id (tree); +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 tree make_constrained_auto (tree, tree); extern void placeholder_extract_concept_and_args (tree, tree&, tree&); extern bool equivalent_placeholder_constraints (tree, tree); extern hashval_t hash_placeholder_constraint (tree); extern bool deduce_constrained_parameter (tree, tree&, tree&); extern tree resolve_constraint_check (tree); extern tree check_function_concept (tree); -extern tree finish_template_introduction (tree, tree); +extern tree finish_template_introduction (tree, tree, location_t loc); extern bool valid_requirements_p (tree); extern tree finish_concept_name (tree); extern tree finish_shorthand_constraint (tree, tree); -extern tree finish_requires_expr (tree, tree); -extern tree finish_simple_requirement (tree); -extern tree finish_type_requirement (tree); -extern tree finish_compound_requirement (tree, tree, bool); -extern tree finish_nested_requirement (tree); +extern tree finish_requires_expr (location_t, tree, tree); +extern tree finish_simple_requirement (location_t, tree); +extern tree finish_type_requirement (location_t, tree); +extern tree finish_compound_requirement (location_t, tree, tree, bool); +extern tree finish_nested_requirement (location_t, tree); extern void check_constrained_friend (tree, tree); extern tree tsubst_requires_expr (tree, tree, tsubst_flags_t, tree); extern tree tsubst_constraint (tree, tree, tsubst_flags_t, tree); extern tree tsubst_constraint_info (tree, tree, tsubst_flags_t, tree); -extern bool function_concept_check_p (tree); -extern tree normalize_expression (tree); -extern tree expand_concept (tree, tree); -extern bool expanding_concept (); -extern tree evaluate_constraints (tree, tree); -extern tree evaluate_function_concept (tree, tree); -extern tree evaluate_variable_concept (tree, tree); -extern tree evaluate_constraint_expression (tree, tree); +extern tree tsubst_parameter_mapping (tree, tree, tsubst_flags_t, tree); +extern tree get_mapped_args (tree); + +struct processing_constraint_expression_sentinel +{ + processing_constraint_expression_sentinel (); + ~processing_constraint_expression_sentinel (); +}; + +extern bool processing_constraint_expression_p (); + +extern tree unpack_concept_check (tree); +extern tree evaluate_concept_check (tree, tsubst_flags_t); +extern tree satisfy_constraint_expression (tree); extern bool constraints_satisfied_p (tree); extern bool constraints_satisfied_p (tree, tree); -extern tree lookup_constraint_satisfaction (tree, tree); -extern tree memoize_constraint_satisfaction (tree, tree, tree); -extern tree lookup_concept_satisfaction (tree, tree); -extern tree memoize_concept_satisfaction (tree, tree, tree); -extern tree get_concept_expansion (tree, tree); -extern tree save_concept_expansion (tree, tree, tree); +extern void clear_satisfaction_cache (); extern bool* lookup_subsumption_result (tree, tree); extern bool save_subsumption_result (tree, tree, bool); - +extern tree find_template_parameters (tree, int); extern bool equivalent_constraints (tree, tree); extern bool equivalently_constrained (tree, tree); extern bool subsumes_constraints (tree, tree); -extern bool strictly_subsumes (tree, tree); +extern bool strictly_subsumes (tree, tree, tree); +extern bool weakly_subsumes (tree, tree, tree); extern int more_constrained (tree, tree); - +extern bool atomic_constraints_identical_p (tree, tree); +extern hashval_t hash_atomic_constraint (tree); extern void diagnose_constraints (location_t, tree, tree); /* in logic.cc */ -extern tree decompose_conclusions (tree); extern bool subsumes (tree, tree); /* In class.c */ @@ -7773,7 +7799,7 @@ extern bool var_in_maybe_constexpr_fn (tree); extern void explain_invalid_constexpr_fn (tree); extern vec<tree> cx_error_context (void); extern tree fold_sizeof_expr (tree); -extern void clear_cv_and_fold_caches (void); +extern void clear_cv_and_fold_caches (bool = true); extern tree unshare_constructor (tree CXX_MEM_STAT_INFO); /* In cp-ubsan.c */ @@ -7820,6 +7846,104 @@ null_node_p (const_tree expr) return expr == null_node; } +/* True iff T is a variable template declaration. */ +inline bool +variable_template_p (tree t) +{ + if (TREE_CODE (t) != TEMPLATE_DECL) + return false; + if (!PRIMARY_TEMPLATE_P (t)) + return false; + if (tree r = DECL_TEMPLATE_RESULT (t)) + return VAR_P (r); + return false; +} + +/* True iff T is a standard concept definition. This will return + true for both the template and underlying declaration. */ + +inline bool +standard_concept_p (tree t) +{ + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + return TREE_CODE (t) == CONCEPT_DECL; +} + +/* True iff T is a variable concept definition. This will return + true for both the template and the underlying declaration. */ + +inline bool +variable_concept_p (tree t) +{ + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + return VAR_P (t) && DECL_DECLARED_CONCEPT_P (t); +} + +/* True iff T is a function concept definition or an overload set + containing multiple function concepts. This will return true for + both the template and the underlying declaration. */ + +inline bool +function_concept_p (tree t) +{ + if (TREE_CODE (t) == OVERLOAD) + t = OVL_FIRST (t); + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + return TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_CONCEPT_P (t); +} + +/* True iff T is a standard, variable, or function concept. */ + +inline bool +concept_definition_p (tree t) +{ + if (t == error_mark_node) + return false; + + /* Adjust for function concept overloads. */ + if (TREE_CODE (t) == OVERLOAD) + t = OVL_FIRST (t); + + /* See through templates. */ + if (TREE_CODE (t) == TEMPLATE_DECL) + t = DECL_TEMPLATE_RESULT (t); + + /* The obvious and easy case. */ + if (TREE_CODE (t) == CONCEPT_DECL) + return true; + + /* Definitely not a concept. */ + if (!VAR_OR_FUNCTION_DECL_P (t)) + return false; + if (!DECL_LANG_SPECIFIC (t)) + return false; + + return DECL_DECLARED_CONCEPT_P (t); +} + +/* Same as above, but for const trees. */ + +inline bool +concept_definition_p (const_tree t) +{ + return concept_definition_p (const_cast<tree> (t)); +} + +/* True if t is an expression that checks a concept. */ + +inline bool +concept_check_p (const_tree t) +{ + if (TREE_CODE (t) == CALL_EXPR) + t = CALL_EXPR_FN (t); + if (t && TREE_CODE (t) == TEMPLATE_ID_EXPR) + return concept_definition_p (TREE_OPERAND (t, 0)); + return false; +} + #if CHECKING_P namespace selftest { extern void run_cp_tests (void); |