<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 8 January 2017 at 19:02, Faisal Vali via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: faisalv<br>
Date: Sun Jan  8 21:02:53 2017<br>
New Revision: 291416<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=291416&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=291416&view=rev</a><br>
Log:<br>
[cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing lambda expressions.<br>
<br>
Add a visitor for lambda expressions to RecordExprEvaluator in ExprConstant.cpp that creates an empty APValue of Struct type to represent the closure object. Additionally, add a LambdaExpr visitor to the TemporaryExprEvaluator that forwards constant evaluation of immediately-called-lambda-<wbr>expressions to the one in RecordExprEvaluator through VisitConstructExpr.<br>
<br>
This patch supports:<br>
constexpr auto ID = [] (auto a) { return a; };<br>
static_assert(ID(3.14) == 3.14);<br>
static_assert([](auto a) { return a + 1; }(10) == 11);<br>
<br>
Lambda captures are still not supported for constexpr lambdas.<br>
<br>
<br>
Modified:<br>
    cfe/trunk/lib/AST/<wbr>ExprConstant.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
    cfe/trunk/test/SemaCXX/cxx1z-<wbr>constexpr-lambdas.cpp<br>
<br>
Modified: cfe/trunk/lib/AST/<wbr>ExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=291416&r1=291415&r2=291416&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ExprConstant.cpp?rev=291416&<wbr>r1=291415&r2=291416&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/AST/<wbr>ExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/AST/<wbr>ExprConstant.cpp Sun Jan  8 21:02:53 2017<br>
@@ -5868,6 +5868,7 @@ namespace {<br>
     bool VisitCXXConstructExpr(const CXXConstructExpr *E) {<br>
       return VisitCXXConstructExpr(E, E->getType());<br>
     }<br>
+    bool VisitLambdaExpr(const LambdaExpr *E);<br>
     bool VisitCXXInheritedCtorInitExpr(<wbr>const CXXInheritedCtorInitExpr *E);<br>
     bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);<br>
     bool VisitCXXStdInitializerListExpr<wbr>(const CXXStdInitializerListExpr *E);<br>
@@ -6202,6 +6203,21 @@ bool RecordExprEvaluator::<wbr>VisitCXXStdIni<br>
   return true;<br>
 }<br>
<br>
+bool RecordExprEvaluator::<wbr>VisitLambdaExpr(const LambdaExpr *E) {<br>
+  const CXXRecordDecl *ClosureClass = E->getLambdaClass();<br>
+  if (ClosureClass->isInvalidDecl()<wbr>) return false;<br>
+<br>
+  if (Info.<wbr>checkingPotentialConstantExpre<wbr>ssion()) return true;<br>
+  if (E->capture_size()) {<br>
+    Info.FFDiag(E, diag::note_unimplemented_<wbr>constexpr_lambda_feature_ast)<br>
+        << "can not evaluate lambda expressions with captures";<br>
+    return false;<br>
+  }<br>
+  // FIXME: Implement captures.<br>
+  Result = APValue(APValue::UninitStruct(<wbr>), /*NumBases*/0, /*NumFields*/0);<br>
+  return true;<br>
+}<br>
+<br>
 static bool EvaluateRecord(const Expr *E, const LValue &This,<br>
                            APValue &Result, EvalInfo &Info) {<br>
   assert(E->isRValue() && E->getType()->isRecordType() &&<br>
@@ -6251,6 +6267,9 @@ public:<br>
   bool VisitCXXStdInitializerListExpr<wbr>(const CXXStdInitializerListExpr *E) {<br>
     return VisitConstructExpr(E);<br>
   }<br>
+  bool VisitLambdaExpr(const LambdaExpr *E) {<br>
+    return VisitConstructExpr(E);<br>
+  }<br>
 };<br>
 } // end anonymous namespace<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=291416&r1=291415&r2=291416&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExpr.cpp?rev=291416&r1=<wbr>291415&r2=291416&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp Sun Jan  8 21:02:53 2017<br>
@@ -13097,8 +13097,10 @@ void Sema::<wbr>PopExpressionEvaluationContex<br>
         //   evaluate [...] a lambda-expression.<br>
         D = diag::err_lambda_in_constant_<wbr>expression;<br>
       }<br>
