[PATCH] Fix PR c++/60065.

Adam Butcher adam@jessamine.co.uk
Fri Feb 21 08:19:00 GMT 2014


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



More information about the Gcc-patches mailing list