diff options
author | Christian Poveda Ruiz <31802960+pvdrz@users.noreply.github.com> | 2022-11-02 15:30:34 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-02 15:30:34 -0500 |
commit | 9c32b460481903d90c6ac5df277bfa853a0558d8 (patch) | |
tree | 6ee9ed2f853a78942314fb71df3868b89125cc86 /bindgen/codegen/mod.rs | |
parent | a673a6bc9b83675a7468379e79dcf5d5659c4623 (diff) |
Add the `--override-abi` option (#2329)
* Add the `--override-abi` option.
This option can be used from the CLI with the <abi>:<regex> syntax and
it overrides the ABI of a function if it matches <regex>.
Fixes #2257
Diffstat (limited to 'bindgen/codegen/mod.rs')
-rw-r--r-- | bindgen/codegen/mod.rs | 46 |
1 files changed, 28 insertions, 18 deletions
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index a59265ab..4e90102d 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -32,7 +32,9 @@ use crate::ir::derive::{ }; use crate::ir::dot; use crate::ir::enum_ty::{Enum, EnumVariant, EnumVariantValue}; -use crate::ir::function::{Abi, Function, FunctionKind, FunctionSig, Linkage}; +use crate::ir::function::{ + Abi, ClangAbi, Function, FunctionKind, FunctionSig, Linkage, +}; use crate::ir::int::IntKind; use crate::ir::item::{IsOpaque, Item, ItemCanonicalName, ItemCanonicalPath}; use crate::ir::item_kind::ItemKind; @@ -2474,9 +2476,13 @@ impl MethodCodegen for Method { _ => panic!("How in the world?"), }; - let supported_abi = match signature.abi() { - Abi::ThisCall => ctx.options().rust_features().thiscall_abi, - Abi::Vectorcall => ctx.options().rust_features().vectorcall_abi, + let supported_abi = match signature.abi(ctx, Some(&*name)) { + ClangAbi::Known(Abi::ThisCall) => { + ctx.options().rust_features().thiscall_abi + } + ClangAbi::Known(Abi::Vectorcall) => { + ctx.options().rust_features().vectorcall_abi + } _ => true, }; @@ -3988,14 +3994,16 @@ impl TryToRustTy for FunctionSig { // TODO: we might want to consider ignoring the reference return value. let ret = utils::fnsig_return_ty(ctx, self); let arguments = utils::fnsig_arguments(ctx, self); - let abi = self.abi(); + let abi = self.abi(ctx, None); match abi { - Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => { + ClangAbi::Known(Abi::ThisCall) + if !ctx.options().rust_features().thiscall_abi => + { warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target"); Ok(proc_macro2::TokenStream::new()) } - Abi::Vectorcall + ClangAbi::Known(Abi::Vectorcall) if !ctx.options().rust_features().vectorcall_abi => { warn!("Skipping function with vectorcall ABI that isn't supported by the configured Rust target"); @@ -4099,22 +4107,24 @@ impl CodeGenerator for Function { attributes.push(attributes::doc(comment)); } - let abi = match signature.abi() { - Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => { + let abi = match signature.abi(ctx, Some(name)) { + ClangAbi::Known(Abi::ThisCall) + if !ctx.options().rust_features().thiscall_abi => + { warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target"); return None; } - Abi::Vectorcall + ClangAbi::Known(Abi::Vectorcall) if !ctx.options().rust_features().vectorcall_abi => { warn!("Skipping function with vectorcall ABI that isn't supported by the configured Rust target"); return None; } - Abi::Win64 if signature.is_variadic() => { + ClangAbi::Known(Abi::Win64) if signature.is_variadic() => { warn!("Skipping variadic function with Win64 ABI that isn't supported"); return None; } - Abi::Unknown(unknown_abi) => { + ClangAbi::Unknown(unknown_abi) => { panic!( "Invalid or unknown abi {:?} for function {:?} ({:?})", unknown_abi, canonical_name, self @@ -4512,7 +4522,7 @@ pub(crate) fn codegen( pub mod utils { use super::{error, ToRustTyOrOpaque}; use crate::ir::context::BindgenContext; - use crate::ir::function::{Abi, FunctionSig}; + use crate::ir::function::{Abi, ClangAbi, FunctionSig}; use crate::ir::item::{Item, ItemCanonicalPath}; use crate::ir::ty::TypeKind; use proc_macro2; @@ -4973,10 +4983,10 @@ pub mod utils { // Returns true if `canonical_name` will end up as `mangled_name` at the // machine code level, i.e. after LLVM has applied any target specific // mangling. - pub fn names_will_be_identical_after_mangling( + pub(crate) fn names_will_be_identical_after_mangling( canonical_name: &str, mangled_name: &str, - call_conv: Option<Abi>, + call_conv: Option<ClangAbi>, ) -> bool { // If the mangled name and the canonical name are the same then no // mangling can have happened between the two versions. @@ -4989,13 +4999,13 @@ pub mod utils { let mangled_name = mangled_name.as_bytes(); let (mangling_prefix, expect_suffix) = match call_conv { - Some(Abi::C) | + Some(ClangAbi::Known(Abi::C)) | // None is the case for global variables None => { (b'_', false) } - Some(Abi::Stdcall) => (b'_', true), - Some(Abi::Fastcall) => (b'@', true), + Some(ClangAbi::Known(Abi::Stdcall)) => (b'_', true), + Some(ClangAbi::Known(Abi::Fastcall)) => (b'@', true), // This is something we don't recognize, stay on the safe side // by emitting the `#[link_name]` attribute |