Re: [c++-concepts] Class template constraints

2013-09-09 Thread Gabriel Dos Reis
Andrew Sutton  writes:

| Ok to commit? Attached is the doc fix patch. I'll send the TREE_TYPE
| patch shortly.

Yes, please -- that is what Jason earlier.  Let me know when youve
committed so that I can synchronize with trunk.

-- Gaby


Re: [c++-concepts] Class template constraints

2013-09-09 Thread Andrew Sutton
Ok to commit? Attached is the doc fix patch. I'll send the TREE_TYPE
patch shortly.

Andrew
Andrew Sutton


On Sat, Sep 7, 2013 at 1:00 PM, Jason Merrill  wrote:
> On 09/06/2013 12:03 PM, Andrew Sutton wrote:
>>
>> +// Returns the template type of the class scope being entered. If we're
>> +// entering a constrained class scope. TMPL is the most general template
>> +// of the scope being entered, and TYPE is its type.
>
>
> TMPL is not part of the interface of fixup_template_type, so it should be
> documented when it is declared rather than before the function.
>
> OK with that tweak.
>
>> +  tree cur_constr = TREE_TYPE (parms);
>
>
> In a separate patch, I'd like to use a different macro name for getting
> constraints from template parms.
>
> Jason
>


templates-2.patch
Description: Binary data


Re: [c++-concepts] Class template constraints

2013-09-07 Thread Jason Merrill

On 09/06/2013 12:03 PM, Andrew Sutton wrote:

+// Returns the template type of the class scope being entered. If we're
+// entering a constrained class scope. TMPL is the most general template
+// of the scope being entered, and TYPE is its type.


TMPL is not part of the interface of fixup_template_type, so it should 
be documented when it is declared rather than before the function.


OK with that tweak.


+  tree cur_constr = TREE_TYPE (parms);


In a separate patch, I'd like to use a different macro name for getting 
constraints from template parms.


Jason



Re: [c++-concepts] Class template constraints

2013-09-06 Thread Andrew Sutton
Updated as per comments.

I moved the resolve_template_scope function out to
finish_template_type. I couldn't figure out how to get the parsed
template parameter from the looked-up template in
lookup_class_template. That information may not be available outside
the parse state.

Andrew
Andrew Sutton


On Wed, Sep 4, 2013 at 3:49 PM, Jason Merrill  wrote:
> On 09/04/2013 01:33 PM, Andrew Sutton wrote:
>>
>> Ah. The goal is to check after we've deduced/coerced template
>> arguments into a valid substitution. With functions, that's in
>> fn_type_unification (hopefully called from instantiate_template)
>
>
> Actually fn_type_unification calls instantiate_template, but yep, we're on
> the same page.
>
> Jason
>


templates.patch
Description: Binary data


Re: [c++-concepts] Class template constraints

2013-09-04 Thread Jason Merrill

On 09/04/2013 01:33 PM, Andrew Sutton wrote:

Ah. The goal is to check after we've deduced/coerced template
arguments into a valid substitution. With functions, that's in
fn_type_unification (hopefully called from instantiate_template)


Actually fn_type_unification calls instantiate_template, but yep, we're 
on the same page.


Jason



Re: [c++-concepts] Class template constraints

2013-09-04 Thread Andrew Sutton
>> It's not supposed to be different. Checking constraints in
>> instantiate_template is actually too late. We want to check before
>> instantiation, at the point of use.
>
> Right, what I was getting at is that instantiate_template actually only
> instantiates the declaration of a function, not the definition, so it
> corresponds to lookup_template_class for class templates.

Ah. The goal is to check after we've deduced/coerced template
arguments into a valid substitution. With functions, that's in
fn_type_unification (hopefully called from instantiate_template), and
for classes in lookup_template_class.

There are some other places too: get_class_bindings for partial
specializations, and determine_specialization for explicit
specializations.


> Oh, did the comment just mean that absence is equivalent to absence?  I
> thought the comment was saying that absence is considered equivalent to
> anything else.  Just tweak the comment, then.

Sounds good.

Andrew


Re: [c++-concepts] Class template constraints

2013-09-04 Thread Jason Merrill

On 09/04/2013 11:59 AM, Andrew Sutton wrote:

It's not supposed to be different. Checking constraints in
instantiate_template is actually too late. We want to check before
instantiation, at the point of use.


