- // Many different ways to call a function handled here
- if let &Some(cleanup) = cleanup {
- let ret_bcx = if let Some((_, target)) = *destination {
- self.blocks[target]
- } else {
- self.unreachable_block()
- };
- let invokeret = bcx.invoke(fn_ptr,
- &llargs,
- ret_bcx,
- llblock(self, cleanup),
- cleanup_bundle);
- fn_ty.apply_attrs_callsite(invokeret);
-
- if let Some((_, target)) = *destination {
- let ret_bcx = self.get_builder(target);
- self.set_debug_loc(&ret_bcx, terminator.source_info);
- let op = OperandRef {
- val: Immediate(invokeret),
- ty: sig.output(),
- };
- self.store_return(&ret_bcx, ret_dest, &fn_ty.ret, op);
- }
- } else {
- let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle);
- fn_ty.apply_attrs_callsite(llret);
- if let Some((_, target)) = *destination {
- let op = OperandRef {
- val: Immediate(llret),
- ty: sig.output(),
- };
- self.store_return(&bcx, ret_dest, &fn_ty.ret, op);
- funclet_br(self, bcx, target);
- } else {
- bcx.unreachable();
- }
- }
+ do_call(self, bcx, fn_ty, fn_ptr, &llargs,
+ destination.as_ref().map(|&(_, target)| (ret_dest, sig.output(), target)),
+ cleanup);