return VTT;
}
+namespace {
+ struct CallBaseDtor : EHScopeStack::LazyCleanup {
+ CXXDestructorDecl *Dtor;
+ bool isBaseVirtual;
+ llvm::Value *Addr;
+
+ CallBaseDtor(CXXDestructorDecl *DD, bool isVirtual, llvm::Value *Addr)
+ : Dtor(DD), isBaseVirtual(isVirtual), Addr(Addr) {}
+
+ void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ // FIXME: Is this OK for C++0x delegating constructors?
+ CGF.EmitCXXDestructorCall(Dtor, Dtor_Base, isBaseVirtual, Addr);
+ }
+ };
+}
+
static void EmitBaseInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
CXXBaseOrMemberInitializer *BaseInit,
CGF.EmitAggExpr(BaseInit->getInit(), V, false, false, true);
- if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) {
- // FIXME: Is this OK for C++0x delegating constructors?
- CodeGenFunction::CleanupBlock Cleanup(CGF, EHCleanup);
-
- CXXDestructorDecl *DD = BaseClassDecl->getDestructor();
- CGF.EmitCXXDestructorCall(DD, Dtor_Base, isBaseVirtual, V);
- }
+ if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor())
+ CGF.EHStack.pushLazyCleanup<CallBaseDtor>(EHCleanup,
+ BaseClassDecl->getDestructor(),
+ isBaseVirtual, V);
}
static void EmitAggMemberInitializer(CodeGenFunction &CGF,
// Emit the fall-through block.
CGF.EmitBlock(AfterFor, true);
}
+
+namespace {
+ struct CallMemberDtor : EHScopeStack::LazyCleanup {
+ FieldDecl *Field;
+ CXXDestructorDecl *Dtor;
+
+ CallMemberDtor(FieldDecl *Field, CXXDestructorDecl *Dtor)
+ : Field(Field), Dtor(Dtor) {}
+
+ void Emit(CodeGenFunction &CGF, bool IsForEH) {
+ // FIXME: Is this OK for C++0x delegating constructors?
+ llvm::Value *ThisPtr = CGF.LoadCXXThis();
+ LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
+
+ CGF.EmitCXXDestructorCall(Dtor, Dtor_Complete, /*ForVirtualBase=*/false,
+ LHS.getAddress());
+ }
+ };
+}
static void EmitMemberInitializer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
return;
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- if (!RD->hasTrivialDestructor()) {
- // FIXME: Is this OK for C++0x delegating constructors?
- CodeGenFunction::CleanupBlock Cleanup(CGF, EHCleanup);
-
- llvm::Value *ThisPtr = CGF.LoadCXXThis();
- LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
-
- CXXDestructorDecl *DD = RD->getDestructor();
- CGF.EmitCXXDestructorCall(DD, Dtor_Complete, /*ForVirtualBase=*/false,
- LHS.getAddress());
- }
+ if (!RD->hasTrivialDestructor())
+ CGF.EHStack.pushLazyCleanup<CallMemberDtor>(EHCleanup, Field,
+ RD->getDestructor());
}
}
// Checks from test3:
- // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(
- // CHECK: call void @_ZN5test31BD2Ev(
- // CHECK: call void @_ZN5test31AD2Ev(
- // CHECK: ret void
-
// CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(
// CHECK: invoke void @_ZN5test312_GLOBAL__N_11DD1Ev(
// CHECK: call void @_ZdlPv({{.*}}) nounwind
// CHECK: call void @_ZN5test312_GLOBAL__N_11DD0Ev(
// CHECK: ret void
+ // CHECK: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(
+ // CHECK: call void @_ZN5test31BD2Ev(
+ // CHECK: call void @_ZN5test31AD2Ev(
+ // CHECK: ret void
+
// CHECK: declare void @_ZN5test31BD2Ev(
// CHECK: declare void @_ZN5test31AD2Ev(