This is the mail archive of the
mailing list for the GCC project.
Re: [SKETCH] Refactor implicit function template implementation and fix 58534, 58536, 58548, 58549 and 58637.
- From: Adam Butcher <adam at jessamine dot co dot uk>
- To: Jason Merrill <jason at redhat dot com>
- Cc: Gcc Patches <gcc-patches at gcc dot gnu dot org>, <daniel dot kruegler at googlemail dot com>, Volker Reichelt <reichelt at gcc dot gnu dot org>
- Date: Thu, 10 Oct 2013 21:45:57 +0100
- Subject: Re: [SKETCH] Refactor implicit function template implementation and fix 58534, 58536, 58548, 58549 and 58637.
- Authentication-results: sourceware.org; auth=none
- References: <08a6b60986417d8ab134b6aa85ecd80e at imap dot force9 dot net> <5254CF91 dot 500 at redhat dot com>
On 2013-10-09 4:37, Jason Merrill wrote:
Of course; makes sense. I had confused myself. Not that it's a
function parameter pack, but presumably you would expect
On 10/07/2013 05:14 AM, Adam Butcher wrote:
+ /* Forbid ambiguous implicit pack expansions by only allowing
+ a single generic type in such a parameter.
+ XXX: Maybe allow if explicitly specified template
+ XXX: 'typename...' account for all expansions? Though this
+ XXX: could be tricky or slow.
This seems wrong. The standard says,
The invented type template-parameter is a parameter pack if the
corresponding parameter-declaration de-
clares a function parameter pack (8.3.5).
So if we have a function parameter pack, any generic type parameters
in the type are packs.
auto f(tuple<auto...> p)
to be supported? This doesn't work with my existing impl since I only
generate a variadic type on the declaration of a function parameter
I think the following cases should also work
auto g1(std::tuple<std::shared_ptr<auto>, std::tuple<auto...>> p)
In both cases, the first generic type is a plain type and the second is
a type pack.
Making the parameter a function parameter pack should also work
auto h1(std::tuple<std::shared_ptr<auto>, std::tuple<auto...>>... v)
The first 'auto' is a pack expanded by 'v' and the second is expanded
within the second tuple (and required to be consistent among all 'v'
+ /* If there is only one generic type in the parameter,
+ assume that that it is a parameter pack. If it turns out,
+ grokdeclarator, that the parameter does not contain a pack
+ expansion, then reset it be a non-pack type. */
+ if (cp_num_implicit_template_type_parms == 1)
+ (cp_last_implicit_template_type_parm)) = true;
This will cause problems with type comparison, since TYPE_CANONICAL
of the implicit parm doesn't have TEMPLATE_PARM_PARAMETER_PACK set.
Indeed it does.
That's why I was talking about using tsubst to replace a non-pack
My original intent was to store the actual template parm scope but I
changed it to the containing scope to make the comparison in
cp_parser_parameter_declaration_list; It determines the completion point
of the implicit template scope. It is terminated once
current_binding_level returns to the initiating scope. I'll have
another look to reduce level_chain traversal.
+ parser->implicit_template_scope = class_scope;
+ parser->implicit_template_scope = fn_parms_scope;
+ current_binding_level =
Why not make implicit_template_scope the actual template scope,
rather than the function/class? It looks like all the users
immediately take the level_chain.
Done. But it still needs a flag to disable in the case of explicit
template specialization. At the moment I've replaced the
explicit_specialization_p parm of cp_parser_single_declaration with a
global cp_parsing_explicit_function_specialization but not sure if
that's the best solution.
+/* Nonzero if parsing a context where 'auto' in a parameter list
+ trigger an implicit template parameter. Specifically, 'auto'
+ introduce a new template type parameter in explicit
+ return types or exception specifiers. */
Can we put this in cp_parser, invert the sense of the flag, and only
set it during cp_parser_parameter_declaration_clause?
I'll post an update once I get some time to rework the pack stuff.