On 2014-02-20 16:18, Jason Merrill wrote:
On 02/19/2014 10:00 PM, Adam Butcher wrote:
+ if (current_template_parms)
+ {
+ cp_binding_level *maybe_tmpl_scope =
current_binding_level->level_chain;
+ while (maybe_tmpl_scope && maybe_tmpl_scope->kind ==
sk_class)
+ maybe_tmpl_scope = maybe_tmpl_scope->level_chain;
+ if (maybe_tmpl_scope && maybe_tmpl_scope->kind ==
sk_template_parms)
+ declaring_template_p = true;
+ }
Won't this return true for a member function of a class template?
i.e.
template <class T>
struct A {
void f(auto x);
};
Yes I think you're right. I was thinking about that yesterday but
hadn't had a chance to get to my PC to check or post a reply. The
intent is to deal with out-of-line implicit member templates. But I
think the issue is more complex; and I think it may be true for the
synthesize code as well as this new code.
A class template with an out-of-line generic function definition will
give the same issue I think:
template <typename T>
void A<T>::f(auto x) {} // should inject a new list
It needs to know when to extend a function template parameter list and
when to insert a new one. Another case:
struct B
{
template <int N>
void f(auto x);
};
template <int N>
void B::f(auto x) {} // should extend existing inner list
And also:
template <typename T>
struct C
{
template <int N>
void f(auto x);
};
template <typename T>
template <int N>
void C<T>::f(auto x) {} // should extend existing inner list
Obviously there is an arbitrary depth of class and class templates.
Need to look further into it when I get some more time.
Once it's resolved I think it'd be useful to create a new function to
determine this rather than doing the scope walk in a number of places.
Something like 'templ_parm_scope_for_fn_being_declared' --- or hopefully
some more elegant name!
Why doesn't num_template_parameter_lists work as a predicate here?
It works in the lambda case as it is updated there, but for generic
functions I think the following prevents it:
cp/parser.c:17063:
/* Inside the function parameter list, surrounding
template-parameter-lists do not apply. */
saved_num_template_parameter_lists
= parser->num_template_parameter_lists;
parser->num_template_parameter_lists = 0;
begin_scope (sk_function_parms, NULL_TREE);
/* Parse the parameter-declaration-clause. */
params = cp_parser_parameter_declaration_clause (parser);
/* Restore saved template parameter lists accounting for
implicit
template parameters. */
parser->num_template_parameter_lists
+= saved_num_template_parameter_lists;
Cheers,
Adam