I have a few questions about the state of initialized lambda captures wrt
First off, is anybody actively working on these? If so, I'll just slink
No; I had started working on them but don't have time any more.
If not, I want to see if this sounds reasonable:
The way I think of these in my head is as-if they have an implicit
specifier of 'auto' as they haven't got a declarator specifier to parse.
My thoughts thus far:
- Invent a DeclSpec corresponding to the auto
- Make a Declarator with our new DeclSpec
- Give the Declarator our previously parsed identifier with SetIdentifier
- Using the lambda body's scope, use HandleDeclarator to introduce the
identifier to the scope
- Attach the init-capture's initializer using AddInitializerToDecl
While more than this must happen, I wanted to see if I was on-track here.
A fair amount of support for them is already present: we will already parse
them, build FieldDecls inside the lambda-expression for them, and attach
the initializer. The problems we have are:
* The init-captures are handled in ActOnStartOfLambdaDefinition, which is
too late, because they are supposed to be in scope in the
parameter-declaration-clause of the lambda. We should split out an
ActOnLambdaIntroducer and move the lambda-introducer handling there.
* The init-captures can't be referenced from within the lambda body
anyway. This is not just a shallow problem -- if we want to keep
representing init-captures as FieldDecls, we will need some new mechanism
for representing "the 'this' pointer of the lambda" (CXXThisExpr represents
the surrounding 'this' pointer), or use a DeclRefExpr instead of a
MemberExpr, or something equally weird.
* The init-captures can't be captured by inner lambdas. There's a defect
in the standard here too, since it doesn't say that this works (because
they're not automatic storage duration variables, and the outer lambda
doesn't really have a 'this' pointer to capture).
* Despite the standard saying that the init-captures declare named members
of the closure type (with unspecified access, and a suggestion -- not in
the wording -- that they should be public!), that really doesn't match the
intentions of CWG very well, so perhaps we should deviate slightly from
N3690 and head towards what we think we actually meant here -- that is,
make the members unnamed.
Given the above, I'm inclined to suggest that we instead act as if an
init-capture declares and captures an implicit variable (whose scope covers
only the lambda) --- except that the variable is only notional, and we
directly construct the member of the lambda in-place. Then most of the
above pieces should just work. More specifically, when we handle an
init-capture in ActOnLambdaIntroducer, we create a VarDecl (marked
implicit) and capture it, rather than only creating a FieldDecl.