diff options
author | Mike Stump <mrs@apple.com> | 2009-12-04 23:26:17 +0000 |
---|---|---|
committer | Mike Stump <mrs@apple.com> | 2009-12-04 23:26:17 +0000 |
commit | bee78dd31b5da3dda6d5e053df389df67e60564c (patch) | |
tree | c14c73ae84ad7ebd156d71b18c6095373f7e9217 /clang/lib/CodeGen/CGException.cpp | |
parent | e6d5445dc1bf69fdbf345ed09dec06c6346313aa (diff) | |
download | bcm5719-llvm-bee78dd31b5da3dda6d5e053df389df67e60564c.tar.gz bcm5719-llvm-bee78dd31b5da3dda6d5e053df389df67e60564c.zip |
Add support for function try blocks.
llvm-svn: 90622
Diffstat (limited to 'clang/lib/CodeGen/CGException.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGException.cpp | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/clang/lib/CodeGen/CGException.cpp b/clang/lib/CodeGen/CGException.cpp index 62064ecf41c..73f66ccd3f5 100644 --- a/clang/lib/CodeGen/CGException.cpp +++ b/clang/lib/CodeGen/CGException.cpp @@ -270,6 +270,7 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { EmitStmt(S.getTryBlock()); return; } + // FIXME: The below is still just a sketch of the code we need. // Pointer to the personality function llvm::Constant *Personality = @@ -295,7 +296,40 @@ void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) { // Emit the statements in the try {} block setInvokeDest(TryHandler); - EmitStmt(S.getTryBlock()); + // FIXME: We should not have to do this here. The AST should have the member + // initializers under the CXXTryStmt's TryBlock. + if (OuterTryBlock == &S) { + GlobalDecl GD = CurGD; + const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); + + if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) { + size_t OldCleanupStackSize = CleanupEntries.size(); + EmitCtorPrologue(CD, CurGD.getCtorType()); + EmitStmt(S.getTryBlock()); + + // If any of the member initializers are temporaries bound to references + // make sure to emit their destructors. + EmitCleanupBlocks(OldCleanupStackSize); + } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) { + llvm::BasicBlock *DtorEpilogue = createBasicBlock("dtor.epilogue"); + PushCleanupBlock(DtorEpilogue); + + EmitStmt(S.getTryBlock()); + + 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); + } else + EmitStmt(S.getTryBlock()); + } else + EmitStmt(S.getTryBlock()); // Jump to end if there is no exception EmitBranchThroughCleanup(FinallyEnd); |