mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 21:53:12 +08:00
Add support for function try blocks.
llvm-svn: 90622
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/StmtCXX.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
@@ -255,6 +256,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD,
|
||||
|
||||
FunctionArgList Args;
|
||||
|
||||
CurGD = GD;
|
||||
OuterTryBlock = 0;
|
||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
||||
if (MD->isInstance()) {
|
||||
// Create the implicit 'this' decl.
|
||||
@@ -286,7 +289,6 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD,
|
||||
FProto->getArgType(i)));
|
||||
}
|
||||
|
||||
// FIXME: Support CXXTryStmt here, too.
|
||||
if (const CompoundStmt *S = FD->getCompoundBody()) {
|
||||
StartFunction(GD, FD->getResultType(), Fn, Args, S->getLBracLoc());
|
||||
|
||||
@@ -351,6 +353,13 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD,
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the 'this' declaration.
|
||||
|
||||
@@ -88,6 +88,12 @@ public:
|
||||
QualType FnRetTy;
|
||||
llvm::Function *CurFn;
|
||||
|
||||
/// CurGD - The GlobalDecl for the current function being compiled.
|
||||
GlobalDecl CurGD;
|
||||
/// OuterTryBlock - This is the address of the outter most try block, 0
|
||||
/// otherwise.
|
||||
const Stmt *OuterTryBlock;
|
||||
|
||||
/// ReturnBlock - Unified return block.
|
||||
llvm::BasicBlock *ReturnBlock;
|
||||
/// ReturnValue - The temporary alloca to hold the return value. This is null
|
||||
|
||||
Reference in New Issue
Block a user