forked from OSchip/llvm-project
Refactor lambda IRGen so AggExprEmitter::VisitLambdaExpr does the right thing.
llvm-svn: 150146
This commit is contained in:
parent
5a294e6a2c
commit
c370a7eec7
|
@ -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<RecordType>();
|
||||
if (!RT)
|
||||
continue;
|
||||
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
|
||||
if (!RD->hasTrivialDestructor())
|
||||
EHStack.pushCleanup<CallLambdaMemberDtor>(EHCleanup, *CurField,
|
||||
RD->getDestructor(),
|
||||
Slot.getAddr());
|
||||
}
|
||||
PopCleanupBlocks(CleanupDepth);
|
||||
|
||||
EmitLambdaExpr(E, Slot);
|
||||
return MakeAddrLValue(Slot.getAddr(), E->getType());
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
Loading…
Reference in New Issue