summaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-07 05:44:49 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2015-08-07 05:44:49 +0000
commit56c12fd4ba064759724236ad896232603b8797ed (patch)
tree23bad22378f96699b757d5523bf73d4139ad66da /gcc/cp/semantics.c
parent29890f2ede84580ebc07431f87e20cc787db8598 (diff)
downloadgcc-56c12fd4ba064759724236ad896232603b8797ed.tar.gz
Add C++ Concepts TS support.
gcc/c-family/ * c-common.c (c_common_reswords): Add __is_same_as, concept, requires. * c-common.h (enum rid): Add RID_IS_SAME_AS, RID_CONCEPT, RID_REQUIRES. (D_CXX_CONCEPTS, D_CXX_CONCEPTS_FLAGS): New. * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_concepts. * c-opts.c (set_std_cxx1z): Set flag_concepts. * c.opt (fconcepts): New. gcc/cp/ * constraint.cc, logic.cc: New files. * Make-lang.in (CXX_AND_OBJCXX_OBJS): Add constraint.o and logic.o. (c++.tags): Also process .cc files. * call.c (enum rejection_reason_code): Add rr_constraint_failure. (print_z_candidate): Handle it. (constraint_failure): New. (add_function_candidate): Check constraints. (build_new_function_call): Handle evaluating concepts. (joust): Check more_constrained. * class.c (add_method): Check equivalently_constrained. (build_clone): Copy constraints. (currently_open_class): Return tree. (resolve_address_of_overloaded_function): Check constraints. * constexpr.c (cxx_eval_constant_expression): Handle REQUIRES_EXPR. (potential_constant_expression_1): Likewise. * cp-objcp-common.c (cp_tree_size): Handle CONSTRAINT_INFO. (cp_common_init_ts): Handle WILDCARD_DECL and REQUIRES_EXPR. * cp-tree.def: Add CONSTRAINT_INFO, WILDCARD_DECL, REQUIRES_EXPR, SIMPLE_REQ, TYPE_REQ, COMPOUND_REQ, NESTED_REQ, PRED_CONSTR, EXPR_CONSTR, TYPE_CONSTR, ICONV_CONSTR, DEDUCT_CONSTR, EXCEPT_CONSTR, PARM_CONSTR, CONJ_CONSTR, DISJ_CONSTR. * cp-tree.h (struct tree_constraint_info, check_nonnull) (check_constraint_info, CI_TEMPLATE_REQS, CI_DECLARATOR_REQS) (CI_ASSOCIATED_CONSTRAINTS, CI_NORMALIZED_CONSTRAINTS) (CI_ASSUMPTIONS, TEMPLATE_PARMS_CONSTRAINTS) (TEMPLATE_PARM_CONSTRAINTS, COMPOUND_REQ_NOEXCEPT_P) (PLACEHOLDER_TYPE_CONSTRAINTS, PRED_CONSTR_EXPR, EXPR_CONSTR_EXPR) (TYPE_CONSTR_TYPE, ICONV_CONSTR_EXPR, ICONV_CONSTR_TYPE) (DEDUCT_CONSTR_EXPR, DEDUCT_CONSTR_PATTERN) (DEDUCT_CONSTR_PLACEHOLDER, EXCEPT_CONSTR_EXPR, PARM_CONSTR_PARMS) (PARM_CONSTR_OPERAND, CONSTRAINT_VAR_P, CONSTRAINED_PARM_CONCEPT) (CONSTRAINED_PARM_EXTRA_ARGS, CONSTRAINED_PARM_PROTOTYPE) (DECL_DECLARED_CONCEPT_P, WILDCARD_PACK_P, struct cp_unevaluated) (struct local_specialization_stack, enum auto_deduction_context) (variable_concept_p, concept_template_p) (struct deferring_access_check_sentinel): New. (enum cp_tree_node_structure_enum): Add TS_CP_CONSTRAINT_INFO. (union lang_tree_node): Add constraint_info field. (struct lang_decl_base): Add concept_p flag. (enum cp_decl_spec): Add ds_concept. (struct cp_declarator): Add requires_clause. * cxx-pretty-print.c (cxx_pretty_printer::primary_expression) (cxx_pretty_printer::expression): Handle REQUIRES_EXPR, TRAIT_EXPR, *_CONSTR. (pp_cxx_parameter_declaration_clause): Accept a chain of PARM_DECLs. (cxx_pretty_printer::declarator): Print requires-clause. (pp_cxx_template_declaration): Likewise. (pp_cxx_trait_expression): Handle CPTK_IS_SAME_AS. (pp_cxx_requires_clause, pp_cxx_requirement) (pp_cxx_requirement_list, pp_cxx_requirement_body) (pp_cxx_requires_expr, pp_cxx_simple_requirement) (pp_cxx_type_requirement, pp_cxx_compound_requirement) (pp_cxx_nested_requirement, pp_cxx_predicate_constraint) (pp_cxx_expression_constraint, pp_cxx_type_constraint) (pp_cxx_implicit_conversion_constraint) (pp_cxx_argument_deduction_constraint) (pp_cxx_exception_constraint, pp_cxx_parameterized_constraint) (pp_cxx_conjunction, pp_cxx_disjunction, pp_cxx_constraint): New. * cxx-pretty-print.h: Declare them. * decl.c (decls_match): Compare constraints. (duplicate_decls): Likewise. Remove constraints before freeing. (cxx_init_decl_processing): Call init_constraint_processing. (cp_finish_decl): Diagnose concept without initializer. (grokfndecl, grokvardecl): Handle concepts and constraints. (grokdeclarator): Handle concept, requires-clause. (grokparms): No longer static. (xref_tag_1): Check constraints. (finish_function): Call check_function_concept. (cp_tree_node_structure): Handle CONSTRAINT_INFO. (check_concept_refinement, is_concept_var, check_concept_fn): New. * decl2.c (check_classfn): Compare constraints. (mark_used): Don't instantiate concepts. * error.c (dump_template_decl): Print constraints. (dump_function_decl): Likewise. (dump_expr): Handle REQUIRES_EXPR, *_REQ, *_CONSTR. * lex.c (init_reswords): Set D_CXX_CONCEPTS. * method.c (implicitly_declare_fn): Copy constraints from inherited ctor. * parser.h (struct cp_parser): Add in_result_type_constraint_p and prevent_constrained_type_specifiers fields. * parser.c (make_call_declarator): Add requires_clause parm. (cp_parser_new): Clear prevent_constrained_type_specifiers. (cp_parser_primary_expression): Handle RID_IS_SAME_AS, RID_REQUIRES. (cp_parser_postfix_expression): Set prevent_constrained_type_specifiers. (cp_parser_trait_expr): Handle RID_IS_SAME_AS. (cp_parser_declaration): Handle concept introduction. (cp_parser_member_declaration): Likewise. (cp_parser_template_parameter): Handle constrained parameter. (cp_parser_type_parameter): Handle constraints. (cp_parser_decl_specifier_seq): Handle RID_CONCEPT. (cp_parser_template_id): Handle partial concept id. (cp_parser_type_name): Add overload that takes typename_keyword_p. Handle constrained parameter. (cp_parser_nonclass_name): Handle concept names. (cp_parser_alias_declaration): Handle constraints. (cp_parser_late_return_type_opt): Also handle requires-clause. (cp_parser_type_id_1): Handle deduction constraint. (cp_parser_parameter_declaration): Handle constrained parameters. (cp_parser_class_specifier_1): Handle constraints. (cp_parser_template_declaration_after_parameters): Split out from cp_parser_template_declaration_after_export. (cp_parser_single_declaration): Handle constraints. (synthesize_implicit_template_parm): Handle constraints. (cp_parser_maybe_concept_name, cp_parser_maybe_partial_concept_id) (cp_parser_introduction_list, get_id_declarator) (get_unqualified_id, is_constrained_parameter) (cp_parser_check_constrained_type_parm) (cp_parser_constrained_type_template_parm) (cp_parser_constrained_template_template_parm) (constrained_non_type_template_parm, finish_constrained_parameter) (declares_constrained_type_template_parameter) (declares_constrained_template_template_parameter) (check_type_concept, cp_parser_maybe_constrained_type_specifier) (cp_parser_maybe_concept_name, cp_parser_maybe_partial_concept_id) (cp_parser_requires_clause, cp_parser_requires_clause_opt) (cp_parser_requires_expression) (cp_parser_requirement_parameter_list, cp_parser_requirement_body) (cp_parser_requirement_list, cp_parser_requirement) (cp_parser_simple_requirement, cp_parser_type_requirement) (cp_parser_compound_requirement, cp_parser_nested_requirement) (cp_parser_template_introduction) (cp_parser_explicit_template_declaration) (get_concept_from_constraint): New. * pt.c (local_specialization_stack): Implement. (maybe_new_partial_specialization): New. (maybe_process_partial_specialization): Use it. (retrieve_local_specialization, register_local_specialization) (template_parm_to_arg, build_template_decl, extract_fnparm_pack) (tsubst_expr): No longer static. (spec_hasher::equal): Compare constraints. (determine_specialization): Handle constraints. (check_explicit_specialization): Handle concepts. (process_template_parm): Handle constraints. (end_template_parm_list): Add overload taking no arguments. (process_partial_specialization): Handle concepts and constraints. Register partial specializations of variable templates. (redeclare_class_template): Handle constraints. (convert_template_argument): Handle WILDCARD_DECL. Check is_compatible_template_arg. (coerce_template_parameter_pack): Handle wildcard packs. (coerce_template_parms): DR 1430 also applies to concepts. Add overloads taking fewer parameters. (lookup_template_class_1): Handle constraints. (lookup_template_variable): Concepts are always bool. (finish_template_variable): Handle concepts and constraints. (tsubst_friend_class): Handle constraints. (gen_elem_of_pack_expansion_instantiation): Handle constraints. (tsubst_pack_expansion): Handle local parameters. (tsubst_decl) [FUNCTION_DECL]: Handle constraints. (tsubst) [TEMPLATE_TYPE_PARM]: Handle deduction constraints. (tsubst_copy_and_build): Handle REQUIRES_EXPR. (more_specialized_fn, more_specialized_partial_spec): Check constraints. (more_specialized_inst): Split out from most_specialized_instantiation. (most_specialized_partial_spec): Check constraints. (instantiate_decl): Never instantiate a concept. (value_dependent_expression_p): Handle REQUIRES_EXPR, TYPE_REQ, variable concepts. (type_dependent_expression_p): Handle WILDCARD_DECL, REQUIRES_EXPR. (instantiation_dependent_r): Handle REQUIRES_EXPR and concepts. (do_auto_deduction): Add overload taking tsubst flags and context enum. Handle constraints. (get_template_for_ordering, most_constrained_function) (is_compatible_template_arg, convert_wildcard_argument) (struct constr_entry, struct constr_hasher, decl_constraints) (valid_constraints_p, get_constraints, set_constraints) (remove_constraints, init_constraint_processing): New. * ptree.c (cxx_print_xnode): Handle CONSTRAINT_INFO. * search.c (lookup_member): Do lookup in the open partial instantiation. * semantics.c (finish_template_template_parm): Handle constraints. (fixup_template_type): New. (finish_template_type): Call it. (trait_expr_value, finish_trait_expr): Handle CPTK_IS_SAME_AS. * tree.c (cp_tree_equal): Handle local parameters, CONSTRAINT_INFO. (cp_walk_subtrees): Handle REQUIRES_EXPR. * typeck.c (cp_build_function_call_vec): Check constraints. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@226713 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c90
1 files changed, 89 insertions, 1 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 17b0a1457b4..7bbae06f717 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2710,10 +2710,18 @@ finish_template_template_parm (tree aggr, tree identifier)
{
tree decl = build_decl (input_location,
TYPE_DECL, identifier, NULL_TREE);
+
tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE);
DECL_TEMPLATE_PARMS (tmpl) = current_template_parms;
DECL_TEMPLATE_RESULT (tmpl) = decl;
DECL_ARTIFICIAL (decl) = 1;
+
+ // Associate the constraints with the underlying declaration,
+ // not the template.
+ tree reqs = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
+ tree constr = build_constraints (reqs, NULL_TREE);
+ set_constraints (decl, constr);
+
end_template_decl ();
gcc_assert (DECL_TEMPLATE_PARMS (tmpl));
@@ -2977,6 +2985,72 @@ finish_template_decl (tree parms)
end_specialization ();
}
+// Returns the template type of the class scope being entered. If we're
+// entering a constrained class scope. TYPE is the class template
+// scope being entered and we may need to match the intended type with
+// a constrained specialization. For example:
+//
+// template<Object T>
+// struct S { void f(); }; #1
+//
+// template<Object T>
+// void S<T>::f() { } #2
+//
+// We check, in #2, that S<T> refers precisely to the type declared by
+// #1 (i.e., that the constraints match). Note that the following should
+// be an error since there is no specialization of S<T> that is
+// unconstrained, but this is not diagnosed here.
+//
+// template<typename T>
+// void S<T>::f() { }
+//
+// We cannot diagnose this problem here since this function also matches
+// qualified template names that are not part of a definition. For example:
+//
+// template<Integral T, Floating_point U>
+// typename pair<T, U>::first_type void f(T, U);
+//
+// Here, it is unlikely that there is a partial specialization of
+// pair constrained for for Integral and Floating_point arguments.
+//
+// The general rule is: if a constrained specialization with matching
+// constraints is found return that type. Also note that if TYPE is not a
+// class-type (e.g. a typename type), then no fixup is needed.
+
+static tree
+fixup_template_type (tree type)
+{
+ // Find the template parameter list at the a depth appropriate to
+ // the scope we're trying to enter.
+ tree parms = current_template_parms;
+ int depth = template_class_depth (type);
+ for (int n = processing_template_decl; n > depth && parms; --n)
+ parms = TREE_CHAIN (parms);
+ if (!parms)
+ return type;
+ tree cur_reqs = TEMPLATE_PARMS_CONSTRAINTS (parms);
+ tree cur_constr = build_constraints (cur_reqs, NULL_TREE);
+
+ // Search for a specialization whose type and constraints match.
+ tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
+ tree specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
+ while (specs)
+ {
+ tree spec_constr = get_constraints (TREE_VALUE (specs));
+
+ // If the type and constraints match a specialization, then we
+ // are entering that type.
+ if (same_type_p (type, TREE_TYPE (specs))
+ && equivalent_constraints (cur_constr, spec_constr))
+ return TREE_TYPE (specs);
+ specs = TREE_CHAIN (specs);
+ }
+
+ // If no specialization matches, then must return the type
+ // previously found.
+ return type;
+}
+
/* Finish processing a template-id (which names a type) of the form
NAME < ARGS >. Return the TYPE_DECL for the type named by the
template-id. If ENTERING_SCOPE is nonzero we are about to enter
@@ -2990,6 +3064,16 @@ finish_template_type (tree name, tree args, int entering_scope)
type = lookup_template_class (name, args,
NULL_TREE, NULL_TREE, entering_scope,
tf_warning_or_error | tf_user);
+
+ /* If we might be entering the scope of a partial specialization,
+ find the one with the right constraints. */
+ if (flag_concepts
+ && entering_scope
+ && CLASS_TYPE_P (type)
+ && dependent_type_p (type)
+ && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)))
+ type = fixup_template_type (type);
+
if (type == error_mark_node)
return type;
else if (CLASS_TYPE_P (type) && !alias_type_or_template_p (type))
@@ -7442,6 +7526,9 @@ trait_expr_value (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_POLYMORPHIC:
return (CLASS_TYPE_P (type1) && TYPE_POLYMORPHIC_P (type1));
+ case CPTK_IS_SAME_AS:
+ return same_type_p (type1, type2);
+
case CPTK_IS_STD_LAYOUT:
return (std_layout_type_p (type1));
@@ -7549,8 +7636,9 @@ finish_trait_expr (cp_trait_kind kind, tree type1, tree type2)
case CPTK_IS_CLASS:
case CPTK_IS_ENUM:
case CPTK_IS_UNION:
+ case CPTK_IS_SAME_AS:
break;
-
+
default:
gcc_unreachable ();
}