On 8 January 2017 at 19:02, Faisal Vali via cfe-commits < cfe-commits@lists.llvm.org> wrote:
> Author: faisalv > Date: Sun Jan 8 21:02:53 2017 > New Revision: 291416 > > URL: http://llvm.org/viewvc/llvm-project?rev=291416&view=rev > Log: > [cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing > lambda expressions. > > 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-expressions to the one in RecordExprEvaluator > through VisitConstructExpr. > > This patch supports: > constexpr auto ID = [] (auto a) { return a; }; > static_assert(ID(3.14) == 3.14); > static_assert([](auto a) { return a + 1; }(10) == 11); > > Lambda captures are still not supported for constexpr lambdas. > > > Modified: > cfe/trunk/lib/AST/ExprConstant.cpp > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp > > Modified: cfe/trunk/lib/AST/ExprConstant.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ > ExprConstant.cpp?rev=291416&r1=291415&r2=291416&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/AST/ExprConstant.cpp (original) > +++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Jan 8 21:02:53 2017 > @@ -5868,6 +5868,7 @@ namespace { > bool VisitCXXConstructExpr(const CXXConstructExpr *E) { > return VisitCXXConstructExpr(E, E->getType()); > } > + bool VisitLambdaExpr(const LambdaExpr *E); > bool VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr > *E); > bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T); > bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr > *E); > @@ -6202,6 +6203,21 @@ bool RecordExprEvaluator::VisitCXXStdIni > return true; > } > > +bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) { > + const CXXRecordDecl *ClosureClass = E->getLambdaClass(); > + if (ClosureClass->isInvalidDecl()) return false; > + > + if (Info.checkingPotentialConstantExpression()) return true; > + if (E->capture_size()) { > + Info.FFDiag(E, diag::note_unimplemented_constexpr_lambda_feature_ast) > + << "can not evaluate lambda expressions with captures"; > + return false; > + } > + // FIXME: Implement captures. > + Result = APValue(APValue::UninitStruct(), /*NumBases*/0, > /*NumFields*/0); > + return true; > +} > + > static bool EvaluateRecord(const Expr *E, const LValue &This, > APValue &Result, EvalInfo &Info) { > assert(E->isRValue() && E->getType()->isRecordType() && > @@ -6251,6 +6267,9 @@ public: > bool VisitCXXStdInitializerListExpr(const CXXStdInitializerListExpr > *E) { > return VisitConstructExpr(E); > } > + bool VisitLambdaExpr(const LambdaExpr *E) { > + return VisitConstructExpr(E); > + } > }; > } // end anonymous namespace > > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/ > SemaExpr.cpp?rev=291416&r1=291415&r2=291416&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jan 8 21:02:53 2017 > @@ -13097,8 +13097,10 @@ void Sema::PopExpressionEvaluationContex > // evaluate [...] a lambda-expression. > D = diag::err_lambda_in_constant_expression; > } > - for (const auto *L : Rec.Lambdas) > - Diag(L->getLocStart(), D); > + // C++1z allows lambda expressions as core constant expressions. > + if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z) > + for (const auto *L : Rec.Lambdas) > + Diag(L->getLocStart(), D); > 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). } else { > // Mark the capture expressions odr-used. This was deferred > // during lambda expression creation. > > Modified: cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > SemaCXX/cxx1z-constexpr-lambdas.cpp?rev=291416&r1= > 291415&r2=291416&view=diff > ============================================================ > ================== > --- cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp (original) > +++ cfe/trunk/test/SemaCXX/cxx1z-constexpr-lambdas.cpp Sun Jan 8 > 21:02:53 2017 > @@ -96,4 +96,81 @@ decltype(deduced_return_type(0)) d; //e > > } // end ns test_conversion_function_for_non_capturing_lambdas > > +namespace test_lambda_is_cce { > +namespace ns1_simple_lambda { > + > +namespace ns0 { > +constexpr int I = [](auto a) { return a; }(10); > + > +static_assert(I == 10); > +static_assert(10 == [](auto a) { return a; }(10)); > +static_assert(3.14 == [](auto a) { return a; }(3.14)); > + > +} //end ns0 > + > +namespace ns1 { > +constexpr auto f(int i) { > + double d = 3.14; > + auto L = [=](auto a) { > + int Isz = sizeof(i); > + return sizeof(i) + sizeof(a) + sizeof(d); > + }; > + int I = L("abc") + L(nullptr); > + return L; > +} > +constexpr auto L = f(3); > +constexpr auto M = L("abc") + L(nullptr); > + > +static_assert(M == sizeof(int) * 2 + sizeof(double) * 2 + sizeof(nullptr) > + sizeof(const char*)); > + > +} // end ns1 > + > +namespace ns2 { > +constexpr auto f(int i) { > + auto L = [](auto a) { return a + a; }; > + return L; > +} > +constexpr auto L = f(3); > +constexpr int I = L(6); > +static_assert(I == 12); > +} // end ns2 > + > +namespace contained_lambdas_call_operator_is_not_constexpr { > +constexpr auto f(int i) { > + double d = 3.14; > + auto L = [=](auto a) { //expected-note{{declared here}} > + int Isz = sizeof(i); > + asm("hello"); > + return sizeof(i) + sizeof(a) + sizeof(d); > + }; > + return L; > +} > + > +constexpr auto L = f(3); > + > +constexpr auto M = // expected-error{{must be initialized by}} > + L("abc"); //expected-note{{non-constexpr function}} > + > +} // end ns contained_lambdas_call_operator_is_not_constexpr > + > + > + > +} // end ns1_simple_lambda > + > +namespace ns1_unimplemented { > +namespace ns1_captures { > +constexpr auto f(int i) { > + double d = 3.14; > + auto L = [=](auto a) { //expected-note{{coming soon}} > + int Isz = i + d; > + return sizeof(i) + sizeof(a) + sizeof(d); > + }; > + return L; > +} > +constexpr auto M = f(3); //expected-error{{constant expression}} > expected-note{{in call to}} > +} // end ns1_captures > +} // end ns1_unimplemented > + > +} // end ns test_lambda_is_cce > + > #endif // ndef CPP14_AND_EARLIER > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits