Skip to content

Commit 297ac73

Browse files
committed
When declaring extern fns from external crates, use the correct abi
Beforehand it was assumed that the standard cdecl abi was used for all extern fns of extern crates, but this reads the abi of the extern fn type and declares the function in the local crate with the appropriate type.
1 parent ccadbd3 commit 297ac73

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

src/librustc/middle/trans/base.rs

+23-10
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ use syntax::parse::token;
8686
use syntax::parse::token::{special_idents};
8787
use syntax::print::pprust::stmt_to_str;
8888
use syntax::{ast, ast_util, codemap, ast_map};
89-
use syntax::abi::{X86, X86_64, Arm, Mips};
89+
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
9090
use syntax::visit;
9191
use syntax::visit::Visitor;
9292

@@ -813,15 +813,28 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
813813
-> ValueRef {
814814
let name = csearch::get_symbol(ccx.sess.cstore, did);
815815
match ty::get(t).sty {
816-
ty::ty_bare_fn(_) | ty::ty_closure(_) => {
817-
let llty = type_of_fn_from_ty(ccx, t);
818-
return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
819-
lib::llvm::CCallConv, llty);
820-
}
821-
_ => {
822-
let llty = type_of(ccx, t);
823-
return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
824-
}
816+
ty::ty_bare_fn(ref fn_ty) => {
817+
// Currently llvm_calling_convention triggers unimpl/bug on
818+
// Rust/RustIntrinsic, so those two are handled specially here.
819+
let cconv = match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
820+
Some(Rust) | Some(RustIntrinsic) => lib::llvm::CCallConv,
821+
Some(*) | None => {
822+
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
823+
c.unwrap_or(lib::llvm::CCallConv)
824+
}
825+
};
826+
let llty = type_of_fn_from_ty(ccx, t);
827+
return get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty);
828+
}
829+
ty::ty_closure(_) => {
830+
let llty = type_of_fn_from_ty(ccx, t);
831+
return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
832+
lib::llvm::CCallConv, llty);
833+
}
834+
_ => {
835+
let llty = type_of(ccx, t);
836+
return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
837+
}
825838
};
826839
}
827840

src/librustc/middle/trans/foreign.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,8 @@ struct LlvmSignature {
7474
///////////////////////////////////////////////////////////////////////////
7575
// Calls to external functions
7676

77-
fn llvm_calling_convention(ccx: @mut CrateContext,
78-
abis: AbiSet)
79-
-> Option<CallConv> {
77+
pub fn llvm_calling_convention(ccx: &mut CrateContext,
78+
abis: AbiSet) -> Option<CallConv> {
8079
let arch = ccx.sess.targ_cfg.arch;
8180
abis.for_arch(arch).map(|abi| {
8281
match *abi {

0 commit comments

Comments
 (0)