Re: [PATCH] PRs c++/51239, c++/51180 - Better support for unbound alias template specialization

2011-12-06 Thread Jason Merrill

On 12/05/2011 07:15 PM, Gabriel Dos Reis wrote:

you need to spend more time in Paris :-)


Clearly! :)

Jason



Re: [PATCH] PRs c++/51239, c++/51180 - Better support for unbound alias template specialization

2011-12-05 Thread Jason Merrill
Hmm.  I know I'm the one that suggested this approach, but I think I'm 
uncomfortable with this minimal change, since code for handling 
BOUND_TEMPLATE_TEMPLATE_PARM expects to be able to get a 
TEMPLATE_TYPE_PARM_INDEX out of it, and that won't work for the alias 
template use.


So I'd like to rename BOUND_TEMPLATE_TEMPLATE_PARM to something more 
generic, perhaps TEMPLATE_ID_TYPE, that just takes a template and args. 
 So existing uses of BOUND_TEMPLATE_TEMPLATE_PARM would be replaced 
with a TEMPLATE_ID_TYPE around a TEMPLATE_TEMPLATE_PARM.


At that point it probably makes sense to replace the use of 
TEMPLATE_ID_EXPR in TYPENAME_TYPE with TEMPLATE_ID_TYPE.


Does this make sense?  Sorry to make more work for you.

Also, rather than pass back unknown_nb_args_p from 
coerce_template_parms, let's make it a predicate next to 
any_dependent_template_arguments_p and then use it in both places.  And 
change the name; it took me a little while to realize that nb is short 
for number.


Thanks,
Jason



Re: [PATCH] PRs c++/51239, c++/51180 - Better support for unbound alias template specialization

2011-12-05 Thread Dodji Seketeli
Jason Merrill ja...@redhat.com writes:

 Hmm.  I know I'm the one that suggested this approach, but I think I'm
 uncomfortable with this minimal change, since code for handling
 BOUND_TEMPLATE_TEMPLATE_PARM expects to be able to get a
 TEMPLATE_TYPE_PARM_INDEX out of it, and that won't work for the alias
 template use.

Yes.  Though I thought I'd spot those places if need be (as I was hoping
the code to ICE for these cases) and let them try to access the
TEMPLATE_TYPE_PARM_INDEX only for non-alias template use cases.  Not
elegant, granted.

 So I'd like to rename BOUND_TEMPLATE_TEMPLATE_PARM to something more
 generic, perhaps TEMPLATE_ID_TYPE, that just takes a template and
 args. So existing uses of BOUND_TEMPLATE_TEMPLATE_PARM would be
 replaced with a TEMPLATE_ID_TYPE around a TEMPLATE_TEMPLATE_PARM.

 At that point it probably makes sense to replace the use of
 TEMPLATE_ID_EXPR in TYPENAME_TYPE with TEMPLATE_ID_TYPE.

 Does this make sense?

Yes it does.

  Sorry to make more work for you.

No problem.  I wasn't sure I'd be able to sell the amount of change
incurred by this kind of generic approach in the first place.  It's
great that I don't have to.  ;-)

 Also, rather than pass back unknown_nb_args_p from
 coerce_template_parms, let's make it a predicate next to
 any_dependent_template_arguments_p and then use it in both places.
 And change the name; it took me a little while to realize that nb is
 short for number.

Okay.  I'll look into this.

Thanks.

-- 
Dodji


Re: [PATCH] PRs c++/51239, c++/51180 - Better support for unbound alias template specialization

2011-12-05 Thread Gabriel Dos Reis
On Mon, Dec 5, 2011 at 9:01 AM, Jason Merrill ja...@redhat.com wrote:
 it took me a little while to realize that nb is short for number.

you need to spend more time in Paris :-)

-- Gaby


[PATCH] PRs c++/51239, c++/51180 - Better support for unbound alias template specialization

2011-12-02 Thread Dodji Seketeli
Hello,

I have conflated the handling of two PRs here, because I think they
are related.

Consider this short example that illustrates the issue of PR
c++/51239:

struct S {};

templatetypename T, typename...
using head = T;

templatetypename... Ts
using x = headTs...;//#1

In #1, we want to be able to represent 'headTs...', in such a way
that the Ts... argument is not substituted for the parameter of f the
head template.  Because the pack expansion Ts... means that we don't
yet have the proper arguments to apply to the head template.  Later
when we have those arguments, for instance:

xint, char i0;

we can proceed with substituting the argument pack [int, char] into
the pack expansion Ts... to get a set of argument {int, char} that
we'll apply to the head template, to get int.

