faisalv created this revision.
faisalv added reviewers: rsmith, hubert.reinterpretcast, aaron.ballman,
erik.pilkington.
faisalv added a subscriber: cfe-commits.
faisalv set the repository for this revision to rL LLVM.
faisalv added a project: clang-c.
Add a visitor for lambda expressions to RecordExprEvaluator in ExprConstant.cpp
that creates an empty APValue Struct - thus supporting the following code:
constexpr auto ID = [] (auto a) { return a; };
static_assert(ID(3.14) == 3.14);
Repository:
rL LLVM
https://reviews.llvm.org/D22996
Files:
lib/AST/ExprConstant.cpp
test/SemaCXX/cxx1z-constexpr-lambdas.cpp
Index: test/SemaCXX/cxx1z-constexpr-lambdas.cpp
===
--- test/SemaCXX/cxx1z-constexpr-lambdas.cpp
+++ test/SemaCXX/cxx1z-constexpr-lambdas.cpp
@@ -2,6 +2,16 @@
// RUN: %clang_cc1 -std=c++1z -verify -fsyntax-only -fblocks -fdelayed-template-parsing %s
// RUN: %clang_cc1 -std=c++14 -verify -fsyntax-only -fblocks %s -DCPP14_AND_EARLIER
+namespace test_lambda_is_literal {
+#ifdef CPP14_AND_EARLIER
+//expected-error@+4{{not a literal type}}
+//expected-note@+2{{not an aggregate and has no constexpr constructors}}
+#endif
+auto L = [] { };
+constexpr int foo(decltype(L) l) { return 0; }
+}
+
+
#ifndef CPP14_AND_EARLIER
namespace test_constexpr_checking {
@@ -35,14 +45,73 @@
} // end ns test_constexpr_call
-#endif
-namespace test_lambda_is_literal {
-#ifdef CPP14_AND_EARLIER
-//expected-error@+4{{not a literal type}}
-//expected-note@+2{{not an aggregate and has no constexpr constructors}}
-#endif
-auto L = [] { };
-constexpr int foo(decltype(L) l) { return 0; }
+namespace test_lambda_is_cce {
+namespace ns1_simple_lambda {
-}
\ No newline at end of file
+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
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -5433,6 +5433,7 @@
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);
@@ -5764,6 +5765,21 @@
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 ,
APValue , EvalInfo ) {
assert(E->isRValue() && E->getType()->isRecordType() &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits