summaryrefslogtreecommitdiff
path: root/bindgen/codegen/mod.rs
diff options
context:
space:
mode:
authorChristian Poveda Ruiz <31802960+pvdrz@users.noreply.github.com>2022-11-02 15:30:34 -0500
committerGitHub <noreply@github.com>2022-11-02 15:30:34 -0500
commit9c32b460481903d90c6ac5df277bfa853a0558d8 (patch)
tree6ee9ed2f853a78942314fb71df3868b89125cc86 /bindgen/codegen/mod.rs
parenta673a6bc9b83675a7468379e79dcf5d5659c4623 (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.rs46
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