[cfe-commits] r150141 - /cfe/trunk/lib/CodeGen/CGExpr.cpp
Eli Friedman
eli.friedman at gmail.com
Wed Feb 8 19:19:12 PST 2012
Author: efriedma
Date: Wed Feb 8 21:19:12 2012
New Revision: 150141
URL: http://llvm.org/viewvc/llvm-project?rev=150141&view=rev
Log:
Basic IRGen for LambdaExprs with captures.
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=150141&r1=150140&r2=150141&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Wed Feb 8 21:19:12 2012
@@ -2361,12 +2361,55 @@
return MakeAddrLValue(Slot.getAddr(), E->getType());
}
+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());
+ }
+ };
+}
+
LValue
CodeGenFunction::EmitLambdaLValue(const LambdaExpr *E) {
- if (E->capture_begin() != E->capture_end())
- return EmitUnsupportedLValue(E, "lambda expression");
-
AggValueSlot Slot = CreateAggTemp(E->getType(), "temp.lvalue");
+
+ 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);
+
return MakeAddrLValue(Slot.getAddr(), E->getType());
}
More information about the cfe-commits
mailing list