diff options
author | John McCall <rjmccall@apple.com> | 2010-02-18 03:17:58 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-02-18 03:17:58 +0000 |
commit | a355e07454463b19829ac92ffd115a097faff0e0 (patch) | |
tree | cb39601140d9cac19861c911455c00ca7451dfef /lib/CodeGen/CodeGenFunction.cpp | |
parent | e77f443dbca8cdc23e5aa94a2653367e4a7cbe47 (diff) |
Extract out function-body code generation into its own method. No functionality
change.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96564 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 126 |
1 files changed, 55 insertions, 71 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index d803a05aa9..ddf4e6431d 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -241,6 +241,53 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } } +void CodeGenFunction::GenerateBody(GlobalDecl GD, llvm::Function *Fn, + FunctionArgList &Args) { + const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); + + Stmt *Body = FD->getBody(); + assert((Body || FD->isImplicit()) && "non-implicit function def has no body"); + + // Emit special ctor/dtor prologues. + llvm::BasicBlock *DtorEpilogue = 0; + if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { + EmitCtorPrologue(CD, GD.getCtorType()); + } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { + DtorEpilogue = createBasicBlock("dtor.epilogue"); + PushCleanupBlock(DtorEpilogue); + + InitializeVtablePtrs(DD->getParent()); + } + + // Emit the body of the function. + if (!Body) + SynthesizeImplicitFunctionBody(GD, Fn, Args); + else { + if (isa<CXXTryStmt>(Body)) + OuterTryBlock = cast<CXXTryStmt>(Body); + + EmitStmt(Body); + } + + // Emit special ctor/ctor epilogues. + if (isa<CXXConstructorDecl>(FD)) { + // If any of the member initializers are temporaries bound to references + // make sure to emit their destructors. + EmitCleanupBlocks(0); + } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { + CleanupBlockInfo Info = PopCleanupBlock(); + assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!"); + + EmitBlock(DtorEpilogue); + EmitDtorEpilogue(DD, GD.getDtorType()); + + if (Info.SwitchBlock) + EmitBlock(Info.SwitchBlock); + if (Info.EndBlock) + EmitBlock(Info.EndBlock); + } +} + void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); @@ -284,80 +331,17 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) { FProto->getArgType(i))); } - if (const CompoundStmt *S = FD->getCompoundBody()) { - StartFunction(GD, FD->getResultType(), Fn, Args, S->getLBracLoc()); - - if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { - EmitCtorPrologue(CD, GD.getCtorType()); - EmitStmt(S); - - // If any of the member initializers are temporaries bound to references - // make sure to emit their destructors. - EmitCleanupBlocks(0); - - } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { - llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue"); - PushCleanupBlock(DtorEpilogue); + SourceRange BodyRange; + if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange(); - InitializeVtablePtrs(DD->getParent()); + // Emit the standard function prologue. + StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin()); - EmitStmt(S); - - CleanupBlockInfo Info = PopCleanupBlock(); + // Generate the body of the function. + GenerateBody(GD, Fn, Args); - assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!"); - EmitBlock(DtorEpilogue); - EmitDtorEpilogue(DD, GD.getDtorType()); - - if (Info.SwitchBlock) - EmitBlock(Info.SwitchBlock); - if (Info.EndBlock) - EmitBlock(Info.EndBlock); - } else { - // Just a regular function, emit its body. - EmitStmt(S); - } - - FinishFunction(S->getRBracLoc()); - } else if (FD->isImplicit()) { - const CXXRecordDecl *ClassDecl = - cast<CXXRecordDecl>(FD->getDeclContext()); - (void) ClassDecl; - if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { - // FIXME: For C++0x, we want to look for implicit *definitions* of - // these special member functions, rather than implicit *declarations*. - if (CD->isCopyConstructor()) { - assert(!ClassDecl->hasUserDeclaredCopyConstructor() && - "Cannot synthesize a non-implicit copy constructor"); - SynthesizeCXXCopyConstructor(CD, GD.getCtorType(), Fn, Args); - } else if (CD->isDefaultConstructor()) { - assert(!ClassDecl->hasUserDeclaredConstructor() && - "Cannot synthesize a non-implicit default constructor."); - SynthesizeDefaultConstructor(CD, GD.getCtorType(), Fn, Args); - } else { - assert(false && "Implicit constructor cannot be synthesized"); - } - } else if (const CXXDestructorDecl *CD = dyn_cast<CXXDestructorDecl>(FD)) { - assert(!ClassDecl->hasUserDeclaredDestructor() && - "Cannot synthesize a non-implicit destructor"); - SynthesizeDefaultDestructor(CD, GD.getDtorType(), Fn, Args); - } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - assert(MD->isCopyAssignment() && - !ClassDecl->hasUserDeclaredCopyAssignment() && - "Cannot synthesize a method that is not an implicit-defined " - "copy constructor"); - SynthesizeCXXCopyAssignment(MD, Fn, Args); - } else { - assert(false && "Cannot synthesize unknown implicit function"); - } - } else if (const Stmt *S = FD->getBody()) { - if (const CXXTryStmt *TS = dyn_cast<CXXTryStmt>(S)) { - OuterTryBlock = TS; - StartFunction(GD, FD->getResultType(), Fn, Args, TS->getTryLoc()); - EmitStmt(TS); - FinishFunction(TS->getEndLoc()); - } - } + // Emit the standard function epilogue. + FinishFunction(BodyRange.getEnd()); // Destroy the 'this' declaration. if (CXXThisDecl) |