aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/CGClass.cpp')
-rw-r--r--lib/CodeGen/CGClass.cpp83
1 files changed, 49 insertions, 34 deletions
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 085cfd3168..a69a3f9566 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -340,7 +340,7 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
if (CGF.Exceptions && !BaseClassDecl->hasTrivialDestructor()) {
// FIXME: Is this OK for C++0x delegating constructors?
- CodeGenFunction::EHCleanupBlock Cleanup(CGF);
+ CodeGenFunction::CleanupBlock Cleanup(CGF, CodeGenFunction::EHCleanup);
CXXDestructorDecl *DD = BaseClassDecl->getDestructor();
CGF.EmitCXXDestructorCall(DD, Dtor_Base, isBaseVirtual, V);
@@ -354,7 +354,7 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,
QualType T,
unsigned Index) {
if (Index == MemberInit->getNumArrayIndices()) {
- CodeGenFunction::CleanupScope Cleanups(CGF);
+ CodeGenFunction::RunCleanupsScope Cleanups(CGF);
llvm::Value *Dest = LHS.getAddress();
if (ArrayIndexVar) {
@@ -410,7 +410,7 @@ static void EmitAggMemberInitializer(CodeGenFunction &CGF,
llvm::BasicBlock *ContinueBlock = CGF.createBasicBlock("for.inc");
{
- CodeGenFunction::CleanupScope Cleanups(CGF);
+ CodeGenFunction::RunCleanupsScope Cleanups(CGF);
// Inside the loop body recurse to emit the inner loop or, eventually, the
// constructor call.
@@ -534,7 +534,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
if (!RD->hasTrivialDestructor()) {
// FIXME: Is this OK for C++0x delegating constructors?
- CodeGenFunction::EHCleanupBlock Cleanup(CGF);
+ CodeGenFunction::CleanupBlock Cleanup(CGF, CodeGenFunction::EHCleanup);
llvm::Value *ThisPtr = CGF.LoadCXXThis();
LValue LHS = CGF.EmitLValueForField(ThisPtr, Field, 0);
@@ -612,7 +612,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
if (IsTryBody)
TryInfo = EnterCXXTryStmt(*cast<CXXTryStmt>(Body));
- unsigned CleanupStackSize = CleanupEntries.size();
+ EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();
// Emit the constructor prologue, i.e. the base and member
// initializers.
@@ -628,7 +628,7 @@ void CodeGenFunction::EmitConstructorBody(FunctionArgList &Args) {
// initializers, which includes (along the exceptional path) the
// destructors for those members and bases that were fully
// constructed.
- EmitCleanupBlocks(CleanupStackSize);
+ PopCleanupBlocks(CleanupDepth);
if (IsTryBody)
ExitCXXTryStmt(*cast<CXXTryStmt>(Body), TryInfo);
@@ -648,9 +648,6 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
B != E; ++B) {
CXXBaseOrMemberInitializer *Member = (*B);
- assert(LiveTemporaries.empty() &&
- "Should not have any live temporaries at initializer start!");
-
if (Member->isBaseInitializer())
EmitBaseInitializer(*this, ClassDecl, Member, CtorType);
else
@@ -659,12 +656,8 @@ void CodeGenFunction::EmitCtorPrologue(const CXXConstructorDecl *CD,
InitializeVTablePointers(ClassDecl);
- for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I) {
- assert(LiveTemporaries.empty() &&
- "Should not have any live temporaries at initializer start!");
-
+ for (unsigned I = 0, E = MemberInitializers.size(); I != E; ++I)
EmitMemberInitializer(*this, ClassDecl, MemberInitializers[I], CD, Args);
- }
}
/// EmitDestructorBody - Emits the body of the current destructor.
@@ -684,8 +677,28 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
if (isTryBody)
TryInfo = EnterCXXTryStmt(*cast<CXXTryStmt>(Body));
- llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue");
- PushCleanupBlock(DtorEpilogue);
+ // Emit the destructor epilogue now. If this is a complete
+ // destructor with a function-try-block, perform the base epilogue
+ // as well.
+ //
+ // FIXME: This isn't really right, because an exception in the
+ // non-EH epilogue should jump to the appropriate place in the
+ // EH epilogue.
+ {
+ CleanupBlock Cleanup(*this, NormalCleanup);
+
+ if (isTryBody && DtorType == Dtor_Complete)
+ EmitDtorEpilogue(Dtor, Dtor_Base);
+ EmitDtorEpilogue(Dtor, DtorType);
+
+ if (Exceptions) {
+ Cleanup.beginEHCleanup();
+
+ if (isTryBody && DtorType == Dtor_Complete)
+ EmitDtorEpilogue(Dtor, Dtor_Base);
+ EmitDtorEpilogue(Dtor, DtorType);
+ }
+ }
bool SkipBody = false; // should get jump-threaded
@@ -724,23 +737,8 @@ void CodeGenFunction::EmitDestructorBody(FunctionArgList &Args) {
// nothing to do besides what's in the epilogue
}
- // Jump to the cleanup block.
- CleanupBlockInfo Info = PopCleanupBlock();
- assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!");
- EmitBlock(DtorEpilogue);
-
- // Emit the destructor epilogue now. If this is a complete
- // destructor with a function-try-block, perform the base epilogue
- // as well.
- if (isTryBody && DtorType == Dtor_Complete)
- EmitDtorEpilogue(Dtor, Dtor_Base);
- EmitDtorEpilogue(Dtor, DtorType);
-
- // Link up the cleanup information.
- if (Info.SwitchBlock)
- EmitBlock(Info.SwitchBlock);
- if (Info.EndBlock)
- EmitBlock(Info.EndBlock);
+ // We're done with the epilogue cleanup.
+ PopCleanupBlock();
// Exit the try if applicable.
if (isTryBody)
@@ -939,7 +937,7 @@ CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *D,
// Keep track of the current number of live temporaries.
{
- CXXTemporariesCleanupScope Scope(*this);
+ RunCleanupsScope Scope(*this);
EmitCXXConstructorCall(D, Ctor_Complete, /*ForVirtualBase=*/false, Address,
ArgBeg, ArgEnd);
@@ -1114,6 +1112,23 @@ void CodeGenFunction::EmitCXXDestructorCall(const CXXDestructorDecl *DD,
EmitCXXMemberCall(DD, Callee, ReturnValueSlot(), This, VTT, 0, 0);
}
+void CodeGenFunction::PushDestructorCleanup(QualType T, llvm::Value *Addr) {
+ CXXRecordDecl *ClassDecl = T->getAsCXXRecordDecl();
+ if (!ClassDecl) return;
+ if (ClassDecl->hasTrivialDestructor()) return;
+
+ const CXXDestructorDecl *D = ClassDecl->getDestructor();
+
+ CleanupBlock Scope(*this, NormalCleanup);
+
+ EmitCXXDestructorCall(D, Dtor_Complete, /*ForVirtualBase=*/false, Addr);
+
+ if (Exceptions) {
+ Scope.beginEHCleanup();
+ EmitCXXDestructorCall(D, Dtor_Complete, /*ForVirtualBase=*/false, Addr);
+ }
+}
+
llvm::Value *
CodeGenFunction::GetVirtualBaseClassOffset(llvm::Value *This,
const CXXRecordDecl *ClassDecl,