On 9 January 2017 at 03:44, Faisal Vali <fais...@gmail.com> wrote: > On Mon, Jan 9, 2017 at 12:13 AM, Richard Smith <rich...@metafoo.co.uk> > wrote: > > 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). > > > > Yes - I'll add those restrictions back (I suppose we'll need to check > whether the nearest enclosing non-lambda context is a valid one [while > still allowing them in default function arguments]) - but then we'll > need to relax some of them when we implement P0315 in post-C++-17 > right? > > For e.g. these would be ok w P0315 right? > > template<int N = []{ return 5; }()> struct X { }; > > X<[](auto a){ return a; }(10)> x;
Who can say... P0315's direction is not finalized as far as I'm aware, and I don't expect it to apply retroactively, so we'll need the DR1607 rules anyway.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits