[SKETCH] Refactor implicit function template implementation and fix 58534, 58536, 58548, 58549 and 58637.

Adam Butcher adam@jessamine.co.uk
Wed Oct 16 05:35:00 GMT 2013


On 2013-10-15 22:21, Adam Butcher wrote:
> On Wed, 25 Sep 2013 11:01:26 -0500, Jason Merrill wrote:
> >
> > 2) If we see 'auto', scan ahead (possibly via tentative parsing) to 
> see if there's a ...
> >
> My current preferred option.  The problem with it is that, ideally, I
> only want to look ahead for '...' in the parm decl if an 'auto' is
> seen. But I'm not sure how to do this in the case where the first
> 'auto' is nested in a template parameter (or other complex type).
> E.g.
>
>    auto f(pair<pair<auto, auto>, auto>... v)
>                     ^
> From the 'auto' I'd need to unwind to the fn parm scope and then try
> to tentatively parse the ellipsis.  To unwind and look ahead for 
> '...'
> needs the full parser mechanics but without any side-effects.  I 
> don't
> think I can do it with the lexer alone as I think there may be
> ambiguity with scanning <, <<, >, >> tokens.
>
> Look-ahead seems like the right way to go (unless there's a way to
> defer type hashing) but I'm not sure how to achieve it.
>
I've got a [potential] [partial] solution to this.  It doesn't handle
edge cases but I believe it will handle the majority of cases.

By maintaining a nesting counter of calls to
cp_parser_enclosed_template_argument_list we can determine, for a
particular parm, what level of template-id were are parsing when we see
an 'auto'.  A tentative skip parse handling < << ( [ ] ) >> > can be
done until reaching an ellipsis or, if <> nesting count drops to zero,
a closing paren or comma terminating the parm.  Mismatches would also
be considered as terminating the parm.

In the ellipsis case we assume some sort of pack.  If the <> nesting
count is zero when an ellipsis is found, we assume a function parameter
pack and flag that all 'auto's in the parm should be type packs and
don't need to do the look-ahead again for this parm.  If the <> nesting
count is non-zero when an ellipsis is found, then only the 'auto's
within that level of template argument list are considered type packs
and look-ahead will be done for 'auto' found in subsequent template
argument lists within the parm.

The latter case implements the implicit type pack extension supporting,
for example, the following:

    f(tuple<auto,tuple<auto...>,tuple<auto...>> t)

This doesn't handle cases where < << >> > are used as operators within
the parm but I think that's an edge case and it would only affect
whether the 'auto' was considered an implicit type pack or not.

I haven't gone all the way with this theory yet, but it could be a
plausible solution.

Let me know what you think.

Cheers,
Adam



More information about the Gcc-patches mailing list