aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGExprCXX.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-02-09 03:32:31 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-02-09 03:32:31 +0000
commit4c5d8afd100189b6cce4fd89bfb8aec5700acb50 (patch)
tree82fefe6b9b44cfee1a74e99e7267dfd598c4f5eb /lib/CodeGen/CGExprCXX.cpp
parentb4e5e286a5cd156247720b1eb204abaa8e09568d (diff)
Refactor lambda IRGen so AggExprEmitter::VisitLambdaExpr does the right thing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150146 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGExprCXX.cpp')
-rw-r--r--lib/CodeGen/CGExprCXX.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index aa3b3a8a83..b049e02403 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -1764,3 +1764,50 @@ llvm::Value *CodeGenFunction::EmitDynamicCast(llvm::Value *Value,
return Value;
}
+
+namespace {
+ struct CallLambdaMemberDtor : EHScopeStack::Cleanup {
+ FieldDecl *Field;
+ CXXDestructorDecl *Dtor;
+ llvm::Value *Lambda;
+
+ CallLambdaMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor,
+ llvm::Value *Lambda)
+ : Field(Field), Dtor(Dtor), Lambda(Lambda) {}
+
+ void Emit(CodeGenFunction &CGF, Flags flags) {
+ LValue LHS = CGF.EmitLValueForField(Lambda, Field, 0);
+ CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
+ LHS.getAddress());
+ }
+ };
+}
+
+void CodeGenFunction::EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Slot) {
+ EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();
+ CXXRecordDecl::field_iterator CurField = E->getLambdaClass()->field_begin();
+ for (LambdaExpr::capture_init_iterator i = E->capture_init_begin(),
+ e = E->capture_init_end();
+ i != e; ++i, ++CurField) {
+ // FIXME: Add array handling
+ // FIXME: Try to refactor with CodeGenFunction::EmitCtorPrologue
+
+ // Emit initialization
+ LValue LV = EmitLValueForFieldInitialization(Slot.getAddr(), *CurField, 0);
+ EmitExprAsInit(*i, *CurField, LV, false);
+
+ // Add temporary cleanup to handle the case where a later initialization
+ // throws.
+ if (!CGM.getLangOptions().Exceptions)
+ continue;
+ const RecordType *RT = CurField->getType()->getAs<RecordType>();
+ if (!RT)
+ continue;
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ if (!RD->hasTrivialDestructor())
+ EHStack.pushCleanup<CallLambdaMemberDtor>(EHCleanup, *CurField,
+ RD->getDestructor(),
+ Slot.getAddr());
+ }
+ PopCleanupBlocks(CleanupDepth);
+}