To date we don't have such an unbound alias template specialization
representation, because we leverage on the fact that head is an
alias template to substitute its arguments into its underlying type
directly.  Doing that in the present case (the argument being a pack
expansion) just wreaks havoc as the PR can attest.

After talking with you offline, we settled on using the existing
BOUND_TEMPLATE_TEMPLATE_PARM tree to represent this new construct.
The alias template and its unbound arguments are stored in the
TYPE_TEMPLATE_INFO of the tree and its TYPE_NAME has the
TYPE_DECL_ALIAS_P flag set.

So now, during the process of building a template specialization,
coerce_template_parms detects that we don't have all the arguments yet
- that is, when one of the arguments is a pack expansion.  In that
case lookup_template_class_1, if the template is an alias template,
builds an unbound alias template specialization and returns it.

We also support substituting for an unbound alias template
specialization.

The problem in PR c++/51180 is that sometimes coerce_template_parms
won't let us build a type fooT... if the template foo has more
than one parameter and no parameter pack.  We then end up in the if
below, and error out:

  if ((nargs  nparms  !variadic_p)
  || (nargs  nparms - variadic_p 
   require_all_args
   (!use_default_args
  || (TREE_VEC_ELT (parms, nargs) != error_mark_node
   !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))
{

So the patch below tries to fix that as well.

Incidentally, I noticed that the test g++.dg/cpp0x/alias-decl-15.C
should actually be considered valid.  I wrongly thought otherwise at
that time.  I have thus adjusted that test case accordingly.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

PR c++/51239
PR c++/51180
* cp-tree.h (UNBOUND_ALIAS_TEMPLATE_P): New
predicate.
* pt.c (build_unbound_alias_template): New.
(coerce_template_parms): Take a new out parameter flag about if
the actual number of arguments is unknown.  Make the template
unbound if one of its arguments is a pack expansion.
(lookup_template_class_1): Adjust for new argument to
coerce_template_parms.  Build an unbound alias template if the
number of arguments is not known yet.
(tsubst)BOUND_TEMPLATE_TEMPLATE_PARM: Handle unbound alias
templates.
(fn_type_unification, get_bindings, most_specialized_class):
Adjust for new argument to coerce_template_parms.

gcc/testsuite/

PR c++/51239
PR c++/51180
* g++.dg/cpp0x/alias-decl-18.C: New test.
* g++.dg/cpp0x/alias-decl-19.C: Likewise.
* g++.dg/cpp0x/alias-decl-15.C: This was wrongly expected
to fail before.  Adjust accordingly.
---
 gcc/cp/cp-tree.h   |   10 +++
 gcc/cp/pt.c|  108 +---
 gcc/testsuite/g++.dg/cpp0x/alias-decl-15.C |   10 ++--
 gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C |   29 
 gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C |   19 +
 5 files changed, 161 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-18.C
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-19.C

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 3f4f408..0dcebd6 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -3662,6 +3662,16 @@ more_aggr_init_expr_args_p (const 
aggr_init_expr_arg_iterator *iter)
   (DECL_TYPE_TEMPLATE_P (NODE) \
 !DECL_ARTIFICIAL (DECL_TEMPLATE_RESULT (NODE)))
 
+/* Nonzero for a node representing an alias template specialization in
+   which the arguments are not yet applied to the alias template.
+   This is used in cases where the arguments are not all fully known
+   yet, and can be applied later when they are.  */
+#define UNBOUND_ALIAS_TEMPLATE_P(NODE) \
+  ((NODE)  \
+TREE_CODE (NODE) == BOUND_TEMPLATE_TEMPLATE_PARM \
+DECL_ALIAS_TEMPLATE_P 

Re: [PATCH] PRs c++/51239, c++/51180 - Better support for unbound alias template specialization

2011-12-02 Thread Gabriel Dos Reis
On Fri, Dec 2, 2011 at 9:51 AM, Dodji Seketeli do...@redhat.com wrote:

 After talking with you offline, we settled on using the existing
 BOUND_TEMPLATE_TEMPLATE_PARM tree to represent this new construct.
 The alias template and its unbound arguments are stored in the
 TYPE_TEMPLATE_INFO of the tree and its TYPE_NAME has the
 TYPE_DECL_ALIAS_P flag set.

This representation sounds much more regular to me, considering
the existing patterns of representing templates.  The alias part in
template alias just means that we can substitute right away when
the alias is applied.  Otherwise, it is a template (like any other) in
all other aspects (except it can't be deduced.)

-- Gaby