diff options
author | John McCall <rjmccall@apple.com> | 2010-02-19 09:25:03 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-02-19 09:25:03 +0000 |
commit | 9fc6a7774643a810c8501dae2323e863fefb623e (patch) | |
tree | 5e1022305d460e971bfeca65e95cbf15597c9808 /lib/CodeGen/CodeGenFunction.cpp | |
parent | 8c0b9646f54499ee88a3b3df308a2bfbaafac345 (diff) |
More refactoring around constructor/destructor code generation.
Fix some bugs with function-try-blocks and simplify normal try-block
code generation.
This implementation excludes a deleting destructor's call to
operator delete() from the function-try-block, which I believe
is correct but which I can't find straightforward support for at
a moment's glance.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96670 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 86 |
1 files changed, 13 insertions, 73 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 98113a700e..7337590f57 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -241,80 +241,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } } -void CodeGenFunction::GenerateBody(GlobalDecl GD, llvm::Function *Fn, - FunctionArgList &Args) { - const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); +void CodeGenFunction::EmitFunctionBody(FunctionArgList &Args) { + const FunctionDecl *FD = cast<FunctionDecl>(CurGD.getDecl()); Stmt *Body = FD->getBody(); - assert((Body || FD->isImplicit()) && "non-implicit function def has no body"); - - bool SkipBody = false; // should get jump-threaded - - // Emit special ctor/dtor prologues. - if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { - // Emit the constructor prologue, i.e. the base and member initializers. - EmitCtorPrologue(CD, GD.getCtorType()); - - // TODO: for complete, non-varargs variants, we can get away with - // just emitting the vbase initializers, then calling the base - // constructor. - - } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { - // In all cases, if there's an exception in the body (or delegate) - // we'll still need to run the epilogue. - llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue"); - PushCleanupBlock(DtorEpilogue); - - // If this is the deleting variant, invoke the complete variant; - // the epilogue will call the appropriate operator delete(). - if (GD.getDtorType() == Dtor_Deleting) { - EmitCXXDestructorCall(DD, Dtor_Complete, LoadCXXThis()); - SkipBody = true; - - // If this is the complete variant, just invoke the base variant; - // the epilogue will destruct the virtual bases. - } else if (GD.getDtorType() == Dtor_Complete) { - EmitCXXDestructorCall(DD, Dtor_Base, LoadCXXThis()); - SkipBody = true; - - // Otherwise, we're in the base variant, so we need to ensure the - // vtable ptrs are right before emitting the body. - } else { - InitializeVtablePtrs(DD->getParent()); - } - } - - // Emit the body of the function. - if (SkipBody) { - // skipped - } else if (!Body) { - SynthesizeImplicitFunctionBody(GD, Fn, Args); - } else { - if (isa<CXXTryStmt>(Body)) - OuterTryBlock = cast<CXXTryStmt>(Body); + if (Body) EmitStmt(Body); - } - - // Emit special ctor/dtor epilogues. - if (isa<CXXConstructorDecl>(FD)) { - // Be sure to emit any cleanup blocks associated with the member - // or base initializers, which includes (along the exceptional - // path) the destructors for those members and bases that were - // fully constructed. - EmitCleanupBlocks(0); - - } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { - // Funnel the previously-pushed cleanup block into the epilogue. - CleanupBlockInfo Info = PopCleanupBlock(); - EmitBlock(Info.CleanupBlock); - - EmitDtorEpilogue(DD, GD.getDtorType()); - - // Go ahead and link in the switch and end blocks. - if (Info.SwitchBlock) - EmitBlock(Info.SwitchBlock); - if (Info.EndBlock) - EmitBlock(Info.EndBlock); + else { + assert(FD->isImplicit() && "non-implicit function def has no body"); + assert(FD->isCopyAssignment() && "implicit function not copy assignment"); + SynthesizeCXXCopyAssignment(Args); } } @@ -328,7 +264,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { FunctionArgList Args; CurGD = GD; - OuterTryBlock = 0; if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { if (MD->isInstance()) { // Create the implicit 'this' decl. @@ -368,7 +303,12 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin()); // Generate the body of the function. - GenerateBody(GD, Fn, Args); + if (isa<CXXDestructorDecl>(FD)) + EmitDestructorBody(Args); + else if (isa<CXXConstructorDecl>(FD)) + EmitConstructorBody(Args); + else + EmitFunctionBody(Args); // Emit the standard function epilogue. FinishFunction(BodyRange.getEnd()); |