aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constraint.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-10-31 12:20:05 -0400
committerJason Merrill <jason@gcc.gnu.org>2015-10-31 12:20:05 -0400
commit4fea442db740d66cd8d16bdeb667d9725f305844 (patch)
tree58ced5bf7feb8ee0c6ac2b1c7d216ad00966909d /gcc/cp/constraint.cc
parenta459b07fa440fcb449e9b65cf0cc649905b6ba9e (diff)
downloadgcc-4fea442db740d66cd8d16bdeb667d9725f305844.zip
gcc-4fea442db740d66cd8d16bdeb667d9725f305844.tar.gz
gcc-4fea442db740d66cd8d16bdeb667d9725f305844.tar.bz2
Implement multiple 'auto' feature from Concepts TS.
* parser.c (cp_parser_type_id_1): Allow 'auto' if -fconcepts. (cp_parser_template_type_arg): Likewise. (get_concept_from_constraint): Split out most logic to... * constraint.cc (placeholder_extract_concept_and_args): ...here. (equivalent_placeholder_constraints, hash_placeholder_constraint): New. * cxx-pretty-print.c (pp_cxx_constrained_type_spec): New. * cxx-pretty-print.h: Declare it. * error.c (dump_type) [TEMPLATE_TYPE_PARM]: Call it. * pt.c (is_auto_r, extract_autos_r, extract_autos, auto_hash): New. (type_uses_auto): Use is_auto_r. (do_auto_deduction): Handle multiple 'auto's if -fconcepts. * typeck.c (structural_comptypes) [TEMPLATE_TYPE_PARM]: Compare constraints. From-SVN: r229629
Diffstat (limited to 'gcc/cp/constraint.cc')
-rw-r--r--gcc/cp/constraint.cc83
1 files changed, 83 insertions, 0 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index cb82535..a1fbf17 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1379,6 +1379,89 @@ make_constrained_auto (tree con, tree args)
return decl;
}
+/* Given the predicate constraint T from a placeholder type, extract its
+ TMPL and ARGS. */
+
+void
+placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args)
+{
+ gcc_assert (TREE_CODE (t) == PRED_CONSTR);
+ t = PRED_CONSTR_EXPR (t);
+ gcc_assert (TREE_CODE (t) == CALL_EXPR
+ || TREE_CODE (t) == TEMPLATE_ID_EXPR
+ || VAR_P (t));
+
+ if (TREE_CODE (t) == CALL_EXPR)
+ t = CALL_EXPR_FN (t);
+ if (TREE_CODE (t) == TEMPLATE_ID_EXPR)
+ {
+ tmpl = TREE_OPERAND (t, 0);
+ if (TREE_CODE (tmpl) == OVERLOAD)
+ {
+ gcc_assert (OVL_CHAIN (tmpl) == NULL_TREE);
+ tmpl = OVL_FUNCTION (tmpl);
+ }
+ args = TREE_OPERAND (t, 1);
+ }
+ else if (DECL_P (t))
+ {
+ tmpl = DECL_TI_TEMPLATE (t);
+ args = DECL_TI_ARGS (t);
+ }
+ else
+ gcc_unreachable ();
+}
+
+/* Returns true iff the placeholders C1 and C2 are equivalent. C1
+ and C2 can be either PRED_CONSTR_EXPR or TEMPLATE_TYPE_PARM. */
+
+bool
+equivalent_placeholder_constraints (tree c1, tree c2)
+{
+ if (TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
+ c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
+ if (TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
+ c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);
+
+ if (c1 == c2)
+ return true;
+ if (!c1 || !c2)
+ return false;
+
+ tree t1, t2, a1, a2;
+ placeholder_extract_concept_and_args (c1, t1, a1);
+ placeholder_extract_concept_and_args (c2, t2, a2);
+
+ if (t1 != t2)
+ return false;
+ int len = TREE_VEC_LENGTH (a1);
+ if (len != TREE_VEC_LENGTH (a2))
+ return false;
+ /* Skip the first argument to avoid infinite recursion on the
+ placeholder auto itself. */
+ for (int i = len-1; i > 0; --i)
+ if (!cp_tree_equal (TREE_VEC_ELT (a1, i),
+ TREE_VEC_ELT (a2, i)))
+ return false;
+ return true;
+}
+
+/* Return a hash value for the placeholder PRED_CONSTR C. */
+
+hashval_t
+hash_placeholder_constraint (tree c)
+{
+ tree t, a;
+ placeholder_extract_concept_and_args (c, t, a);
+
+ /* Like hash_tmpl_and_args, but skip the first argument. */
+ hashval_t val = iterative_hash_object (DECL_UID (t), 0);
+
+ for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
+ val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
+
+ return val;
+}
/*---------------------------------------------------------------------------
Constraint substitution