diff --git a/bindgen-tests/tests/expectations/tests/char16_t.rs b/bindgen-tests/tests/expectations/tests/char16_t.rs new file mode 100644 index 0000000000..82d30fe517 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/char16_t.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[repr(transparent)] +pub struct bindgen_cchar16_t(u16); +unsafe extern "C" { + #[link_name = "\u{1}_Z16receive_char16_tDs"] + pub fn receive_char16_t(input: bindgen_cchar16_t); +} diff --git a/bindgen-tests/tests/headers/char16_t.hpp b/bindgen-tests/tests/headers/char16_t.hpp new file mode 100644 index 0000000000..35e1f16dd3 --- /dev/null +++ b/bindgen-tests/tests/headers/char16_t.hpp @@ -0,0 +1,4 @@ +// bindgen-flags: --use-distinct-char16-t --raw-line '#[repr(transparent)] pub struct bindgen_cchar16_t(u16);' -- -x c++ -std=c++14 + +void receive_char16_t(char16_t input) { +} diff --git a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs index 91ed5c2ebc..251eeb0922 100644 --- a/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs +++ b/bindgen-tests/tests/parse_callbacks/item_discovery_callback/mod.rs @@ -140,7 +140,9 @@ fn compare_item_info( expected, generated, ), - DiscoveredItem::Enum { .. } => compare_enum_info(expected_item, generated_item), + DiscoveredItem::Enum { .. } => { + compare_enum_info(expected_item, generated_item) + } // DiscoveredItem::Mod { final_name } => todo!(), // DiscoveredItem::Function { final_name } => todo!(), // DiscoveredItem::Method { final_name, parent } => todo!(), @@ -222,7 +224,6 @@ pub fn compare_union_info( } } - pub fn compare_enum_info( expected_item: &DiscoveredItem, generated_item: &DiscoveredItem, diff --git a/bindgen/codegen/helpers.rs b/bindgen/codegen/helpers.rs index eec71de356..0582d0b63d 100644 --- a/bindgen/codegen/helpers.rs +++ b/bindgen/codegen/helpers.rs @@ -200,7 +200,12 @@ pub(crate) mod ast_ty { match ik { IntKind::Bool => syn::parse_quote! { bool }, IntKind::Char { .. } => raw_type(ctx, "c_char"), - IntKind::Char16 => raw_type(ctx, "c_char16_t"), + // The following is used only when an unusual command-line + // argument is used. bindgen_cchar16_t is not a real type; + // but this allows downstream postprocessors to distinguish + // this case and do something special for C++ bindings + // containing char16_t. + IntKind::Char16 => syn::parse_quote! { bindgen_cchar16_t }, IntKind::SChar => raw_type(ctx, "c_schar"), IntKind::UChar => raw_type(ctx, "c_uchar"), IntKind::Short => raw_type(ctx, "c_short"), diff --git a/bindgen/ir/function.rs b/bindgen/ir/function.rs index 1ce59d199b..ef798fdd69 100644 --- a/bindgen/ir/function.rs +++ b/bindgen/ir/function.rs @@ -935,7 +935,7 @@ impl ClangSubItemParser for Function { Some(SpecialMemberKind::CopyConstructor) } else if cursor.is_move_constructor() { Some(SpecialMemberKind::MoveConstructor) - } else if cursor.kind() == clang_sys::CXCursor_Destructor { + } else if cursor.kind() == CXCursor_Destructor { Some(SpecialMemberKind::Destructor) } else { None diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs index d774adcf5c..cda66e0ff3 100644 --- a/bindgen/options/mod.rs +++ b/bindgen/options/mod.rs @@ -182,19 +182,6 @@ options! { as_args: "--represent-cxx-operators", }, - /// Whether we should distinguish between 'char16_t' and 'u16' - use_distinct_char16_t: bool { - methods: { - /// If this is true, denote 'char16_t' as a separate type from 'u16' - /// Disabled by default. - pub fn use_distinct_char16_t(mut self, doit: bool) -> Builder { - self.options.use_distinct_char16_t = doit; - self - } - }, - as_args: "--use-distinct-char16-t", - }, - /// Use a newtype wrapper to clearly denote "opaque" types; that is, /// types where bindgen has generated a type matching the size and /// alignment of the C++ type but without any knowledge of what's @@ -267,6 +254,27 @@ options! { as_args: "--use-unused-template-param-newtype-wrapper", }, + /// Whether we should distinguish between 'char16_t' and 'u16'. + /// As standard, bindgen represents `char16_t` as `u16`. + /// Rust does not have a `std::os::raw::c_char16_t` type, and thus + /// we can't use a built-in Rust type in the generated bindings. + /// But for some uses of bindgen, especially when downstream + /// post-processing occurs, it's important to distinguish `char16_t` + /// from normal `uint16_t`. When this option is enabled, bindgen + /// generates a fake type called `bindgen_cchar16_t`. Downstream + /// code post-processors should arrange to replace this with a + /// real type. + use_distinct_char16_t: bool { + methods: { + /// If this is true, denote 'char16_t' as a separate type from 'u16' + /// Disabled by default. + pub fn use_distinct_char16_t(mut self, doit: bool) -> Builder { + self.options.use_distinct_char16_t = doit; + self + } + }, + as_args: "--use-distinct-char16-t", + }, /// Types that have been blocklisted and should not appear anywhere in the generated code. blocklisted_types: RegexSet {