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],
|
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); }
|
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) {
|
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::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect};
|
||||||
use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
|
use lib::llvm::{Opcode, IntPredicate, RealPredicate, False};
|
||||||
use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
|
use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef};
|
||||||
|
use lib::llvm::{StructRetAttribute};
|
||||||
use middle::trans::base;
|
use middle::trans::base;
|
||||||
use middle::trans::common::*;
|
use middle::trans::common::*;
|
||||||
use middle::trans::machine::llalign_of_min;
|
use middle::trans::machine::llalign_of_min;
|
||||||
|
@ -778,14 +779,9 @@ impl Builder {
|
||||||
|
|
||||||
pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
|
pub fn call(&self, llfn: ValueRef, args: &[ValueRef]) -> ValueRef {
|
||||||
self.count_insn("call");
|
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| {
|
do args.as_imm_buf |ptr, len| {
|
||||||
unsafe {
|
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],
|
pub fn call_with_conv(&self, llfn: ValueRef, args: &[ValueRef],
|
||||||
conv: CallConv) -> ValueRef {
|
conv: CallConv, sret: bool) -> ValueRef {
|
||||||
self.count_insn("callwithconv");
|
self.count_insn("callwithconv");
|
||||||
unsafe {
|
unsafe {
|
||||||
let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
|
let v = llvm::LLVMBuildCall(self.llbuilder, llfn, vec::raw::to_ptr(args),
|
||||||
args.len() as c_uint, noname());
|
args.len() as c_uint, noname());
|
||||||
lib::llvm::SetInstructionCallConv(v, conv);
|
lib::llvm::SetInstructionCallConv(v, conv);
|
||||||
|
if sret {
|
||||||
|
let return_slot = 1;
|
||||||
|
llvm::LLVMAddInstrAttribute(v, return_slot, StructRetAttribute as c_uint);
|
||||||
|
}
|
||||||
v
|
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,
|
// If the function we just called does not use an outpointer,
|
||||||
// store the result into the rust outpointer. Cast the outpointer
|
// store the result into the rust outpointer. Cast the outpointer
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue