Re: [c++-concepts] explicit instantiation and specialization

2014-08-15 Thread Andrew Sutton
Just committed this patch, fixing the bootstrap.

2014-08-13  Andrew Sutton  

Fix regression in bootstrap.
  * gcc/cp/call.c (get_temploid): Removed. No longer called.
  (joust): Remove unused variable declarations.

Andrew


On Wed, Aug 13, 2014 at 9:50 PM, Andrew Sutton
 wrote:
> Ah... sorry. Leftovers. I didn't have time to run a full bootstrap
> build before heading out for a few days. I'll try to get those out
> tomorrow afternoon-ish.
>
> Andrew
>
>
> On Wed, Aug 13, 2014 at 9:13 PM, Ed Smith-Rowland <3dw...@verizon.net> wrote:
>> I get build fail:
>>
>> ../../gcc_concepts/gcc/cp/call.c:8793:8: error: unused variable ‘m1’
>> [-Werror=unused-variable]
>>tree m1 = get_temploid (cand1);
>> ^
>> ../../gcc_concepts/gcc/cp/call.c:8794:8: error: unused variable ‘m2’
>> [-Werror=unused-variable]
>>tree m2 = get_temploid (cand2);
>> ^
>> cc1plus: all warnings being treated as errors
>>
>> Commenting the lines let the build finish.
>>
>> Ed
>>
Index: gcc/cp/call.c
===
--- gcc/cp/call.c	(revision 213924)
+++ gcc/cp/call.c	(working copy)
@@ -8755,24 +8755,6 @@ add_warning (struct z_candidate *winner,
   winner->warnings = cw;
 }
 
-// When a CANDidate function is a member function of a class template
-// specialization, return the temploid describing that function.
-// Returns NULL_TREE otherwise.
-static inline tree
-get_temploid (struct z_candidate *cand)
-{
-  gcc_assert (cand);
-  tree t = NULL_TREE;
-  if (!cand->template_decl)
-{
-  if (DECL_P (cand->fn) && DECL_USE_TEMPLATE (cand->fn))
-t = DECL_TI_TEMPLATE (cand->fn);
-  if (t && TREE_CODE (t) == TEMPLATE_INFO)
-t = TI_TEMPLATE (t);
-}
-return t;
-}
-
 /* Compare two candidates for overloading as described in
[over.match.best].  Return values:
 
@@ -8789,10 +8771,6 @@ joust (struct z_candidate *cand1, struct
   size_t i;
   size_t len;
 
-  // Try to get a temploid describing each candidate. 
-  tree m1 = get_temploid (cand1);
-  tree m2 = get_temploid (cand2);
-
   /* Candidates that involve bad conversions are always worse than those
  that don't.  */
   if (cand1->viable > cand2->viable)


Re: [c++-concepts] explicit instantiation and specialization

2014-08-13 Thread Andrew Sutton
Ah... sorry. Leftovers. I didn't have time to run a full bootstrap
build before heading out for a few days. I'll try to get those out
tomorrow afternoon-ish.

Andrew


On Wed, Aug 13, 2014 at 9:13 PM, Ed Smith-Rowland <3dw...@verizon.net> wrote:
> I get build fail:
>
> ../../gcc_concepts/gcc/cp/call.c:8793:8: error: unused variable ‘m1’
> [-Werror=unused-variable]
>tree m1 = get_temploid (cand1);
> ^
> ../../gcc_concepts/gcc/cp/call.c:8794:8: error: unused variable ‘m2’
> [-Werror=unused-variable]
>tree m2 = get_temploid (cand2);
> ^
> cc1plus: all warnings being treated as errors
>
> Commenting the lines let the build finish.
>
> Ed
>


Re: [c++-concepts] explicit instantiation and specialization

2014-08-13 Thread Ed Smith-Rowland

I get build fail:

../../gcc_concepts/gcc/cp/call.c:8793:8: error: unused variable ‘m1’ 
[-Werror=unused-variable]

   tree m1 = get_temploid (cand1);
^
../../gcc_concepts/gcc/cp/call.c:8794:8: error: unused variable ‘m2’ 
[-Werror=unused-variable]

   tree m2 = get_temploid (cand2);
^
cc1plus: all warnings being treated as errors

Commenting the lines let the build finish.

Ed



[c++-concepts] explicit instantiation and specialization

2014-08-13 Thread Andrew Sutton
This patch re-implements explicit instantiation and specialization.
The latter isn't fully tested just yet, but it's close.

Constraints for explicit instantiations and specializations are
deduced from their candidates, not explicitly specified as part of the
declaration.

2014-08-13  Andrew Sutton  

