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.
This commit is contained in:
parent
ccadbd3b7c
commit
297ac739d8
2 changed files with 25 additions and 13 deletions
|
@ -86,7 +86,7 @@ use syntax::parse::token;
|
||||||
use syntax::parse::token::{special_idents};
|
use syntax::parse::token::{special_idents};
|
||||||
use syntax::print::pprust::stmt_to_str;
|
use syntax::print::pprust::stmt_to_str;
|
||||||
use syntax::{ast, ast_util, codemap, ast_map};
|
use syntax::{ast, ast_util, codemap, ast_map};
|
||||||
use syntax::abi::{X86, X86_64, Arm, Mips};
|
use syntax::abi::{X86, X86_64, Arm, Mips, Rust, RustIntrinsic};
|
||||||
use syntax::visit;
|
use syntax::visit;
|
||||||
use syntax::visit::Visitor;
|
use syntax::visit::Visitor;
|
||||||
|
|
||||||
|
@ -813,15 +813,28 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t)
|
||||||
-> ValueRef {
|
-> ValueRef {
|
||||||
let name = csearch::get_symbol(ccx.sess.cstore, did);
|
let name = csearch::get_symbol(ccx.sess.cstore, did);
|
||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_bare_fn(_) | ty::ty_closure(_) => {
|
ty::ty_bare_fn(ref fn_ty) => {
|
||||||
let llty = type_of_fn_from_ty(ccx, t);
|
// Currently llvm_calling_convention triggers unimpl/bug on
|
||||||
return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
|
// Rust/RustIntrinsic, so those two are handled specially here.
|
||||||
lib::llvm::CCallConv, llty);
|
let cconv = match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
|
||||||
}
|
Some(Rust) | Some(RustIntrinsic) => lib::llvm::CCallConv,
|
||||||
_ => {
|
Some(*) | None => {
|
||||||
let llty = type_of(ccx, t);
|
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
|
||||||
return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
|
c.unwrap_or(lib::llvm::CCallConv)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
let llty = type_of_fn_from_ty(ccx, t);
|
||||||
|
return get_extern_fn(&mut ccx.externs, ccx.llmod, name, cconv, llty);
|
||||||
|
}
|
||||||
|
ty::ty_closure(_) => {
|
||||||
|
let llty = type_of_fn_from_ty(ccx, t);
|
||||||
|
return get_extern_fn(&mut ccx.externs, ccx.llmod, name,
|
||||||
|
lib::llvm::CCallConv, llty);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let llty = type_of(ccx, t);
|
||||||
|
return get_extern_const(&mut ccx.externs, ccx.llmod, name, llty);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,9 +74,8 @@ struct LlvmSignature {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Calls to external functions
|
// Calls to external functions
|
||||||
|
|
||||||
fn llvm_calling_convention(ccx: @mut CrateContext,
|
pub fn llvm_calling_convention(ccx: &mut CrateContext,
|
||||||
abis: AbiSet)
|
abis: AbiSet) -> Option<CallConv> {
|
||||||
-> Option<CallConv> {
|
|
||||||
let arch = ccx.sess.targ_cfg.arch;
|
let arch = ccx.sess.targ_cfg.arch;
|
||||||
abis.for_arch(arch).map(|abi| {
|
abis.for_arch(arch).map(|abi| {
|
||||||
match *abi {
|
match *abi {
|
||||||
|
|
Loading…
Add table
Reference in a new issue