<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>