diff --git a/bindgen/clang.rs b/bindgen/clang.rs index 3438bfa2c4..4a4ed89d69 100644 --- a/bindgen/clang.rs +++ b/bindgen/clang.rs @@ -2297,6 +2297,15 @@ impl Drop for EvalResult { unsafe { clang_EvalResult_dispose(self.x) }; } } +/// ABI kinds as defined in +/// +#[derive(Debug, Eq, PartialEq, Copy, Clone)] +pub(crate) enum ABIKind { + /// All the regular targets like Linux, Mac, WASM, etc. implement the Itanium ABI + GenericItanium, + /// The ABI used when compiling for the MSVC target + Microsoft, +} /// Target information obtained from libclang. #[derive(Debug)] @@ -2305,6 +2314,8 @@ pub(crate) struct TargetInfo { pub(crate) triple: String, /// The width of the pointer _in bits_. pub(crate) pointer_width: usize, + /// The ABI of the target + pub(crate) abi: ABIKind, } impl TargetInfo { @@ -2320,9 +2331,17 @@ impl TargetInfo { } assert!(pointer_width > 0); assert_eq!(pointer_width % 8, 0); + + let abi = if triple.contains("msvc") { + ABIKind::Microsoft + } else { + ABIKind::GenericItanium + }; + TargetInfo { triple, pointer_width: pointer_width as usize, + abi, } } } diff --git a/bindgen/ir/context.rs b/bindgen/ir/context.rs index 11048b70c8..517d3365b6 100644 --- a/bindgen/ir/context.rs +++ b/bindgen/ir/context.rs @@ -19,7 +19,7 @@ use super::module::{Module, ModuleKind}; use super::template::{TemplateInstantiation, TemplateParameters}; use super::traversal::{self, Edge, ItemTraversal}; use super::ty::{FloatKind, Type, TypeKind}; -use crate::clang::{self, Cursor}; +use crate::clang::{self, ABIKind, Cursor}; use crate::codegen::CodegenError; use crate::BindgenOptions; use crate::{Entry, HashMap, HashSet}; @@ -626,6 +626,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.target_info.pointer_width / 8 } + /// Returns the ABI, which is mostly useful for determining the mangling kind. + pub(crate) fn abi_kind(&self) -> ABIKind { + self.target_info.abi + } + /// Get the stack of partially parsed types that we are in the middle of /// parsing. pub(crate) fn currently_parsed_types(&self) -> &[PartialType] { diff --git a/bindgen/ir/function.rs b/bindgen/ir/function.rs index 6342758f9f..6679a3d509 100644 --- a/bindgen/ir/function.rs +++ b/bindgen/ir/function.rs @@ -7,7 +7,7 @@ use super::item::Item; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::TypeKind; use crate::callbacks::{ItemInfo, ItemKind}; -use crate::clang::{self, Attribute}; +use crate::clang::{self, ABIKind, Attribute}; use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; use clang_sys::{self, CXCallingConv}; @@ -324,11 +324,12 @@ pub(crate) fn cursor_mangling( return None; } + let is_itanium_abi = ctx.abi_kind() == ABIKind::GenericItanium; let is_destructor = cursor.kind() == clang_sys::CXCursor_Destructor; if let Ok(mut manglings) = cursor.cxx_manglings() { while let Some(m) = manglings.pop() { // Only generate the destructor group 1, see below. - if is_destructor && !m.ends_with("D1Ev") { + if is_itanium_abi && is_destructor && !m.ends_with("D1Ev") { continue; } @@ -341,7 +342,7 @@ pub(crate) fn cursor_mangling( return None; } - if is_destructor { + if is_itanium_abi && is_destructor { // With old (3.8-) libclang versions, and the Itanium ABI, clang returns // the "destructor group 0" symbol, which means that it'll try to free // memory, which definitely isn't what we want.