From: Eli Friedman Date: Thu, 9 Feb 2012 03:32:31 +0000 (+0000) Subject: Refactor lambda IRGen so AggExprEmitter::VisitLambdaExpr does the right thing. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4c5d8afd100189b6cce4fd89bfb8aec5700acb50;p=clang 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 --- diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index e309571eff..85b01387e8 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -2361,55 +2361,10 @@ CodeGenFunction::EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E) { 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) { 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(); - if (!RT) - continue; - CXXRecordDecl *RD = cast(RT->getDecl()); - if (!RD->hasTrivialDestructor()) - EHStack.pushCleanup(EHCleanup, *CurField, - RD->getDestructor(), - Slot.getAddr()); - } - PopCleanupBlocks(CleanupDepth); - + EmitLambdaExpr(E, Slot); return MakeAddrLValue(Slot.getAddr(), E->getType()); } diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index 2c10fe6a11..a85cb9dbc3 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -142,12 +142,12 @@ public: } void VisitCXXBindTemporaryExpr(CXXBindTemporaryExpr *E); void VisitCXXConstructExpr(const CXXConstructExpr *E); + void VisitLambdaExpr(LambdaExpr *E); void VisitExprWithCleanups(ExprWithCleanups *E); void VisitCXXScalarValueInitExpr(CXXScalarValueInitExpr *E); void VisitCXXTypeidExpr(CXXTypeidExpr *E) { EmitAggLoadOfLValue(E); } void VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E); void VisitOpaqueValueExpr(OpaqueValueExpr *E); - void VisitLambdaExpr(LambdaExpr *E) { EmitAggLoadOfLValue(E); } void VisitPseudoObjectExpr(PseudoObjectExpr *E) { if (E->isGLValue()) { @@ -539,6 +539,12 @@ AggExprEmitter::VisitCXXConstructExpr(const CXXConstructExpr *E) { CGF.EmitCXXConstructExpr(E, Slot); } +void +AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) { + AggValueSlot Slot = EnsureSlot(E->getType()); + CGF.EmitLambdaExpr(E, Slot); +} + void AggExprEmitter::VisitExprWithCleanups(ExprWithCleanups *E) { CGF.enterFullExpression(E); CodeGenFunction::RunCleanupsScope cleanups(CGF); 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(); + if (!RT) + continue; + CXXRecordDecl *RD = cast(RT->getDecl()); + if (!RD->hasTrivialDestructor()) + EHStack.pushCleanup(EHCleanup, *CurField, + RD->getDestructor(), + Slot.getAddr()); + } + PopCleanupBlocks(CleanupDepth); +} diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 2c61d22f34..e9766ab933 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -2400,6 +2400,8 @@ public: void EmitCXXThrowExpr(const CXXThrowExpr *E); + void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest); + RValue EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest = 0); //===--------------------------------------------------------------------===//