auto merge of #9158 : thestinger/rust/extern, r=alexcrichton
Since function pointers do not carry along the function attributes with them in the type, this needs to be set on the call instruction itself. Closes #9152
This commit is contained in:
commit
150b4ffccc
3 changed files with 10 additions and 10 deletions
|
@ -655,9 +655,9 @@ pub fn FastCall(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
|
|||
}
|
||||
|
||||
pub fn CallWithConv(cx: @mut Block, Fn: ValueRef, Args: &[ValueRef],
|
||||
Conv: CallConv) -> ValueRef {
|
||||
Conv: CallConv, sret: bool) -> ValueRef {
|
||||
if cx.unreachable { return _UndefReturn(cx, Fn); }
|
||||
B(cx).call_with_conv(Fn, Args, Conv)
|
||||
B(cx).call_with_conv(Fn, Args, Conv, sret)
|
||||
}
|
||||
|
||||
pub fn AtomicFence(cx: @mut Block, order: AtomicOrdering) {
|
||||
|
|
|
@ -13,6 +13,7 @@ use lib::llvm::llvm;
|
|||
use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
|
||||
use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
|
||||
use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
|
||||
use lib::llvm::{StructRetAttribute};
|
||||
use middle::trans::base;
|
||||
use middle::trans::common::*;
|
||||
use middle::trans::machine::llalign_of_min;
|
||||
|
@ -778,14 +779,9 @@ impl Builder {
|
|||
|
||||
pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
|
||||
self.count_insn("call");
|
||||
|
||||
debug!("Call(llfn=%s, args=%?)",
|
||||
self.ccx.tn.val_to_str(llfn),
|
||||
args.map(|arg| self.ccx.tn.val_to_str(*arg)));
|
||||
|
||||
do args.as_imm_buf |ptr, len| {
|
||||
unsafe {
|
||||
llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname())
|
||||
llvm::LLVMBuildCall(self.llbuilder, llfn, ptr, len as c_uint, noname())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -801,12 +797,16 @@ impl Builder {
|
|||
}
|
||||
|
||||
pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
|
||||
conv: CallConv) -> ValueRef {
|
||||
conv: CallConv, sret: bool) -> ValueRef {
|
||||
self.count_insn("callwithconv");
|
||||
unsafe {
|
||||
let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
|
||||
args.len() as c_uint, noname());
|
||||
lib::llvm::SetInstructionCallConv(v, conv);
|
||||
if sret {
|
||||
let return_slot = 1;
|
||||
llvm::LLVMAddInstrAttribute(v, return_slot, StructRetAttribute as c_uint);
|
||||
}
|
||||
v
|
||||
}
|
||||
}
|
||||
|
|
|
@ -266,7 +266,7 @@ pub fn trans_native_call(bcx: @mut Block,
|
|||
}
|
||||
};
|
||||
|
||||
let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc);
|
||||
let llforeign_retval = CallWithConv(bcx, llfn, llargs_foreign, cc, fn_type.sret);
|
||||
|
||||
// If the function we just called does not use an outpointer,
|
||||
// store the result into the rust outpointer. Cast the outpointer
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue