// Emit the handlers
CGF.EmitBlock(TryHandler);
+ // Get the correct versions of the exception handling intrinsics
+ llvm::TargetData td = llvm::TargetData::TargetData(&TheModule);
+ int PointerWidth = td.getTypeSizeInBits(PtrTy);
+ assert((PointerWidth == 32 || PointerWidth == 64) &&
+ "Can't yet handle exceptions if pointers are not 32 or 64 bits");
llvm::Value *llvm_eh_exception =
CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_exception);
- llvm::Value *llvm_eh_selector_i64 =
- CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i32);
- llvm::Value *llvm_eh_typeid_for_i64 =
- CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i32);
+ llvm::Value *llvm_eh_selector = PointerWidth == 32 ?
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i32) :
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_selector_i64);
+ llvm::Value *llvm_eh_typeid_for = PointerWidth == 32 ?
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i32) :
+ CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for_i64);
// Exception object
llvm::Value *Exc = CGF.Builder.CreateCall(llvm_eh_exception, "exc");
const ObjCInterfaceType *IT =
PT->getPointeeType()->getAsObjCInterfaceType();
assert(IT && "Invalid @catch type.");
- CGF.ErrorUnsupported(&S, "@catch block with non-id argument statement");
- // FIXME: This should be the Class for the corresponding interface
- llvm::Value *EHType = NULLPtr;
+ llvm::Value *EHType =
+ MakeConstantString(IT->getDecl()->getNameAsString());
ESelArgs.push_back(EHType);
}
}
}
// Find which handler was matched.
- llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector_i64,
+ llvm::Value *ESelector = CGF.Builder.CreateCall(llvm_eh_selector,
ESelArgs.begin(), ESelArgs.end(), "selector");
for (unsigned i = 0, e = Handlers.size(); i != e; ++i) {
// to Match if it does, or to the next BB if it doesn't.
llvm::BasicBlock *Match = CGF.createBasicBlock("match");
Next = CGF.createBasicBlock("catch.next");
- llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for_i64,
+ llvm::Value *Id = CGF.Builder.CreateCall(llvm_eh_typeid_for,
CGF.Builder.CreateBitCast(ESelArgs[i+2], PtrTy));
CGF.Builder.CreateCondBr(CGF.Builder.CreateICmpEQ(ESelector, Id), Match,
Next);
}
if (CatchBody) {
- //FIXME: Do we need to reset the invoke destination here? Exceptions in
- //@catch {} blocks should unwind higher up.
-
- //FIXME: This may not be right. The exception object is returned in
- //__builtin_eh_return_data_regno(0), but I am not sure how to get at
- //this in LLVM
llvm::Value *ExcObject = CGF.Builder.CreateBitCast(Exc,
CGF.ConvertType(CatchParam->getType()));