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; Thanks! _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits