The documentation for Parser::ParseFunctionDeclarator (hereafter referred to as PFD) has this note near the end:

   For C++, after the parameter-list, it also parses "cv-qualifier-
   seq[opt]", C++0x "ref-qualifier[opt]" and "exception-

I would like to use this function when parsing lambda expressions, but the extra parts it parses at the end are simultaneously too much (cv-qualifier-seq, ref-qualifier) and not enough (attribute-specifier, 'mutable') for lambdas.

I could try to call PFD anyway, then check if it parsed anything extra that it shouldn't have. I believe this is existing convention, e.g., to diagnose const-qualified non-member functions.

However, PFD calls Declarator::AddTypeInfo, which takes a DeclaratorChunk that, for function declarators, requires information about the parameters, qualifiers, exceptions, and return type all at once. Here is the documentation for DeclaratorChunk:

   One instance of this struct is used for each type in a declarator
   that is parsed.

This suggests to me that I cannot, after calling PFD, call AddTypeInfo to add the lambda-declarator parts that PFD missed. Thus, I see two options to address the situation:

1. Try to extend PFD to parse a lambda-declarator. Existing clients will need to add checks for the parts that don't belong in regular function declarators.

2. Factor code out of PFD into several component functions. Old clients can still use PFD, and I can use just the pieces I need. This is the option I personally favor.

Any thoughts?

- John

You have several options. Making ParseFunctionDeclarator parse lambdas and have every existing client check for unexpected pieces is probably the worst.
Splitting ParseFunctionDeclarator into component parts so that you can reuse them is a pretty good option.
Another option is to simply pass a boolean to ParseFunctionDeclarator that tells it to continue lambda-style after the parameters instead of function-style. Default it to false and you might not even have to change the code for all other uses, but in any case the compiler will tell you if you do it wrong. We do stuff like this a lot.
Of course, a boolean gives two complicated branches. Yet another option would be to pass the "after-parameters" action as a function pointer. Basically, you factor the existing cv-qualifier etc. parsing stuff as well as the AddTypeInfo call into a function and make every existing call site pass that, while your lambda parser stuff passes a different function that parses mutable and attributes and calls the appropriate AddTypeInfo variant. ParseCXXNewExpresssion does something similar for ParseDeclarator.

The choice is yours.


Declarators already have a context, indicating where they were written, and we'll need a new setting for lambda declarators anyway. It's possible that that can be harnessed, i.e. if we're parsing a lambda declarator and this is the 'right-most' function chunk.