Right, what I was getting at is that instantiate_template actually only 
instantiates the declaration of a function, not the definition, so it 
corresponds to lookup_template_class for class templates.


instantiate_decl is what actually instantiates the body.  Confusing 
internal function naming.



I think that the absence of constraints fits into those definition
nicely, since it represents the empty set of propositions.


Oh, did the comment just mean that absence is equivalent to absence?  I 
thought the comment was saying that absence is considered equivalent to 
anything else.  Just tweak the comment, then.


Jason



Re: [c++-concepts] Class template constraints

2013-09-04 Thread Andrew Sutton
>> 1. Type constraints are checked on lookup rather than instantiation.
>
>
> How is this different from function template constraints?  Is this just a
> difference in internal function name (instantiate_template vs
> lookup_template_class)?

It's not supposed to be different. Checking constraints in
instantiate_template is actually too late. We want to check before
instantiation, at the point of use. This also means we don't need
complete types to check constraints. So this:

  template
struct X;

  X* x;

Should fail and does. This change also makes it impossible to have
partial specializations that are more general than the primary
template. Checking in lookup_class_template does not consult the
specializations.

Constraints on partial specializations are checked in
most_specialized_class (or one of its subroutines).

>
>> +// Returns the type of a template specialization only if that
>> +// specializaiton needs to defined. Otherwise (e.g., if the type has
>
>
> specialization
>
>> +  // Do the constraints match the most general template? Note that
>> +  // the absence of constraints will also match.
>> +  if (equivalent_constraints (cur_constr, DECL_CONSTRAINTS (tmpl)))
>
>
> If absence matches, I think the name "equivalent" is misleading.  But the
> implementation seems to require subsumes in both directions.  What's up
> here?

Subsumption is essentially computing an implication between
constraints, so that if P subsumes Q, you could also say that P => Q.
Checking in both directions gives P => Q and Q => P, or P <=> Q, which
is logical equivalence.

I think that the absence of constraints fits into those definition
nicely, since it represents the empty set of propositions.

>> +  // 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 you're going to use this function from lookup_template_class_1, it can't
> use current_template_*, since those are parser state which might be
> something completely unrelated when we get here during instantiation.

I was worried about that. I'm not sure how this gets invoked during
instantiation. I'll look at it.

-- 
Andrew Sutton
andrew.n.sut...@gmail.com


Re: [c++-concepts] Class template constraints

2013-09-04 Thread Jason Merrill

On 09/03/2013 11:01 AM, Andrew Sutton wrote:

Attached is a patch for constrained class templates. It's the 3rd time
I've sent it.


Please feel free to ping me if you're waiting for a patch review; once a 
week is not too much.



1. Type constraints are checked on lookup rather than instantiation.


How is this different from function template constraints?  Is this just 
a difference in internal function name (instantiate_template vs 
lookup_template_class)?



+// Returns the type of a template specialization only if that
+// specializaiton needs to defined. Otherwise (e.g., if the type has


specialization


+  // Do the constraints match the most general template? Note that
+  // the absence of constraints will also match.
+  if (equivalent_constraints (cur_constr, DECL_CONSTRAINTS (tmpl)))


If absence matches, I think the name "equivalent" is misleading.  But 
the implementation seems to require subsumes in both directions.  What's 
up here?



+  // 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 you're going to use this function from lookup_template_class_1, it 
can't use current_template_*, since those are parser state which might 
be something completely unrelated when we get here during instantiation.



+return resolve_template_scope(gen_tmpl, template_type);


