This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


On Wed, 25 Sep 2013 11:01:26 -0500, Jason Merrill wrote:
On 09/24/2013 02:05 AM, Adam Butcher wrote:
> On the subject of on-the-fly synthesis: I haven't started yet but I'm
> thinking to trigger in 'cp_parser_simple_type_specifier' when
> 'current_binding_level->kind == sk_function_parms'.
>
This is working out quite well. And I've cleaned up and optimized synthesize_implicit_template_parm to update current_template_parms directly. Implicitly packs are still a problem though.

> I can foresee a
> potential issue with packs in that, upon reading the 'auto' (potentially > nested in some other type), a plain template parm will be synthesized;
> but it may need to be a pack parm type if '...' is found later.

Hmm, good point.

I think there are two options:

1) Build up the type as normal and use tsubst to replace the non-pack template parameter with a pack if needed.

The problem I've hit with this (and other hacks I've tried that involve finishing the type first and rewriting afterward) is that, with parm types such as "pair<auto,auto>...", the specialization "pair<auto,auto>" is indexed in pt.c by hash_specialization into type_specializations before the '...' is seen. In an explicit template, the template type parms are already marked as packs so are hashed as such and are distinct from non-pack template type parms.

The issue occurs in cases such as:

  auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
  auto b = [] (auto, pair<auto,auto>... v) { return sizeof... (v); };

  a(1, pair<int, float>());
  b(2, pair<char, double>(), pair<float, int>());

If the declarations of a and b are reversed, it works as expected.

I cannot find a way to prevent picking up the non-pack "pair<auto,auto>" type on the way through parsing "pair<auto,auto>...". I've tried a few hacks to prevent hashing if an 'auto' is present in the current type but ended up with canonical type issues. I also tried rehashing after pack replacement but still hit the same issue. My conclusion is that the 'auto' needs to synthesize a pack type from the start for parameter packs. Which leads to:

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.

Any suggestions?

Cheers,
Adam


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]