Make sure to store the exception in the catch parameter.

llvm-svn: 56102
This commit is contained in:
Anders Carlsson 2008-09-11 09:15:33 +00:00
parent b5130d8588
commit 9396a89899
5 changed files with 38 additions and 19 deletions

View File

@ -456,12 +456,4 @@ void CodeGenFunction::EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S)
CGM.getObjCRuntime().EmitThrowStmt(*this, S);
}
void CodeGenFunction::EmitObjCAtCatchStmt(const ObjCAtCatchStmt &S)
{
if (const Stmt *CatchParam = S.getCatchParamStmt())
EmitStmt(CatchParam);
EmitStmt(S.getCatchBody());
}
CGObjCRuntime::~CGObjCRuntime() {}

View File

@ -1442,16 +1442,18 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
// Handle catch list
for (; CatchStmt; CatchStmt = CatchStmt->getNextCatchStmt()) {
llvm::BasicBlock *NextCatchBlock = llvm::BasicBlock::Create("nextcatch");
llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught");
QualType T;
bool MatchesAll = false;
const DeclStmt *CatchParam =
cast_or_null<DeclStmt>(CatchStmt->getCatchParamStmt());
// catch(...) always matches.
if (CatchStmt->hasEllipsis())
if (!CatchParam)
MatchesAll = true;
else {
const DeclStmt *DS = cast<DeclStmt>(CatchStmt->getCatchParamStmt());
QualType PT = cast<ValueDecl>(DS->getDecl())->getType();
QualType PT = cast<ValueDecl>(CatchParam->getDecl())->getType();
T = PT->getAsPointerType()->getPointeeType();
// catch(id e) always matches.
@ -1460,10 +1462,18 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
}
if (MatchesAll) {
CGF.EmitStmt(CatchStmt);
if (CatchParam) {
CGF.EmitStmt(CatchParam);
const VarDecl *VD = cast<VarDecl>(CatchParam->getDecl());
llvm::Value *V = CGF.GetAddrOfLocalVar(VD);
CGF.Builder.CreateStore(Caught, V);
}
CGF.EmitStmt(CatchStmt->getCatchBody());
CGF.Builder.CreateBr(FinallyBlock);
CGF.EmitBlock(NextCatchBlock);
break;
}
@ -1474,7 +1484,6 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
// Check if the @catch block matches the exception object.
llvm::Value *Class = EmitClassRef(CGF.Builder, ObjCType->getDecl());
llvm::Value *Caught = CGF.Builder.CreateLoad(CaughtPtr, "caught");
llvm::Value *Match = CGF.Builder.CreateCall2(ObjCTypes.ExceptionMatchFn,
Class, Caught, "match");
@ -1486,7 +1495,18 @@ void CGObjCMac::EmitTryStmt(CodeGen::CodeGenFunction &CGF,
// Emit the @catch block.
CGF.EmitBlock(MatchedBlock);
CGF.EmitStmt(CatchStmt);
if (CatchParam) {
CGF.EmitStmt(CatchParam);
const VarDecl *VD = cast<VarDecl>(CatchParam->getDecl());
llvm::Value *Tmp =
CGF.Builder.CreateBitCast(Caught, CGF.ConvertType(VD->getType()),
"tmp");
CGF.Builder.CreateStore(Tmp, CGF.GetAddrOfLocalVar(VD));
}
CGF.EmitStmt(CatchStmt->getCatchBody());
CGF.Builder.CreateBr(FinallyBlock);
CGF.EmitBlock(NextCatchBlock);

View File

@ -81,8 +81,8 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
EmitObjCAtTryStmt(cast<ObjCAtTryStmt>(*S));
break;
case Stmt::ObjCAtCatchStmtClass:
EmitObjCAtCatchStmt(cast<ObjCAtCatchStmt>(*S));
break;
assert(0 && "@catch statements should be handled by EmitObjCAtTryStmt");
break;
case Stmt::ObjCAtFinallyStmtClass:
assert(0 && "@finally statements should be handled by EmitObjCAtTryStmt");
break;

View File

@ -47,6 +47,11 @@ CodeGenFunction::GetAddrOfStaticLocalVar(const VarDecl *BVD) {
return cast<llvm::Constant>(LocalDeclMap[BVD]);
}
llvm::Value *CodeGenFunction::GetAddrOfLocalVar(const VarDecl *VD)
{
return LocalDeclMap[VD];
}
const llvm::Type *CodeGenFunction::ConvertType(QualType T) {
return CGM.getTypes().ConvertType(T);
}

View File

@ -221,6 +221,9 @@ public:
/// GetAddrOfStaticLocalVar - Return the address of a static local variable.
llvm::Constant *GetAddrOfStaticLocalVar(const VarDecl *BVD);
/// GetAddrOfLocalVar - Return the address of a local variable.
llvm::Value *GetAddrOfLocalVar(const VarDecl *VD);
/// getAccessedFieldNo - Given an encoded value and a result number, return
/// the input field number being accessed.
static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
@ -269,7 +272,6 @@ public:
void EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S);
void EmitObjCAtTryStmt(const ObjCAtTryStmt &S);
void EmitObjCAtCatchStmt(const ObjCAtCatchStmt &S);
void EmitObjCAtThrowStmt(const ObjCAtThrowStmt &S);
//===--------------------------------------------------------------------===//