<div dir="ltr">On Tue, Jun 11, 2013 at 10:05 PM, Faisal Vali <span dir="ltr"><<a href="mailto:faisalv@gmail.com" target="_blank">faisalv@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hello,<br>
Attached is a patch that implements a very simple form of generic lambdas<br>
that allows 'auto' and variadic 'auto' as parameters in lambdas. This<br>
allows the<br>
following code to compile:<br>
auto Fact = [](auto Self, unsigned n) -> unsigned {<br>
return !n ? 1 : Self(Self, n - 1) * n;<br>
};<br>
auto six = Fact(Fact, 3);<br></blockquote><div><br></div><div>Index: lib/Serialization/ASTReader.cpp</div><div>===================================================================</div><div>--- lib/Serialization/ASTReader.cpp<span class="" style="white-space:pre"> </span>(revision 183717)</div>
<div>+++ lib/Serialization/ASTReader.cpp<span class="" style="white-space:pre"> </span>(working copy)</div><div>@@ -4704,7 +4704,10 @@</div><div> QualType Deduced = readType(*Loc.F, Record, Idx);</div><div> bool IsDecltypeAuto = Record[Idx++];</div>
<div> bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;</div><div>- return Context.getAutoType(Deduced, IsDecltypeAuto, IsDependent);</div><div>+ //FIXME: How do we figure out if this needs to be a parameter pack?</div>
<div><br></div><div>By making the corresponding change to ASTWriter.cpp.</div><div><br></div><div>@@ -547,6 +550,18 @@</div><div> </div><div> /// \brief The type of the call method.</div><div> TypeSourceInfo *MethodTyInfo;</div>
<div>+</div><div>+ /// \brief The Lambda call method</div><div>+ CXXMethodDecl *CallOperator;</div><div>+ </div><div>+ /// \brief The Lambda conversion operator, for non-capturing lambdas</div><div>+ CXXConversionDecl *ConversionOperator;</div>
<div>+ </div><div>+ /// \brief The Lambda static method invoker, for non-capturing lambdas</div><div>+ CXXMethodDecl *StaticInvoker;</div><div>+</div><div>+ LambdaExpr *ParentLambdaExpr;</div><div><br></div><div>
It's not obvious why you're making this change... we try to keep the AST as small as possible.</div><div><br></div><div> </div><div><div>+ ParmVarDecl *PVD = cast<ParmVarDecl>(Param);</div><div>+ // Handle 'auto' within a generic lambda.</div>
<div>+ // FVQUESTION: Should I use getOriginalType here - how do i </div><div>+ // know when to use which?</div><div>+ QualType ParamType = PVD->getType();</div><div><br></div><div>If you're unsure, getType() is probably the right choice... I don't think it matters here, though.</div>
<div><br></div><div>+ if (getLangOpts().CPlusPlus1y && ParamType->getContainedAutoType()) { </div><div>+ TemplateTypeParmDecl *TemplateParam = </div><div>+ Actions.ActOnLambdaAutoParameter(getCurScope(), PVD, </div>
<div>+ CurTemplateDepth, CurAutoParameterIndex); </div><div>+ TemplateParams.push_back(TemplateParam);</div><div>+ } </div></div><div><br></div><div>We generally prefer to avoid having code in Parser/ inspect AST types. Can you move building the TemplateParameterList into ActOnStartOfLambdaDefinition?</div>
<div><br></div><div><div>+// The name of the static invoker function that will forward</div><div>+// to the corresponding lambda call operator.</div><div>+static inline const char* getSecretLambdaStaticInvokerStringID() {</div>
<div>+ return "__invoker";</div><div>+}</div></div><div><br></div><div>I'm not sure how this abstraction is actually helpful, given the function only has one use.</div><div><br></div><div><div>+ // FVQUESTION? When a generic lamdba call operator is being instantiated, if</div>
<div>+ // for some reason instantiation fails, the SemaDiagnosticEmitter ends up</div><div>+ // emitting the entire instantiation stack, and since local pending </div><div>+ // instantiations are called recursively,</div>
</div><div><br></div><div>We should not be instantiating the lambda in your example more than once at the same time. If we are, it's probably a bug.<br></div><div><br></div><div><br></div><div>-Eli</div></div></div></div>