summaryrefslogtreecommitdiffstats
path: root/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorFaisal Vali <faisalv@yahoo.com>2017-01-09 03:02:53 +0000
committerFaisal Vali <faisalv@yahoo.com>2017-01-09 03:02:53 +0000
commit25f75c4838e012e4c08ac295c62c85db644820af (patch)
tree18d496b965d10d8ec2d2be48d822aa18f36af272 /lib/AST/ExprConstant.cpp
parent4711e1718192744efb5fc85d65621450cdcfa919 (diff)
[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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@291416 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r--lib/AST/ExprConstant.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index bb0b8ba5c8..18206e5e0e 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -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::VisitCXXStdInitializerListExpr(
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