Implement deduction-based explicit instantiation and specialization.
* gcc/cp/call.c (joust): Allow all non-templates to be ordered by
constraints.
* gcc/cp/pt.c (get_class_bindings): Remove superfluous parameter and
move constraint check into most_specialized_class.
(most_constrained_function): Order functions with the same signatures
by their constraints.
(determine_specialization): Candidates must satisfy constraints. Also,
order non-template candidates by constraints. Improve diagnostics
for instances where candidates are rejected.
(more_specialized_inst): New. Compare function templates.
(most_specialized_instantiation): Refactor to use
more_specialized_inst and order by constraints.
(most_specialized_class): Candidates must satisfy constraints.
* gcc/cp/decl.c (various) Cosmetic fixes.
(adjust_fn_constraints): Rewrite so that class template constraints
are not imposed on member function declarations.
* gcc/testsuite/g++.dg/concepts: New tests.

Andrew Sutton
Index: gcc/cp/decl.c
===
--- gcc/cp/decl.c	(revision 213909)
+++ gcc/cp/decl.c	(working copy)
@@ -991,11 +991,6 @@ decls_match (tree newdecl, tree olddecl)
   if (t1 != t2)
 	return 0;
 
-  // Normal functions can be constraind. Two functions with the
-  // same type and different constraints are different functions.
-  tree c1 = get_constraints (newdecl);
-  tree c2 = get_constraints (olddecl);
-
   if (CP_DECL_CONTEXT (newdecl) != CP_DECL_CONTEXT (olddecl)
 	  && ! (DECL_EXTERN_C_P (newdecl)
 		&& DECL_EXTERN_C_P (olddecl)))
@@ -1014,6 +1009,11 @@ decls_match (tree newdecl, tree olddecl)
 	 type for declaration matching.  */
   r2 = fndecl_declared_return_type (olddecl);
 
+  // Normal functions can be constraind. Two functions with the
+  // same type and different constraints are different functions.
+  tree c1 = get_constraints (newdecl);
+  tree c2 = get_constraints (olddecl);
+
   if (same_type_p (TREE_TYPE (f1), r2))
 	{
 	  if (!prototype_p (f2) && DECL_EXTERN_C_P (olddecl)
@@ -1041,7 +1041,7 @@ decls_match (tree newdecl, tree olddecl)
 	  TREE_TYPE (newdecl) = TREE_TYPE (olddecl);
 	}
 #endif
-	  else {
+	  else
 	types_match =
 	  compparms (p1, p2)
 	  && type_memfn_rqual (f1) == type_memfn_rqual (f2)
@@ -1049,7 +1049,6 @@ decls_match (tree newdecl, tree olddecl)
 	  && (TYPE_ATTRIBUTES (TREE_TYPE (newdecl)) == NULL_TREE
 	  || comp_type_attributes (TREE_TYPE (newdecl),
 	   TREE_TYPE (olddecl)) != 0);
-  }
 	}
   else
 	types_match = 0;
@@ -7564,24 +7563,54 @@ get_leading_constraints ()
 // parameter list. The adjustment makes them part of the current
 // template requirements.
 static void
-adjust_out_of_class_fn_requirements (tree ctype)
+adjust_fn_constraints (tree ctype)
 {
+  // When grokking a member function template, we are processing
+  // template decl at a depth greater than that of the member's
+  // enclosing class. That is, this case corresponds to the
+  // following declarations:
+  //
+  //template
+  //struct S {
+  //  template void f(U);
+  //};
+  //
+  //template template  void S::f(U) { }
+  //
+  // In both decls, the constraint D is not the current leading
+  // constraint. Make it so.
+  //
+  // Note that for normal member functions, there are no leading
+  // requirements we need to gather.
   if (ctype && processing_template_decl > template_class_depth (ctype))
 {
   if (tree ci = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms))
 {
+  // TODO: When do I ever have leading requirements for a
+  // member function template?
   tree reqs = CI_LEADING_REQS (ci);
   if (reqs && !get_leading_constraints ())
 current_template_reqs = save_leading_constraints (reqs);
 }
 }
-  else if (current_template_parms)
+
+  // Otherwise, this is just a regular function template. Like so:
+  //
+  //template void f();
+  //
+  // Note that the constraint C is not the current leading requirement
+  // at this point; it was stashed before the declarator was parsed.
+  // Make it the leading constraint.
+  else if (!ctype && current_template_parms)
   {
 if (tree ci = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms))
   {
 tree r1 = CI_LEADING_REQS (ci);
 if (current_template_reqs)
   {
+// TODO: As with above, when do I ever have leading
+// requirements that aren't part of the