-      for (const auto *L : Rec.Lambdas)<br>
-        Diag(L->getLocStart(), D);<br>
+      // C++1z allows lambda expressions as core constant expressions.<br>
+      if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z)<br>
+        for (const auto *L : Rec.Lambdas)<br>
+          Diag(L->getLocStart(), D);<br></blockquote><div><br></div><div>We'll need an implementation of DR1607 before we're done here, since it looks like this has removed the last restriction on lambda-expressions in function template signatures in some contexts (array bounds, template arguments).</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
     } else {<br>
       // Mark the capture expressions odr-used. This was deferred<br>
       // during lambda expression creation.<br>
<br>
Modified: cfe/trunk/test/SemaCXX/cxx1z-<wbr>constexpr-lambdas.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=291416&r1=291415&r2=291416&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>SemaCXX/cxx1z-constexpr-<wbr>lambdas.cpp?rev=291416&r1=<wbr>291415&r2=291416&view=diff</a><br>
==============================<wbr>==============================<wbr>==================<br>
--- cfe/trunk/test/SemaCXX/cxx1z-<wbr>constexpr-lambdas.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/cxx1z-<wbr>constexpr-lambdas.cpp Sun Jan  8 21:02:53 2017<br>
@@ -96,4 +96,81 @@ decltype(deduced_return_type(<wbr>0)) d;  //e<br>
<br>
 } // end ns test_conversion_function_for_<wbr>non_capturing_lambdas<br>
<br>
+namespace test_lambda_is_cce {<br>
+namespace ns1_simple_lambda {<br>
+<br>
+namespace ns0 {<br>
+constexpr int I = [](auto a) { return a; }(10);<br>
+<br>
+static_assert(I == 10);<br>
+static_assert(10 == [](auto a) { return a; }(10));<br>
+static_assert(3.14 == [](auto a) { return a; }(3.14));<br>
+<br>
+} //end ns0<br>
+<br>
+namespace ns1 {<br>
+constexpr auto f(int i) {<br>
+  double d = 3.14;<br>
+  auto L = [=](auto a) {<br>
+    int Isz = sizeof(i);<br>
+    return sizeof(i) + sizeof(a) + sizeof(d);<br>
+  };<br>
+  int I = L("abc") + L(nullptr);<br>
+  return L;<br>
+}<br>
+constexpr auto L = f(3);<br>
+constexpr auto M =  L("abc") + L(nullptr);<br>
+<br>
+static_assert(M == sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) + sizeof(const char*));<br>
+<br>
+} // end ns1<br>
+<br>
+namespace ns2 {<br>
+constexpr auto f(int i) {<br>
+  auto L = [](auto a) { return a + a; };<br>
+  return L;<br>
+}<br>
+constexpr auto L = f(3);<br>
+constexpr int I = L(6);<br>
+static_assert(I == 12);<br>
+} // end ns2<br>
+<br>
+namespace contained_lambdas_call_<wbr>operator_is_not_constexpr {<br>
+constexpr auto f(int i) {<br>
+  double d = 3.14;<br>
+  auto L = [=](auto a) { //expected-note{{declared here}}<br>
+    int Isz = sizeof(i);<br>
+    asm("hello");<br>
+    return sizeof(i) + sizeof(a) + sizeof(d);<br>
+  };<br>
+  return L;<br>
+}<br>
+<br>
+constexpr auto L = f(3);<br>
+<br>
+constexpr auto M =  // expected-error{{must be initialized by}}<br>
+    L("abc"); //expected-note{{non-constexpr function}}<br>
+<br>
+} // end ns contained_lambdas_call_<wbr>operator_is_not_constexpr<br>
+<br>
+<br>
+<br>
+} // end ns1_simple_lambda<br>
+<br>
+namespace ns1_unimplemented {<br>
+namespace ns1_captures {<br>
+constexpr auto f(int i) {<br>
+  double d = 3.14;<br>
+  auto L = [=](auto a) { //expected-note{{coming soon}}<br>
+    int Isz = i + d;<br>
+    return sizeof(i) + sizeof(a) + sizeof(d);<br>
+  };<br>
+  return L;<br>
+}<br>
+constexpr auto M = f(3);  //expected-error{{constant expression}} expected-note{{in call to}}<br>
+} // end ns1_captures<br>
+} // end ns1_unimplemented<br>
+<br>
+} // end ns test_lambda_is_cce<br>
+<br>
 #endif // ndef CPP14_AND_EARLIER<br>
<br>
<br>
______________________________<wbr>_________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>