Space before (.


+  // Diaagnose constraints here since they are not diagnosed


Extra 'a'.


+  // If not, it is equivalent to have failed to compute the binding.


"to having failed"

Jason



[c++-concepts] Class template constraints

2013-09-03 Thread Andrew Sutton
Attached is a patch for constrained class templates. It's the 3rd time
I've sent it.

I added some fixes for bugs discovered after the previous send, and
added support for matching constrained declarations in out-of-class
member function definitions.

2013-08-02  Andrew Sutton  
* gcc/cp/pt.c (get_class_bindings): Pass the partial specialization
for constraint evaluation. Evaluate constraints, resulting in
deduction failure on error.
(get_specializaing_template_decl), (get_specialization_constraints),
(maybe_new_partial_specialization): New.
(maybe_process_partial_specialization): Allow the creation of
new types for constrained partial specializations.
(process_partial_specialization): Modify the canonical type
of constrained partial specializations.
(resolve_template_scope): New. Match the template scope to a
specialization with appropriate constraints.
(lookup_template_class_1): Compare constraints when entering a
template scope. Check constraints on lookup. Do not explicitly check
alias constraints.
(instantiate_class_template_1): Do not explicitly check constraints
during class template instantiation.
(tsubst_decl): Instantiate the constraints of template declarations.
(more_specialized_class): Pass specializations to get_class_bindings().
Compare specialization constraints if the types are equivalent.
(most_specialized_class): Pass specialization to get_class_bndings().
* gcc/cp/decl2.c (check_class_fn): Get the decl's requirements from
either the current template reqs or from the template parameters.
Allow overloading of constrained out-of-class member definitions.
* gcc/cp/parser.c (cp_parser_parse_type_parameter): Attach
requirements to the current template parameter list.
(cp_parser_init_declarator): Parse requires clauses for out-of-class
member definitions. Be sure to restore current constraints before
exiting the function.
(cp_parser_member_declarator): Restore the previous requirements in
an early-exit branch.
(cp_parser_late_parsing_for_member): Restore constraints after
maybe_end_member_template_processing().
(cp_parser_template_declaration_after_exp): Attach constraints to
the current template parameters.
* gcc/cp/constraint.cc (reduce_template_id): Don't crash when
omitting ()'s on constraint calls.
(check_requirements): Don't evaluate dependent arguments.
(check_constraints): Don't try to evaluate when arguments are
dependent.
(equivalent_constraints): Optimize the case when a and b are the
same constraints.

-- 
Andrew Sutton


template.patch
Description: Binary data


[c++-concepts] class template constraints

2013-08-02 Thread Andrew Sutton
Attached is a patch that deals with class template constraints. In
particular, it does 3 things:

1. Type constraints are checked on lookup rather than instantiation.
2. Initial support for constrained out-of-class definitions is added
(more work needed)
3. Support for constrained partial template specialization is added.

Change Log:

2013-08-02  Andrew Sutton  
* gcc/cp/pt.c (get_class_bindings): Pass the partial specialization
for constraint evaluation. Evaluate constraints, resulting in
deduction failure on error.
(get_specializaing_template_decl), (get_specialization_constraints),
(maybe_new_partial_specialization): New.
(maybe_process_partial_specialization): Allow the creation of
new types for constrained partial specializations.
(process_partial_specialization): Modify the canonical type
of constrained partial specializations.
(lookup_template_class_1): Check constraints on lookup. Do not
explicitly check alias constraints.
(instantiate_class_template_1): Do not explicitly check constraints
during class template instantiation.
(more_specialized_class): Pass specializations to get_class_bindings().
Compare specialization constraints if the types are equivalent.
(most_specialized_class): Pass specialization to get_class_bndings().
* gcc/cp/constraint.cc (reduce_template_id): Don't crash when
omitting ()'s on constraint calls.
(check_constraints): Don't try to evaluate when arguments are
dependent.
(equivalent_constraints): Optimize the case when a and b are the
same constraints.
* gcc/cp/decl2.c (check_class_fn): Allow overloading of constrained
out-of-class member definitions.
* gcc/cp/parser.c (cp_parser_init_declarator): Parse requires
clauses for out-of-class member definitions. Be sure to restore
current constraints before exiting the function.
(cp_parser_late_parsing_for_member): Restore constraints after
maybe_end_member_template_processing().

Andrew


template-1.patch
Description: Binary data


[c++-concepts] class template constraints

2013-06-26 Thread Andrew Sutton
I changed the method by which class (and alias) template constraints
are checked. Rather than waiting until instantiation, they are now
checked after computing the binding in lookup_class template.
Actually, after the hashtable lookup so we don't re-check constraints
for previously instantiated specializations.

Previously, this was allowed:

  vector* p;

Assuming that vector restricted its arguments to only object types.
The program is ill-formed if vector is ever instantiated. This
patch causes formation of the type vector to result in an error.

Changelog:

2013-06-25  Andrew Sutton  
* gcc/cp/constraint.cc (check_constraints): Don't check against
dependent arguments. Just return true.
* gcc/cp/ptr.c (lookup_class_template_1): Check template constraints
and diagnose failures. Removing specific check for alias templates.
(instantiate_class_template_1): Remove constraints check during
template instantiation.

Andrew


class.patch
Description: Binary data