133d722a9Sopenharmony_ciuse crate::syntax::atom::Atom::*; 233d722a9Sopenharmony_ciuse crate::syntax::attrs::{self, OtherAttrs}; 333d722a9Sopenharmony_ciuse crate::syntax::cfg::CfgExpr; 433d722a9Sopenharmony_ciuse crate::syntax::file::Module; 533d722a9Sopenharmony_ciuse crate::syntax::instantiate::{ImplKey, NamedImplKey}; 633d722a9Sopenharmony_ciuse crate::syntax::qualified::QualifiedName; 733d722a9Sopenharmony_ciuse crate::syntax::report::Errors; 833d722a9Sopenharmony_ciuse crate::syntax::symbol::Symbol; 933d722a9Sopenharmony_ciuse crate::syntax::{ 1033d722a9Sopenharmony_ci self, check, mangle, Api, Doc, Enum, ExternFn, ExternType, Impl, Lifetimes, Pair, Signature, 1133d722a9Sopenharmony_ci Struct, Trait, Type, TypeAlias, Types, 1233d722a9Sopenharmony_ci}; 1333d722a9Sopenharmony_ciuse crate::type_id::Crate; 1433d722a9Sopenharmony_ciuse crate::{derive, generics}; 1533d722a9Sopenharmony_ciuse proc_macro2::{Ident, Span, TokenStream}; 1633d722a9Sopenharmony_ciuse quote::{format_ident, quote, quote_spanned, ToTokens}; 1733d722a9Sopenharmony_ciuse std::mem; 1833d722a9Sopenharmony_ciuse syn::{parse_quote, punctuated, Generics, Lifetime, Result, Token}; 1933d722a9Sopenharmony_ci 2033d722a9Sopenharmony_cipub fn bridge(mut ffi: Module) -> Result<TokenStream> { 2133d722a9Sopenharmony_ci let ref mut errors = Errors::new(); 2233d722a9Sopenharmony_ci 2333d722a9Sopenharmony_ci let mut cfg = CfgExpr::Unconditional; 2433d722a9Sopenharmony_ci let mut doc = Doc::new(); 2533d722a9Sopenharmony_ci let attrs = attrs::parse( 2633d722a9Sopenharmony_ci errors, 2733d722a9Sopenharmony_ci mem::take(&mut ffi.attrs), 2833d722a9Sopenharmony_ci attrs::Parser { 2933d722a9Sopenharmony_ci cfg: Some(&mut cfg), 3033d722a9Sopenharmony_ci doc: Some(&mut doc), 3133d722a9Sopenharmony_ci ..Default::default() 3233d722a9Sopenharmony_ci }, 3333d722a9Sopenharmony_ci ); 3433d722a9Sopenharmony_ci 3533d722a9Sopenharmony_ci let content = mem::take(&mut ffi.content); 3633d722a9Sopenharmony_ci let trusted = ffi.unsafety.is_some(); 3733d722a9Sopenharmony_ci let namespace = &ffi.namespace; 3833d722a9Sopenharmony_ci let ref mut apis = syntax::parse_items(errors, content, trusted, namespace); 3933d722a9Sopenharmony_ci #[cfg(feature = "experimental-enum-variants-from-header")] 4033d722a9Sopenharmony_ci crate::load::load(errors, apis); 4133d722a9Sopenharmony_ci let ref types = Types::collect(errors, apis); 4233d722a9Sopenharmony_ci errors.propagate()?; 4333d722a9Sopenharmony_ci 4433d722a9Sopenharmony_ci let generator = check::Generator::Macro; 4533d722a9Sopenharmony_ci check::typecheck(errors, apis, types, generator); 4633d722a9Sopenharmony_ci errors.propagate()?; 4733d722a9Sopenharmony_ci 4833d722a9Sopenharmony_ci Ok(expand(ffi, doc, attrs, apis, types)) 4933d722a9Sopenharmony_ci} 5033d722a9Sopenharmony_ci 5133d722a9Sopenharmony_cifn expand(ffi: Module, doc: Doc, attrs: OtherAttrs, apis: &[Api], types: &Types) -> TokenStream { 5233d722a9Sopenharmony_ci let mut expanded = TokenStream::new(); 5333d722a9Sopenharmony_ci let mut hidden = TokenStream::new(); 5433d722a9Sopenharmony_ci let mut forbid = TokenStream::new(); 5533d722a9Sopenharmony_ci 5633d722a9Sopenharmony_ci for api in apis { 5733d722a9Sopenharmony_ci if let Api::RustType(ety) = api { 5833d722a9Sopenharmony_ci expanded.extend(expand_rust_type_import(ety)); 5933d722a9Sopenharmony_ci hidden.extend(expand_rust_type_assert_unpin(ety, types)); 6033d722a9Sopenharmony_ci } 6133d722a9Sopenharmony_ci } 6233d722a9Sopenharmony_ci 6333d722a9Sopenharmony_ci for api in apis { 6433d722a9Sopenharmony_ci match api { 6533d722a9Sopenharmony_ci Api::Include(_) | Api::Impl(_) => {} 6633d722a9Sopenharmony_ci Api::Struct(strct) => { 6733d722a9Sopenharmony_ci expanded.extend(expand_struct(strct)); 6833d722a9Sopenharmony_ci hidden.extend(expand_struct_operators(strct)); 6933d722a9Sopenharmony_ci forbid.extend(expand_struct_forbid_drop(strct)); 7033d722a9Sopenharmony_ci } 7133d722a9Sopenharmony_ci Api::Enum(enm) => expanded.extend(expand_enum(enm)), 7233d722a9Sopenharmony_ci Api::CxxType(ety) => { 7333d722a9Sopenharmony_ci let ident = &ety.name.rust; 7433d722a9Sopenharmony_ci if !types.structs.contains_key(ident) && !types.enums.contains_key(ident) { 7533d722a9Sopenharmony_ci expanded.extend(expand_cxx_type(ety)); 7633d722a9Sopenharmony_ci hidden.extend(expand_cxx_type_assert_pinned(ety, types)); 7733d722a9Sopenharmony_ci } 7833d722a9Sopenharmony_ci } 7933d722a9Sopenharmony_ci Api::CxxFunction(efn) => { 8033d722a9Sopenharmony_ci expanded.extend(expand_cxx_function_shim(efn, types)); 8133d722a9Sopenharmony_ci } 8233d722a9Sopenharmony_ci Api::RustType(ety) => { 8333d722a9Sopenharmony_ci expanded.extend(expand_rust_type_impl(ety)); 8433d722a9Sopenharmony_ci hidden.extend(expand_rust_type_layout(ety, types)); 8533d722a9Sopenharmony_ci } 8633d722a9Sopenharmony_ci Api::RustFunction(efn) => hidden.extend(expand_rust_function_shim(efn, types)), 8733d722a9Sopenharmony_ci Api::TypeAlias(alias) => { 8833d722a9Sopenharmony_ci expanded.extend(expand_type_alias(alias)); 8933d722a9Sopenharmony_ci hidden.extend(expand_type_alias_verify(alias, types)); 9033d722a9Sopenharmony_ci } 9133d722a9Sopenharmony_ci } 9233d722a9Sopenharmony_ci } 9333d722a9Sopenharmony_ci 9433d722a9Sopenharmony_ci for (impl_key, &explicit_impl) in &types.impls { 9533d722a9Sopenharmony_ci match *impl_key { 9633d722a9Sopenharmony_ci ImplKey::RustBox(ident) => { 9733d722a9Sopenharmony_ci hidden.extend(expand_rust_box(ident, types, explicit_impl)); 9833d722a9Sopenharmony_ci } 9933d722a9Sopenharmony_ci ImplKey::RustVec(ident) => { 10033d722a9Sopenharmony_ci hidden.extend(expand_rust_vec(ident, types, explicit_impl)); 10133d722a9Sopenharmony_ci } 10233d722a9Sopenharmony_ci ImplKey::UniquePtr(ident) => { 10333d722a9Sopenharmony_ci expanded.extend(expand_unique_ptr(ident, types, explicit_impl)); 10433d722a9Sopenharmony_ci } 10533d722a9Sopenharmony_ci ImplKey::SharedPtr(ident) => { 10633d722a9Sopenharmony_ci expanded.extend(expand_shared_ptr(ident, types, explicit_impl)); 10733d722a9Sopenharmony_ci } 10833d722a9Sopenharmony_ci ImplKey::WeakPtr(ident) => { 10933d722a9Sopenharmony_ci expanded.extend(expand_weak_ptr(ident, types, explicit_impl)); 11033d722a9Sopenharmony_ci } 11133d722a9Sopenharmony_ci ImplKey::CxxVector(ident) => { 11233d722a9Sopenharmony_ci expanded.extend(expand_cxx_vector(ident, explicit_impl, types)); 11333d722a9Sopenharmony_ci } 11433d722a9Sopenharmony_ci } 11533d722a9Sopenharmony_ci } 11633d722a9Sopenharmony_ci 11733d722a9Sopenharmony_ci if !forbid.is_empty() { 11833d722a9Sopenharmony_ci hidden.extend(expand_forbid(forbid)); 11933d722a9Sopenharmony_ci } 12033d722a9Sopenharmony_ci 12133d722a9Sopenharmony_ci // Work around https://github.com/rust-lang/rust/issues/67851. 12233d722a9Sopenharmony_ci if !hidden.is_empty() { 12333d722a9Sopenharmony_ci expanded.extend(quote! { 12433d722a9Sopenharmony_ci #[doc(hidden)] 12533d722a9Sopenharmony_ci const _: () = { 12633d722a9Sopenharmony_ci #hidden 12733d722a9Sopenharmony_ci }; 12833d722a9Sopenharmony_ci }); 12933d722a9Sopenharmony_ci } 13033d722a9Sopenharmony_ci 13133d722a9Sopenharmony_ci let vis = &ffi.vis; 13233d722a9Sopenharmony_ci let mod_token = &ffi.mod_token; 13333d722a9Sopenharmony_ci let ident = &ffi.ident; 13433d722a9Sopenharmony_ci let span = ffi.brace_token.span; 13533d722a9Sopenharmony_ci let expanded = quote_spanned!(span=> {#expanded}); 13633d722a9Sopenharmony_ci 13733d722a9Sopenharmony_ci quote! { 13833d722a9Sopenharmony_ci #doc 13933d722a9Sopenharmony_ci #attrs 14033d722a9Sopenharmony_ci #[deny(improper_ctypes, improper_ctypes_definitions)] 14133d722a9Sopenharmony_ci #[allow(clippy::unknown_clippy_lints)] 14233d722a9Sopenharmony_ci #[allow( 14333d722a9Sopenharmony_ci non_camel_case_types, 14433d722a9Sopenharmony_ci non_snake_case, 14533d722a9Sopenharmony_ci clippy::extra_unused_type_parameters, 14633d722a9Sopenharmony_ci clippy::ptr_as_ptr, 14733d722a9Sopenharmony_ci clippy::upper_case_acronyms, 14833d722a9Sopenharmony_ci clippy::use_self, 14933d722a9Sopenharmony_ci )] 15033d722a9Sopenharmony_ci #vis #mod_token #ident #expanded 15133d722a9Sopenharmony_ci } 15233d722a9Sopenharmony_ci} 15333d722a9Sopenharmony_ci 15433d722a9Sopenharmony_cifn expand_struct(strct: &Struct) -> TokenStream { 15533d722a9Sopenharmony_ci let ident = &strct.name.rust; 15633d722a9Sopenharmony_ci let doc = &strct.doc; 15733d722a9Sopenharmony_ci let attrs = &strct.attrs; 15833d722a9Sopenharmony_ci let generics = &strct.generics; 15933d722a9Sopenharmony_ci let type_id = type_id(&strct.name); 16033d722a9Sopenharmony_ci let fields = strct.fields.iter().map(|field| { 16133d722a9Sopenharmony_ci let doc = &field.doc; 16233d722a9Sopenharmony_ci let attrs = &field.attrs; 16333d722a9Sopenharmony_ci // This span on the pub makes "private type in public interface" errors 16433d722a9Sopenharmony_ci // appear in the right place. 16533d722a9Sopenharmony_ci let vis = field.visibility; 16633d722a9Sopenharmony_ci quote!(#doc #attrs #vis #field) 16733d722a9Sopenharmony_ci }); 16833d722a9Sopenharmony_ci let mut derives = None; 16933d722a9Sopenharmony_ci let derived_traits = derive::expand_struct(strct, &mut derives); 17033d722a9Sopenharmony_ci 17133d722a9Sopenharmony_ci let span = ident.span(); 17233d722a9Sopenharmony_ci let visibility = strct.visibility; 17333d722a9Sopenharmony_ci let struct_token = strct.struct_token; 17433d722a9Sopenharmony_ci let struct_def = quote_spanned! {span=> 17533d722a9Sopenharmony_ci #visibility #struct_token #ident #generics { 17633d722a9Sopenharmony_ci #(#fields,)* 17733d722a9Sopenharmony_ci } 17833d722a9Sopenharmony_ci }; 17933d722a9Sopenharmony_ci 18033d722a9Sopenharmony_ci quote! { 18133d722a9Sopenharmony_ci #doc 18233d722a9Sopenharmony_ci #derives 18333d722a9Sopenharmony_ci #attrs 18433d722a9Sopenharmony_ci #[repr(C)] 18533d722a9Sopenharmony_ci #struct_def 18633d722a9Sopenharmony_ci 18733d722a9Sopenharmony_ci unsafe impl #generics ::cxx::ExternType for #ident #generics { 18833d722a9Sopenharmony_ci #[allow(unused_attributes)] // incorrect lint 18933d722a9Sopenharmony_ci #[doc(hidden)] 19033d722a9Sopenharmony_ci type Id = #type_id; 19133d722a9Sopenharmony_ci type Kind = ::cxx::kind::Trivial; 19233d722a9Sopenharmony_ci } 19333d722a9Sopenharmony_ci 19433d722a9Sopenharmony_ci #derived_traits 19533d722a9Sopenharmony_ci } 19633d722a9Sopenharmony_ci} 19733d722a9Sopenharmony_ci 19833d722a9Sopenharmony_cifn expand_struct_operators(strct: &Struct) -> TokenStream { 19933d722a9Sopenharmony_ci let ident = &strct.name.rust; 20033d722a9Sopenharmony_ci let generics = &strct.generics; 20133d722a9Sopenharmony_ci let mut operators = TokenStream::new(); 20233d722a9Sopenharmony_ci 20333d722a9Sopenharmony_ci for derive in &strct.derives { 20433d722a9Sopenharmony_ci let span = derive.span; 20533d722a9Sopenharmony_ci match derive.what { 20633d722a9Sopenharmony_ci Trait::PartialEq => { 20733d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "eq"); 20833d722a9Sopenharmony_ci let local_name = format_ident!("__operator_eq_{}", strct.name.rust); 20933d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as PartialEq>::eq", strct.name.rust); 21033d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 21133d722a9Sopenharmony_ci #[doc(hidden)] 21233d722a9Sopenharmony_ci #[export_name = #link_name] 21333d722a9Sopenharmony_ci extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool { 21433d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 21533d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || *lhs == *rhs) 21633d722a9Sopenharmony_ci } 21733d722a9Sopenharmony_ci }); 21833d722a9Sopenharmony_ci 21933d722a9Sopenharmony_ci if !derive::contains(&strct.derives, Trait::Eq) { 22033d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "ne"); 22133d722a9Sopenharmony_ci let local_name = format_ident!("__operator_ne_{}", strct.name.rust); 22233d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as PartialEq>::ne", strct.name.rust); 22333d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 22433d722a9Sopenharmony_ci #[doc(hidden)] 22533d722a9Sopenharmony_ci #[export_name = #link_name] 22633d722a9Sopenharmony_ci extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool { 22733d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 22833d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || *lhs != *rhs) 22933d722a9Sopenharmony_ci } 23033d722a9Sopenharmony_ci }); 23133d722a9Sopenharmony_ci } 23233d722a9Sopenharmony_ci } 23333d722a9Sopenharmony_ci Trait::PartialOrd => { 23433d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "lt"); 23533d722a9Sopenharmony_ci let local_name = format_ident!("__operator_lt_{}", strct.name.rust); 23633d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as PartialOrd>::lt", strct.name.rust); 23733d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 23833d722a9Sopenharmony_ci #[doc(hidden)] 23933d722a9Sopenharmony_ci #[export_name = #link_name] 24033d722a9Sopenharmony_ci extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool { 24133d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 24233d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || *lhs < *rhs) 24333d722a9Sopenharmony_ci } 24433d722a9Sopenharmony_ci }); 24533d722a9Sopenharmony_ci 24633d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "le"); 24733d722a9Sopenharmony_ci let local_name = format_ident!("__operator_le_{}", strct.name.rust); 24833d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as PartialOrd>::le", strct.name.rust); 24933d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 25033d722a9Sopenharmony_ci #[doc(hidden)] 25133d722a9Sopenharmony_ci #[export_name = #link_name] 25233d722a9Sopenharmony_ci extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool { 25333d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 25433d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || *lhs <= *rhs) 25533d722a9Sopenharmony_ci } 25633d722a9Sopenharmony_ci }); 25733d722a9Sopenharmony_ci 25833d722a9Sopenharmony_ci if !derive::contains(&strct.derives, Trait::Ord) { 25933d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "gt"); 26033d722a9Sopenharmony_ci let local_name = format_ident!("__operator_gt_{}", strct.name.rust); 26133d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as PartialOrd>::gt", strct.name.rust); 26233d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 26333d722a9Sopenharmony_ci #[doc(hidden)] 26433d722a9Sopenharmony_ci #[export_name = #link_name] 26533d722a9Sopenharmony_ci extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool { 26633d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 26733d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || *lhs > *rhs) 26833d722a9Sopenharmony_ci } 26933d722a9Sopenharmony_ci }); 27033d722a9Sopenharmony_ci 27133d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "ge"); 27233d722a9Sopenharmony_ci let local_name = format_ident!("__operator_ge_{}", strct.name.rust); 27333d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as PartialOrd>::ge", strct.name.rust); 27433d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 27533d722a9Sopenharmony_ci #[doc(hidden)] 27633d722a9Sopenharmony_ci #[export_name = #link_name] 27733d722a9Sopenharmony_ci extern "C" fn #local_name #generics(lhs: &#ident #generics, rhs: &#ident #generics) -> bool { 27833d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 27933d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || *lhs >= *rhs) 28033d722a9Sopenharmony_ci } 28133d722a9Sopenharmony_ci }); 28233d722a9Sopenharmony_ci } 28333d722a9Sopenharmony_ci } 28433d722a9Sopenharmony_ci Trait::Hash => { 28533d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "hash"); 28633d722a9Sopenharmony_ci let local_name = format_ident!("__operator_hash_{}", strct.name.rust); 28733d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{} as Hash>::hash", strct.name.rust); 28833d722a9Sopenharmony_ci operators.extend(quote_spanned! {span=> 28933d722a9Sopenharmony_ci #[doc(hidden)] 29033d722a9Sopenharmony_ci #[export_name = #link_name] 29133d722a9Sopenharmony_ci #[allow(clippy::cast_possible_truncation)] 29233d722a9Sopenharmony_ci extern "C" fn #local_name #generics(this: &#ident #generics) -> usize { 29333d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_label); 29433d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || ::cxx::private::hash(this)) 29533d722a9Sopenharmony_ci } 29633d722a9Sopenharmony_ci }); 29733d722a9Sopenharmony_ci } 29833d722a9Sopenharmony_ci _ => {} 29933d722a9Sopenharmony_ci } 30033d722a9Sopenharmony_ci } 30133d722a9Sopenharmony_ci 30233d722a9Sopenharmony_ci operators 30333d722a9Sopenharmony_ci} 30433d722a9Sopenharmony_ci 30533d722a9Sopenharmony_cifn expand_struct_forbid_drop(strct: &Struct) -> TokenStream { 30633d722a9Sopenharmony_ci let ident = &strct.name.rust; 30733d722a9Sopenharmony_ci let generics = &strct.generics; 30833d722a9Sopenharmony_ci let span = ident.span(); 30933d722a9Sopenharmony_ci let impl_token = Token; 31033d722a9Sopenharmony_ci 31133d722a9Sopenharmony_ci quote_spanned! {span=> 31233d722a9Sopenharmony_ci #impl_token #generics self::Drop for super::#ident #generics {} 31333d722a9Sopenharmony_ci } 31433d722a9Sopenharmony_ci} 31533d722a9Sopenharmony_ci 31633d722a9Sopenharmony_cifn expand_enum(enm: &Enum) -> TokenStream { 31733d722a9Sopenharmony_ci let ident = &enm.name.rust; 31833d722a9Sopenharmony_ci let doc = &enm.doc; 31933d722a9Sopenharmony_ci let attrs = &enm.attrs; 32033d722a9Sopenharmony_ci let repr = &enm.repr; 32133d722a9Sopenharmony_ci let type_id = type_id(&enm.name); 32233d722a9Sopenharmony_ci let variants = enm.variants.iter().map(|variant| { 32333d722a9Sopenharmony_ci let doc = &variant.doc; 32433d722a9Sopenharmony_ci let attrs = &variant.attrs; 32533d722a9Sopenharmony_ci let variant_ident = &variant.name.rust; 32633d722a9Sopenharmony_ci let discriminant = &variant.discriminant; 32733d722a9Sopenharmony_ci let span = variant_ident.span(); 32833d722a9Sopenharmony_ci Some(quote_spanned! {span=> 32933d722a9Sopenharmony_ci #doc 33033d722a9Sopenharmony_ci #attrs 33133d722a9Sopenharmony_ci #[allow(dead_code)] 33233d722a9Sopenharmony_ci pub const #variant_ident: Self = #ident { repr: #discriminant }; 33333d722a9Sopenharmony_ci }) 33433d722a9Sopenharmony_ci }); 33533d722a9Sopenharmony_ci let mut derives = None; 33633d722a9Sopenharmony_ci let derived_traits = derive::expand_enum(enm, &mut derives); 33733d722a9Sopenharmony_ci 33833d722a9Sopenharmony_ci let span = ident.span(); 33933d722a9Sopenharmony_ci let visibility = enm.visibility; 34033d722a9Sopenharmony_ci let struct_token = Token; 34133d722a9Sopenharmony_ci let enum_repr = quote! { 34233d722a9Sopenharmony_ci #[allow(missing_docs)] 34333d722a9Sopenharmony_ci pub repr: #repr, 34433d722a9Sopenharmony_ci }; 34533d722a9Sopenharmony_ci let enum_def = quote_spanned! {span=> 34633d722a9Sopenharmony_ci #visibility #struct_token #ident { 34733d722a9Sopenharmony_ci #enum_repr 34833d722a9Sopenharmony_ci } 34933d722a9Sopenharmony_ci }; 35033d722a9Sopenharmony_ci 35133d722a9Sopenharmony_ci quote! { 35233d722a9Sopenharmony_ci #doc 35333d722a9Sopenharmony_ci #derives 35433d722a9Sopenharmony_ci #attrs 35533d722a9Sopenharmony_ci #[repr(transparent)] 35633d722a9Sopenharmony_ci #enum_def 35733d722a9Sopenharmony_ci 35833d722a9Sopenharmony_ci #[allow(non_upper_case_globals)] 35933d722a9Sopenharmony_ci impl #ident { 36033d722a9Sopenharmony_ci #(#variants)* 36133d722a9Sopenharmony_ci } 36233d722a9Sopenharmony_ci 36333d722a9Sopenharmony_ci unsafe impl ::cxx::ExternType for #ident { 36433d722a9Sopenharmony_ci #[allow(unused_attributes)] // incorrect lint 36533d722a9Sopenharmony_ci #[doc(hidden)] 36633d722a9Sopenharmony_ci type Id = #type_id; 36733d722a9Sopenharmony_ci type Kind = ::cxx::kind::Trivial; 36833d722a9Sopenharmony_ci } 36933d722a9Sopenharmony_ci 37033d722a9Sopenharmony_ci #derived_traits 37133d722a9Sopenharmony_ci } 37233d722a9Sopenharmony_ci} 37333d722a9Sopenharmony_ci 37433d722a9Sopenharmony_cifn expand_cxx_type(ety: &ExternType) -> TokenStream { 37533d722a9Sopenharmony_ci let ident = &ety.name.rust; 37633d722a9Sopenharmony_ci let doc = &ety.doc; 37733d722a9Sopenharmony_ci let attrs = &ety.attrs; 37833d722a9Sopenharmony_ci let generics = &ety.generics; 37933d722a9Sopenharmony_ci let type_id = type_id(&ety.name); 38033d722a9Sopenharmony_ci 38133d722a9Sopenharmony_ci let lifetime_fields = ety.generics.lifetimes.iter().map(|lifetime| { 38233d722a9Sopenharmony_ci let field = format_ident!("_lifetime_{}", lifetime.ident); 38333d722a9Sopenharmony_ci quote!(#field: ::cxx::core::marker::PhantomData<&#lifetime ()>) 38433d722a9Sopenharmony_ci }); 38533d722a9Sopenharmony_ci let repr_fields = quote! { 38633d722a9Sopenharmony_ci _private: ::cxx::private::Opaque, 38733d722a9Sopenharmony_ci #(#lifetime_fields,)* 38833d722a9Sopenharmony_ci }; 38933d722a9Sopenharmony_ci 39033d722a9Sopenharmony_ci let span = ident.span(); 39133d722a9Sopenharmony_ci let visibility = &ety.visibility; 39233d722a9Sopenharmony_ci let struct_token = Token; 39333d722a9Sopenharmony_ci let extern_type_def = quote_spanned! {span=> 39433d722a9Sopenharmony_ci #visibility #struct_token #ident #generics { 39533d722a9Sopenharmony_ci #repr_fields 39633d722a9Sopenharmony_ci } 39733d722a9Sopenharmony_ci }; 39833d722a9Sopenharmony_ci 39933d722a9Sopenharmony_ci quote! { 40033d722a9Sopenharmony_ci #doc 40133d722a9Sopenharmony_ci #attrs 40233d722a9Sopenharmony_ci #[repr(C)] 40333d722a9Sopenharmony_ci #extern_type_def 40433d722a9Sopenharmony_ci 40533d722a9Sopenharmony_ci unsafe impl #generics ::cxx::ExternType for #ident #generics { 40633d722a9Sopenharmony_ci #[allow(unused_attributes)] // incorrect lint 40733d722a9Sopenharmony_ci #[doc(hidden)] 40833d722a9Sopenharmony_ci type Id = #type_id; 40933d722a9Sopenharmony_ci type Kind = ::cxx::kind::Opaque; 41033d722a9Sopenharmony_ci } 41133d722a9Sopenharmony_ci } 41233d722a9Sopenharmony_ci} 41333d722a9Sopenharmony_ci 41433d722a9Sopenharmony_cifn expand_cxx_type_assert_pinned(ety: &ExternType, types: &Types) -> TokenStream { 41533d722a9Sopenharmony_ci let ident = &ety.name.rust; 41633d722a9Sopenharmony_ci let infer = Token); 41733d722a9Sopenharmony_ci 41833d722a9Sopenharmony_ci let resolve = types.resolve(ident); 41933d722a9Sopenharmony_ci let lifetimes = resolve.generics.to_underscore_lifetimes(); 42033d722a9Sopenharmony_ci 42133d722a9Sopenharmony_ci quote! { 42233d722a9Sopenharmony_ci let _: fn() = { 42333d722a9Sopenharmony_ci // Derived from https://github.com/nvzqz/static-assertions-rs. 42433d722a9Sopenharmony_ci trait __AmbiguousIfImpl<A> { 42533d722a9Sopenharmony_ci fn infer() {} 42633d722a9Sopenharmony_ci } 42733d722a9Sopenharmony_ci 42833d722a9Sopenharmony_ci impl<T> __AmbiguousIfImpl<()> for T 42933d722a9Sopenharmony_ci where 43033d722a9Sopenharmony_ci T: ?::cxx::core::marker::Sized 43133d722a9Sopenharmony_ci {} 43233d722a9Sopenharmony_ci 43333d722a9Sopenharmony_ci #[allow(dead_code)] 43433d722a9Sopenharmony_ci struct __Invalid; 43533d722a9Sopenharmony_ci 43633d722a9Sopenharmony_ci impl<T> __AmbiguousIfImpl<__Invalid> for T 43733d722a9Sopenharmony_ci where 43833d722a9Sopenharmony_ci T: ?::cxx::core::marker::Sized + ::cxx::core::marker::Unpin, 43933d722a9Sopenharmony_ci {} 44033d722a9Sopenharmony_ci 44133d722a9Sopenharmony_ci // If there is only one specialized trait impl, type inference with 44233d722a9Sopenharmony_ci // `_` can be resolved and this can compile. Fails to compile if 44333d722a9Sopenharmony_ci // user has added a manual Unpin impl for their opaque C++ type as 44433d722a9Sopenharmony_ci // then `__AmbiguousIfImpl<__Invalid>` also exists. 44533d722a9Sopenharmony_ci <#ident #lifetimes as __AmbiguousIfImpl<#infer>>::infer 44633d722a9Sopenharmony_ci }; 44733d722a9Sopenharmony_ci } 44833d722a9Sopenharmony_ci} 44933d722a9Sopenharmony_ci 45033d722a9Sopenharmony_cifn expand_cxx_function_decl(efn: &ExternFn, types: &Types) -> TokenStream { 45133d722a9Sopenharmony_ci let generics = &efn.generics; 45233d722a9Sopenharmony_ci let receiver = efn.receiver.iter().map(|receiver| { 45333d722a9Sopenharmony_ci let receiver_type = receiver.ty(); 45433d722a9Sopenharmony_ci quote!(_: #receiver_type) 45533d722a9Sopenharmony_ci }); 45633d722a9Sopenharmony_ci let args = efn.args.iter().map(|arg| { 45733d722a9Sopenharmony_ci let var = &arg.name.rust; 45833d722a9Sopenharmony_ci let colon = arg.colon_token; 45933d722a9Sopenharmony_ci let ty = expand_extern_type(&arg.ty, types, true); 46033d722a9Sopenharmony_ci if arg.ty == RustString { 46133d722a9Sopenharmony_ci quote!(#var #colon *const #ty) 46233d722a9Sopenharmony_ci } else if let Type::RustVec(_) = arg.ty { 46333d722a9Sopenharmony_ci quote!(#var #colon *const #ty) 46433d722a9Sopenharmony_ci } else if let Type::Fn(_) = arg.ty { 46533d722a9Sopenharmony_ci quote!(#var #colon ::cxx::private::FatFunction) 46633d722a9Sopenharmony_ci } else if types.needs_indirect_abi(&arg.ty) { 46733d722a9Sopenharmony_ci quote!(#var #colon *mut #ty) 46833d722a9Sopenharmony_ci } else { 46933d722a9Sopenharmony_ci quote!(#var #colon #ty) 47033d722a9Sopenharmony_ci } 47133d722a9Sopenharmony_ci }); 47233d722a9Sopenharmony_ci let all_args = receiver.chain(args); 47333d722a9Sopenharmony_ci let ret = if efn.throws { 47433d722a9Sopenharmony_ci quote!(-> ::cxx::private::Result) 47533d722a9Sopenharmony_ci } else { 47633d722a9Sopenharmony_ci expand_extern_return_type(&efn.ret, types, true) 47733d722a9Sopenharmony_ci }; 47833d722a9Sopenharmony_ci let mut outparam = None; 47933d722a9Sopenharmony_ci if indirect_return(efn, types) { 48033d722a9Sopenharmony_ci let ret = expand_extern_type(efn.ret.as_ref().unwrap(), types, true); 48133d722a9Sopenharmony_ci outparam = Some(quote!(__return: *mut #ret)); 48233d722a9Sopenharmony_ci } 48333d722a9Sopenharmony_ci let link_name = mangle::extern_fn(efn, types); 48433d722a9Sopenharmony_ci let local_name = format_ident!("__{}", efn.name.rust); 48533d722a9Sopenharmony_ci quote! { 48633d722a9Sopenharmony_ci #[link_name = #link_name] 48733d722a9Sopenharmony_ci fn #local_name #generics(#(#all_args,)* #outparam) #ret; 48833d722a9Sopenharmony_ci } 48933d722a9Sopenharmony_ci} 49033d722a9Sopenharmony_ci 49133d722a9Sopenharmony_cifn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream { 49233d722a9Sopenharmony_ci let doc = &efn.doc; 49333d722a9Sopenharmony_ci let attrs = &efn.attrs; 49433d722a9Sopenharmony_ci let decl = expand_cxx_function_decl(efn, types); 49533d722a9Sopenharmony_ci let receiver = efn.receiver.iter().map(|receiver| { 49633d722a9Sopenharmony_ci let var = receiver.var; 49733d722a9Sopenharmony_ci if receiver.pinned { 49833d722a9Sopenharmony_ci let colon = receiver.colon_token; 49933d722a9Sopenharmony_ci let ty = receiver.ty_self(); 50033d722a9Sopenharmony_ci quote!(#var #colon #ty) 50133d722a9Sopenharmony_ci } else { 50233d722a9Sopenharmony_ci let ampersand = receiver.ampersand; 50333d722a9Sopenharmony_ci let lifetime = &receiver.lifetime; 50433d722a9Sopenharmony_ci let mutability = receiver.mutability; 50533d722a9Sopenharmony_ci quote!(#ampersand #lifetime #mutability #var) 50633d722a9Sopenharmony_ci } 50733d722a9Sopenharmony_ci }); 50833d722a9Sopenharmony_ci let args = efn.args.iter().map(|arg| quote!(#arg)); 50933d722a9Sopenharmony_ci let all_args = receiver.chain(args); 51033d722a9Sopenharmony_ci let ret = if efn.throws { 51133d722a9Sopenharmony_ci let ok = match &efn.ret { 51233d722a9Sopenharmony_ci Some(ret) => quote!(#ret), 51333d722a9Sopenharmony_ci None => quote!(()), 51433d722a9Sopenharmony_ci }; 51533d722a9Sopenharmony_ci quote!(-> ::cxx::core::result::Result<#ok, ::cxx::Exception>) 51633d722a9Sopenharmony_ci } else { 51733d722a9Sopenharmony_ci expand_return_type(&efn.ret) 51833d722a9Sopenharmony_ci }; 51933d722a9Sopenharmony_ci let indirect_return = indirect_return(efn, types); 52033d722a9Sopenharmony_ci let receiver_var = efn 52133d722a9Sopenharmony_ci .receiver 52233d722a9Sopenharmony_ci .iter() 52333d722a9Sopenharmony_ci .map(|receiver| receiver.var.to_token_stream()); 52433d722a9Sopenharmony_ci let arg_vars = efn.args.iter().map(|arg| { 52533d722a9Sopenharmony_ci let var = &arg.name.rust; 52633d722a9Sopenharmony_ci let span = var.span(); 52733d722a9Sopenharmony_ci match &arg.ty { 52833d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => { 52933d722a9Sopenharmony_ci quote_spanned!(span=> #var.as_mut_ptr() as *const ::cxx::private::RustString) 53033d722a9Sopenharmony_ci } 53133d722a9Sopenharmony_ci Type::RustBox(ty) => { 53233d722a9Sopenharmony_ci if types.is_considered_improper_ctype(&ty.inner) { 53333d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw(#var).cast()) 53433d722a9Sopenharmony_ci } else { 53533d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw(#var)) 53633d722a9Sopenharmony_ci } 53733d722a9Sopenharmony_ci } 53833d722a9Sopenharmony_ci Type::UniquePtr(ty) => { 53933d722a9Sopenharmony_ci if types.is_considered_improper_ctype(&ty.inner) { 54033d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::UniquePtr::into_raw(#var).cast()) 54133d722a9Sopenharmony_ci } else { 54233d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::UniquePtr::into_raw(#var)) 54333d722a9Sopenharmony_ci } 54433d722a9Sopenharmony_ci } 54533d722a9Sopenharmony_ci Type::RustVec(_) => quote_spanned!(span=> #var.as_mut_ptr() as *const ::cxx::private::RustVec<_>), 54633d722a9Sopenharmony_ci Type::Ref(ty) => match &ty.inner { 54733d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => match ty.mutable { 54833d722a9Sopenharmony_ci false => quote_spanned!(span=> ::cxx::private::RustString::from_ref(#var)), 54933d722a9Sopenharmony_ci true => quote_spanned!(span=> ::cxx::private::RustString::from_mut(#var)), 55033d722a9Sopenharmony_ci }, 55133d722a9Sopenharmony_ci Type::RustVec(vec) if vec.inner == RustString => match ty.mutable { 55233d722a9Sopenharmony_ci false => quote_spanned!(span=> ::cxx::private::RustVec::from_ref_vec_string(#var)), 55333d722a9Sopenharmony_ci true => quote_spanned!(span=> ::cxx::private::RustVec::from_mut_vec_string(#var)), 55433d722a9Sopenharmony_ci }, 55533d722a9Sopenharmony_ci Type::RustVec(_) => match ty.mutable { 55633d722a9Sopenharmony_ci false => quote_spanned!(span=> ::cxx::private::RustVec::from_ref(#var)), 55733d722a9Sopenharmony_ci true => quote_spanned!(span=> ::cxx::private::RustVec::from_mut(#var)), 55833d722a9Sopenharmony_ci }, 55933d722a9Sopenharmony_ci inner if types.is_considered_improper_ctype(inner) => { 56033d722a9Sopenharmony_ci let var = match ty.pinned { 56133d722a9Sopenharmony_ci false => quote!(#var), 56233d722a9Sopenharmony_ci true => quote_spanned!(span=> ::cxx::core::pin::Pin::into_inner_unchecked(#var)), 56333d722a9Sopenharmony_ci }; 56433d722a9Sopenharmony_ci match ty.mutable { 56533d722a9Sopenharmony_ci false => { 56633d722a9Sopenharmony_ci quote_spanned!(span=> #var as *const #inner as *const ::cxx::core::ffi::c_void) 56733d722a9Sopenharmony_ci } 56833d722a9Sopenharmony_ci true => quote_spanned!(span=> #var as *mut #inner as *mut ::cxx::core::ffi::c_void), 56933d722a9Sopenharmony_ci } 57033d722a9Sopenharmony_ci } 57133d722a9Sopenharmony_ci _ => quote!(#var), 57233d722a9Sopenharmony_ci }, 57333d722a9Sopenharmony_ci Type::Ptr(ty) => { 57433d722a9Sopenharmony_ci if types.is_considered_improper_ctype(&ty.inner) { 57533d722a9Sopenharmony_ci quote_spanned!(span=> #var.cast()) 57633d722a9Sopenharmony_ci } else { 57733d722a9Sopenharmony_ci quote!(#var) 57833d722a9Sopenharmony_ci } 57933d722a9Sopenharmony_ci } 58033d722a9Sopenharmony_ci Type::Str(_) => quote_spanned!(span=> ::cxx::private::RustStr::from(#var)), 58133d722a9Sopenharmony_ci Type::SliceRef(ty) => match ty.mutable { 58233d722a9Sopenharmony_ci false => quote_spanned!(span=> ::cxx::private::RustSlice::from_ref(#var)), 58333d722a9Sopenharmony_ci true => quote_spanned!(span=> ::cxx::private::RustSlice::from_mut(#var)), 58433d722a9Sopenharmony_ci }, 58533d722a9Sopenharmony_ci ty if types.needs_indirect_abi(ty) => quote_spanned!(span=> #var.as_mut_ptr()), 58633d722a9Sopenharmony_ci _ => quote!(#var), 58733d722a9Sopenharmony_ci } 58833d722a9Sopenharmony_ci }); 58933d722a9Sopenharmony_ci let vars = receiver_var.chain(arg_vars); 59033d722a9Sopenharmony_ci let trampolines = efn 59133d722a9Sopenharmony_ci .args 59233d722a9Sopenharmony_ci .iter() 59333d722a9Sopenharmony_ci .filter_map(|arg| { 59433d722a9Sopenharmony_ci if let Type::Fn(f) = &arg.ty { 59533d722a9Sopenharmony_ci let var = &arg.name; 59633d722a9Sopenharmony_ci Some(expand_function_pointer_trampoline(efn, var, f, types)) 59733d722a9Sopenharmony_ci } else { 59833d722a9Sopenharmony_ci None 59933d722a9Sopenharmony_ci } 60033d722a9Sopenharmony_ci }) 60133d722a9Sopenharmony_ci .collect::<TokenStream>(); 60233d722a9Sopenharmony_ci let mut setup = efn 60333d722a9Sopenharmony_ci .args 60433d722a9Sopenharmony_ci .iter() 60533d722a9Sopenharmony_ci .filter(|arg| types.needs_indirect_abi(&arg.ty)) 60633d722a9Sopenharmony_ci .map(|arg| { 60733d722a9Sopenharmony_ci let var = &arg.name.rust; 60833d722a9Sopenharmony_ci let span = var.span(); 60933d722a9Sopenharmony_ci // These are arguments for which C++ has taken ownership of the data 61033d722a9Sopenharmony_ci // behind the mut reference it received. 61133d722a9Sopenharmony_ci quote_spanned! {span=> 61233d722a9Sopenharmony_ci let mut #var = ::cxx::core::mem::MaybeUninit::new(#var); 61333d722a9Sopenharmony_ci } 61433d722a9Sopenharmony_ci }) 61533d722a9Sopenharmony_ci .collect::<TokenStream>(); 61633d722a9Sopenharmony_ci let local_name = format_ident!("__{}", efn.name.rust); 61733d722a9Sopenharmony_ci let span = efn.semi_token.span; 61833d722a9Sopenharmony_ci let call = if indirect_return { 61933d722a9Sopenharmony_ci let ret = expand_extern_type(efn.ret.as_ref().unwrap(), types, true); 62033d722a9Sopenharmony_ci setup.extend(quote_spanned! {span=> 62133d722a9Sopenharmony_ci let mut __return = ::cxx::core::mem::MaybeUninit::<#ret>::uninit(); 62233d722a9Sopenharmony_ci }); 62333d722a9Sopenharmony_ci setup.extend(if efn.throws { 62433d722a9Sopenharmony_ci quote_spanned! {span=> 62533d722a9Sopenharmony_ci #local_name(#(#vars,)* __return.as_mut_ptr()).exception()?; 62633d722a9Sopenharmony_ci } 62733d722a9Sopenharmony_ci } else { 62833d722a9Sopenharmony_ci quote_spanned! {span=> 62933d722a9Sopenharmony_ci #local_name(#(#vars,)* __return.as_mut_ptr()); 63033d722a9Sopenharmony_ci } 63133d722a9Sopenharmony_ci }); 63233d722a9Sopenharmony_ci quote_spanned!(span=> __return.assume_init()) 63333d722a9Sopenharmony_ci } else if efn.throws { 63433d722a9Sopenharmony_ci quote_spanned! {span=> 63533d722a9Sopenharmony_ci #local_name(#(#vars),*).exception() 63633d722a9Sopenharmony_ci } 63733d722a9Sopenharmony_ci } else { 63833d722a9Sopenharmony_ci quote_spanned! {span=> 63933d722a9Sopenharmony_ci #local_name(#(#vars),*) 64033d722a9Sopenharmony_ci } 64133d722a9Sopenharmony_ci }; 64233d722a9Sopenharmony_ci let mut expr; 64333d722a9Sopenharmony_ci if efn.throws && efn.sig.ret.is_none() { 64433d722a9Sopenharmony_ci expr = call; 64533d722a9Sopenharmony_ci } else { 64633d722a9Sopenharmony_ci expr = match &efn.ret { 64733d722a9Sopenharmony_ci None => call, 64833d722a9Sopenharmony_ci Some(ret) => match ret { 64933d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => { 65033d722a9Sopenharmony_ci quote_spanned!(span=> #call.into_string()) 65133d722a9Sopenharmony_ci } 65233d722a9Sopenharmony_ci Type::RustBox(ty) => { 65333d722a9Sopenharmony_ci if types.is_considered_improper_ctype(&ty.inner) { 65433d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#call.cast())) 65533d722a9Sopenharmony_ci } else { 65633d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#call)) 65733d722a9Sopenharmony_ci } 65833d722a9Sopenharmony_ci } 65933d722a9Sopenharmony_ci Type::RustVec(vec) => { 66033d722a9Sopenharmony_ci if vec.inner == RustString { 66133d722a9Sopenharmony_ci quote_spanned!(span=> #call.into_vec_string()) 66233d722a9Sopenharmony_ci } else { 66333d722a9Sopenharmony_ci quote_spanned!(span=> #call.into_vec()) 66433d722a9Sopenharmony_ci } 66533d722a9Sopenharmony_ci } 66633d722a9Sopenharmony_ci Type::UniquePtr(ty) => { 66733d722a9Sopenharmony_ci if types.is_considered_improper_ctype(&ty.inner) { 66833d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#call.cast())) 66933d722a9Sopenharmony_ci } else { 67033d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#call)) 67133d722a9Sopenharmony_ci } 67233d722a9Sopenharmony_ci } 67333d722a9Sopenharmony_ci Type::Ref(ty) => match &ty.inner { 67433d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => match ty.mutable { 67533d722a9Sopenharmony_ci false => quote_spanned!(span=> #call.as_string()), 67633d722a9Sopenharmony_ci true => quote_spanned!(span=> #call.as_mut_string()), 67733d722a9Sopenharmony_ci }, 67833d722a9Sopenharmony_ci Type::RustVec(vec) if vec.inner == RustString => match ty.mutable { 67933d722a9Sopenharmony_ci false => quote_spanned!(span=> #call.as_vec_string()), 68033d722a9Sopenharmony_ci true => quote_spanned!(span=> #call.as_mut_vec_string()), 68133d722a9Sopenharmony_ci }, 68233d722a9Sopenharmony_ci Type::RustVec(_) => match ty.mutable { 68333d722a9Sopenharmony_ci false => quote_spanned!(span=> #call.as_vec()), 68433d722a9Sopenharmony_ci true => quote_spanned!(span=> #call.as_mut_vec()), 68533d722a9Sopenharmony_ci }, 68633d722a9Sopenharmony_ci inner if types.is_considered_improper_ctype(inner) => { 68733d722a9Sopenharmony_ci let mutability = ty.mutability; 68833d722a9Sopenharmony_ci let deref_mut = quote_spanned!(span=> &#mutability *#call.cast()); 68933d722a9Sopenharmony_ci match ty.pinned { 69033d722a9Sopenharmony_ci false => deref_mut, 69133d722a9Sopenharmony_ci true => { 69233d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::core::pin::Pin::new_unchecked(#deref_mut)) 69333d722a9Sopenharmony_ci } 69433d722a9Sopenharmony_ci } 69533d722a9Sopenharmony_ci } 69633d722a9Sopenharmony_ci _ => call, 69733d722a9Sopenharmony_ci }, 69833d722a9Sopenharmony_ci Type::Ptr(ty) => { 69933d722a9Sopenharmony_ci if types.is_considered_improper_ctype(&ty.inner) { 70033d722a9Sopenharmony_ci quote_spanned!(span=> #call.cast()) 70133d722a9Sopenharmony_ci } else { 70233d722a9Sopenharmony_ci call 70333d722a9Sopenharmony_ci } 70433d722a9Sopenharmony_ci } 70533d722a9Sopenharmony_ci Type::Str(_) => quote_spanned!(span=> #call.as_str()), 70633d722a9Sopenharmony_ci Type::SliceRef(slice) => { 70733d722a9Sopenharmony_ci let inner = &slice.inner; 70833d722a9Sopenharmony_ci match slice.mutable { 70933d722a9Sopenharmony_ci false => quote_spanned!(span=> #call.as_slice::<#inner>()), 71033d722a9Sopenharmony_ci true => quote_spanned!(span=> #call.as_mut_slice::<#inner>()), 71133d722a9Sopenharmony_ci } 71233d722a9Sopenharmony_ci } 71333d722a9Sopenharmony_ci _ => call, 71433d722a9Sopenharmony_ci }, 71533d722a9Sopenharmony_ci }; 71633d722a9Sopenharmony_ci if efn.throws { 71733d722a9Sopenharmony_ci expr = quote_spanned!(span=> ::cxx::core::result::Result::Ok(#expr)); 71833d722a9Sopenharmony_ci } 71933d722a9Sopenharmony_ci }; 72033d722a9Sopenharmony_ci let mut dispatch = quote!(#setup #expr); 72133d722a9Sopenharmony_ci let visibility = efn.visibility; 72233d722a9Sopenharmony_ci let unsafety = &efn.sig.unsafety; 72333d722a9Sopenharmony_ci if unsafety.is_none() { 72433d722a9Sopenharmony_ci dispatch = quote_spanned!(span=> unsafe { #dispatch }); 72533d722a9Sopenharmony_ci } 72633d722a9Sopenharmony_ci let fn_token = efn.sig.fn_token; 72733d722a9Sopenharmony_ci let ident = &efn.name.rust; 72833d722a9Sopenharmony_ci let generics = &efn.generics; 72933d722a9Sopenharmony_ci let arg_list = quote_spanned!(efn.sig.paren_token.span=> (#(#all_args,)*)); 73033d722a9Sopenharmony_ci let fn_body = quote_spanned!(span=> { 73133d722a9Sopenharmony_ci extern "C" { 73233d722a9Sopenharmony_ci #decl 73333d722a9Sopenharmony_ci } 73433d722a9Sopenharmony_ci #trampolines 73533d722a9Sopenharmony_ci #dispatch 73633d722a9Sopenharmony_ci }); 73733d722a9Sopenharmony_ci match &efn.receiver { 73833d722a9Sopenharmony_ci None => { 73933d722a9Sopenharmony_ci quote! { 74033d722a9Sopenharmony_ci #doc 74133d722a9Sopenharmony_ci #attrs 74233d722a9Sopenharmony_ci #visibility #unsafety #fn_token #ident #generics #arg_list #ret #fn_body 74333d722a9Sopenharmony_ci } 74433d722a9Sopenharmony_ci } 74533d722a9Sopenharmony_ci Some(receiver) => { 74633d722a9Sopenharmony_ci let elided_generics; 74733d722a9Sopenharmony_ci let receiver_ident = &receiver.ty.rust; 74833d722a9Sopenharmony_ci let resolve = types.resolve(&receiver.ty); 74933d722a9Sopenharmony_ci let receiver_generics = if receiver.ty.generics.lt_token.is_some() { 75033d722a9Sopenharmony_ci &receiver.ty.generics 75133d722a9Sopenharmony_ci } else { 75233d722a9Sopenharmony_ci elided_generics = Lifetimes { 75333d722a9Sopenharmony_ci lt_token: resolve.generics.lt_token, 75433d722a9Sopenharmony_ci lifetimes: resolve 75533d722a9Sopenharmony_ci .generics 75633d722a9Sopenharmony_ci .lifetimes 75733d722a9Sopenharmony_ci .pairs() 75833d722a9Sopenharmony_ci .map(|pair| { 75933d722a9Sopenharmony_ci let lifetime = Lifetime::new("'_", pair.value().apostrophe); 76033d722a9Sopenharmony_ci let punct = pair.punct().map(|&&comma| comma); 76133d722a9Sopenharmony_ci punctuated::Pair::new(lifetime, punct) 76233d722a9Sopenharmony_ci }) 76333d722a9Sopenharmony_ci .collect(), 76433d722a9Sopenharmony_ci gt_token: resolve.generics.gt_token, 76533d722a9Sopenharmony_ci }; 76633d722a9Sopenharmony_ci &elided_generics 76733d722a9Sopenharmony_ci }; 76833d722a9Sopenharmony_ci quote_spanned! {ident.span()=> 76933d722a9Sopenharmony_ci impl #generics #receiver_ident #receiver_generics { 77033d722a9Sopenharmony_ci #doc 77133d722a9Sopenharmony_ci #attrs 77233d722a9Sopenharmony_ci #visibility #unsafety #fn_token #ident #arg_list #ret #fn_body 77333d722a9Sopenharmony_ci } 77433d722a9Sopenharmony_ci } 77533d722a9Sopenharmony_ci } 77633d722a9Sopenharmony_ci } 77733d722a9Sopenharmony_ci} 77833d722a9Sopenharmony_ci 77933d722a9Sopenharmony_cifn expand_function_pointer_trampoline( 78033d722a9Sopenharmony_ci efn: &ExternFn, 78133d722a9Sopenharmony_ci var: &Pair, 78233d722a9Sopenharmony_ci sig: &Signature, 78333d722a9Sopenharmony_ci types: &Types, 78433d722a9Sopenharmony_ci) -> TokenStream { 78533d722a9Sopenharmony_ci let c_trampoline = mangle::c_trampoline(efn, var, types); 78633d722a9Sopenharmony_ci let r_trampoline = mangle::r_trampoline(efn, var, types); 78733d722a9Sopenharmony_ci let local_name = parse_quote!(__); 78833d722a9Sopenharmony_ci let prevent_unwind_label = format!("::{}::{}", efn.name.rust, var.rust); 78933d722a9Sopenharmony_ci let body_span = efn.semi_token.span; 79033d722a9Sopenharmony_ci let shim = expand_rust_function_shim_impl( 79133d722a9Sopenharmony_ci sig, 79233d722a9Sopenharmony_ci types, 79333d722a9Sopenharmony_ci &r_trampoline, 79433d722a9Sopenharmony_ci local_name, 79533d722a9Sopenharmony_ci prevent_unwind_label, 79633d722a9Sopenharmony_ci None, 79733d722a9Sopenharmony_ci Some(&efn.generics), 79833d722a9Sopenharmony_ci &efn.attrs, 79933d722a9Sopenharmony_ci body_span, 80033d722a9Sopenharmony_ci ); 80133d722a9Sopenharmony_ci let var = &var.rust; 80233d722a9Sopenharmony_ci 80333d722a9Sopenharmony_ci quote! { 80433d722a9Sopenharmony_ci let #var = ::cxx::private::FatFunction { 80533d722a9Sopenharmony_ci trampoline: { 80633d722a9Sopenharmony_ci extern "C" { 80733d722a9Sopenharmony_ci #[link_name = #c_trampoline] 80833d722a9Sopenharmony_ci fn trampoline(); 80933d722a9Sopenharmony_ci } 81033d722a9Sopenharmony_ci #shim 81133d722a9Sopenharmony_ci trampoline as usize as *const ::cxx::core::ffi::c_void 81233d722a9Sopenharmony_ci }, 81333d722a9Sopenharmony_ci ptr: #var as usize as *const ::cxx::core::ffi::c_void, 81433d722a9Sopenharmony_ci }; 81533d722a9Sopenharmony_ci } 81633d722a9Sopenharmony_ci} 81733d722a9Sopenharmony_ci 81833d722a9Sopenharmony_cifn expand_rust_type_import(ety: &ExternType) -> TokenStream { 81933d722a9Sopenharmony_ci let ident = &ety.name.rust; 82033d722a9Sopenharmony_ci let span = ident.span(); 82133d722a9Sopenharmony_ci 82233d722a9Sopenharmony_ci quote_spanned! {span=> 82333d722a9Sopenharmony_ci use super::#ident; 82433d722a9Sopenharmony_ci } 82533d722a9Sopenharmony_ci} 82633d722a9Sopenharmony_ci 82733d722a9Sopenharmony_cifn expand_rust_type_impl(ety: &ExternType) -> TokenStream { 82833d722a9Sopenharmony_ci let ident = &ety.name.rust; 82933d722a9Sopenharmony_ci let generics = &ety.generics; 83033d722a9Sopenharmony_ci let span = ident.span(); 83133d722a9Sopenharmony_ci let unsafe_impl = quote_spanned!(ety.type_token.span=> unsafe impl); 83233d722a9Sopenharmony_ci 83333d722a9Sopenharmony_ci let mut impls = quote_spanned! {span=> 83433d722a9Sopenharmony_ci #[doc(hidden)] 83533d722a9Sopenharmony_ci #unsafe_impl #generics ::cxx::private::RustType for #ident #generics {} 83633d722a9Sopenharmony_ci }; 83733d722a9Sopenharmony_ci 83833d722a9Sopenharmony_ci for derive in &ety.derives { 83933d722a9Sopenharmony_ci if derive.what == Trait::ExternType { 84033d722a9Sopenharmony_ci let type_id = type_id(&ety.name); 84133d722a9Sopenharmony_ci let span = derive.span; 84233d722a9Sopenharmony_ci impls.extend(quote_spanned! {span=> 84333d722a9Sopenharmony_ci unsafe impl #generics ::cxx::ExternType for #ident #generics { 84433d722a9Sopenharmony_ci #[allow(unused_attributes)] // incorrect lint 84533d722a9Sopenharmony_ci #[doc(hidden)] 84633d722a9Sopenharmony_ci type Id = #type_id; 84733d722a9Sopenharmony_ci type Kind = ::cxx::kind::Opaque; 84833d722a9Sopenharmony_ci } 84933d722a9Sopenharmony_ci }); 85033d722a9Sopenharmony_ci } 85133d722a9Sopenharmony_ci } 85233d722a9Sopenharmony_ci 85333d722a9Sopenharmony_ci impls 85433d722a9Sopenharmony_ci} 85533d722a9Sopenharmony_ci 85633d722a9Sopenharmony_cifn expand_rust_type_assert_unpin(ety: &ExternType, types: &Types) -> TokenStream { 85733d722a9Sopenharmony_ci let ident = &ety.name.rust; 85833d722a9Sopenharmony_ci let begin_span = Token; 85933d722a9Sopenharmony_ci let unpin = quote_spanned! {ety.semi_token.span=> 86033d722a9Sopenharmony_ci #begin_span cxx::core::marker::Unpin 86133d722a9Sopenharmony_ci }; 86233d722a9Sopenharmony_ci 86333d722a9Sopenharmony_ci let resolve = types.resolve(ident); 86433d722a9Sopenharmony_ci let lifetimes = resolve.generics.to_underscore_lifetimes(); 86533d722a9Sopenharmony_ci 86633d722a9Sopenharmony_ci quote_spanned! {ident.span()=> 86733d722a9Sopenharmony_ci let _ = { 86833d722a9Sopenharmony_ci fn __AssertUnpin<T: ?::cxx::core::marker::Sized + #unpin>() {} 86933d722a9Sopenharmony_ci __AssertUnpin::<#ident #lifetimes> 87033d722a9Sopenharmony_ci }; 87133d722a9Sopenharmony_ci } 87233d722a9Sopenharmony_ci} 87333d722a9Sopenharmony_ci 87433d722a9Sopenharmony_cifn expand_rust_type_layout(ety: &ExternType, types: &Types) -> TokenStream { 87533d722a9Sopenharmony_ci // Rustc will render as follows if not sized: 87633d722a9Sopenharmony_ci // 87733d722a9Sopenharmony_ci // type TheirType; 87833d722a9Sopenharmony_ci // -----^^^^^^^^^- 87933d722a9Sopenharmony_ci // | | 88033d722a9Sopenharmony_ci // | doesn't have a size known at compile-time 88133d722a9Sopenharmony_ci // required by this bound in `__AssertSized` 88233d722a9Sopenharmony_ci 88333d722a9Sopenharmony_ci let ident = &ety.name.rust; 88433d722a9Sopenharmony_ci let begin_span = Token; 88533d722a9Sopenharmony_ci let sized = quote_spanned! {ety.semi_token.span=> 88633d722a9Sopenharmony_ci #begin_span cxx::core::marker::Sized 88733d722a9Sopenharmony_ci }; 88833d722a9Sopenharmony_ci 88933d722a9Sopenharmony_ci let link_sizeof = mangle::operator(&ety.name, "sizeof"); 89033d722a9Sopenharmony_ci let link_alignof = mangle::operator(&ety.name, "alignof"); 89133d722a9Sopenharmony_ci 89233d722a9Sopenharmony_ci let local_sizeof = format_ident!("__sizeof_{}", ety.name.rust); 89333d722a9Sopenharmony_ci let local_alignof = format_ident!("__alignof_{}", ety.name.rust); 89433d722a9Sopenharmony_ci 89533d722a9Sopenharmony_ci let resolve = types.resolve(ident); 89633d722a9Sopenharmony_ci let lifetimes = resolve.generics.to_underscore_lifetimes(); 89733d722a9Sopenharmony_ci 89833d722a9Sopenharmony_ci quote_spanned! {ident.span()=> 89933d722a9Sopenharmony_ci { 90033d722a9Sopenharmony_ci #[doc(hidden)] 90133d722a9Sopenharmony_ci fn __AssertSized<T: ?#sized + #sized>() -> ::cxx::core::alloc::Layout { 90233d722a9Sopenharmony_ci ::cxx::core::alloc::Layout::new::<T>() 90333d722a9Sopenharmony_ci } 90433d722a9Sopenharmony_ci #[doc(hidden)] 90533d722a9Sopenharmony_ci #[export_name = #link_sizeof] 90633d722a9Sopenharmony_ci extern "C" fn #local_sizeof() -> usize { 90733d722a9Sopenharmony_ci __AssertSized::<#ident #lifetimes>().size() 90833d722a9Sopenharmony_ci } 90933d722a9Sopenharmony_ci #[doc(hidden)] 91033d722a9Sopenharmony_ci #[export_name = #link_alignof] 91133d722a9Sopenharmony_ci extern "C" fn #local_alignof() -> usize { 91233d722a9Sopenharmony_ci __AssertSized::<#ident #lifetimes>().align() 91333d722a9Sopenharmony_ci } 91433d722a9Sopenharmony_ci } 91533d722a9Sopenharmony_ci } 91633d722a9Sopenharmony_ci} 91733d722a9Sopenharmony_ci 91833d722a9Sopenharmony_cifn expand_forbid(impls: TokenStream) -> TokenStream { 91933d722a9Sopenharmony_ci quote! { 92033d722a9Sopenharmony_ci mod forbid { 92133d722a9Sopenharmony_ci pub trait Drop {} 92233d722a9Sopenharmony_ci #[allow(drop_bounds)] 92333d722a9Sopenharmony_ci impl<T: ?::cxx::core::marker::Sized + ::cxx::core::ops::Drop> self::Drop for T {} 92433d722a9Sopenharmony_ci #impls 92533d722a9Sopenharmony_ci } 92633d722a9Sopenharmony_ci } 92733d722a9Sopenharmony_ci} 92833d722a9Sopenharmony_ci 92933d722a9Sopenharmony_cifn expand_rust_function_shim(efn: &ExternFn, types: &Types) -> TokenStream { 93033d722a9Sopenharmony_ci let link_name = mangle::extern_fn(efn, types); 93133d722a9Sopenharmony_ci let local_name = match &efn.receiver { 93233d722a9Sopenharmony_ci None => format_ident!("__{}", efn.name.rust), 93333d722a9Sopenharmony_ci Some(receiver) => format_ident!("__{}__{}", receiver.ty.rust, efn.name.rust), 93433d722a9Sopenharmony_ci }; 93533d722a9Sopenharmony_ci let prevent_unwind_label = match &efn.receiver { 93633d722a9Sopenharmony_ci None => format!("::{}", efn.name.rust), 93733d722a9Sopenharmony_ci Some(receiver) => format!("::{}::{}", receiver.ty.rust, efn.name.rust), 93833d722a9Sopenharmony_ci }; 93933d722a9Sopenharmony_ci let invoke = Some(&efn.name.rust); 94033d722a9Sopenharmony_ci let body_span = efn.semi_token.span; 94133d722a9Sopenharmony_ci expand_rust_function_shim_impl( 94233d722a9Sopenharmony_ci efn, 94333d722a9Sopenharmony_ci types, 94433d722a9Sopenharmony_ci &link_name, 94533d722a9Sopenharmony_ci local_name, 94633d722a9Sopenharmony_ci prevent_unwind_label, 94733d722a9Sopenharmony_ci invoke, 94833d722a9Sopenharmony_ci None, 94933d722a9Sopenharmony_ci &efn.attrs, 95033d722a9Sopenharmony_ci body_span, 95133d722a9Sopenharmony_ci ) 95233d722a9Sopenharmony_ci} 95333d722a9Sopenharmony_ci 95433d722a9Sopenharmony_cifn expand_rust_function_shim_impl( 95533d722a9Sopenharmony_ci sig: &Signature, 95633d722a9Sopenharmony_ci types: &Types, 95733d722a9Sopenharmony_ci link_name: &Symbol, 95833d722a9Sopenharmony_ci local_name: Ident, 95933d722a9Sopenharmony_ci prevent_unwind_label: String, 96033d722a9Sopenharmony_ci invoke: Option<&Ident>, 96133d722a9Sopenharmony_ci outer_generics: Option<&Generics>, 96233d722a9Sopenharmony_ci attrs: &OtherAttrs, 96333d722a9Sopenharmony_ci body_span: Span, 96433d722a9Sopenharmony_ci) -> TokenStream { 96533d722a9Sopenharmony_ci let generics = outer_generics.unwrap_or(&sig.generics); 96633d722a9Sopenharmony_ci let receiver_var = sig 96733d722a9Sopenharmony_ci .receiver 96833d722a9Sopenharmony_ci .as_ref() 96933d722a9Sopenharmony_ci .map(|receiver| quote_spanned!(receiver.var.span=> __self)); 97033d722a9Sopenharmony_ci let receiver = sig.receiver.as_ref().map(|receiver| { 97133d722a9Sopenharmony_ci let colon = receiver.colon_token; 97233d722a9Sopenharmony_ci let receiver_type = receiver.ty(); 97333d722a9Sopenharmony_ci quote!(#receiver_var #colon #receiver_type) 97433d722a9Sopenharmony_ci }); 97533d722a9Sopenharmony_ci let args = sig.args.iter().map(|arg| { 97633d722a9Sopenharmony_ci let var = &arg.name.rust; 97733d722a9Sopenharmony_ci let colon = arg.colon_token; 97833d722a9Sopenharmony_ci let ty = expand_extern_type(&arg.ty, types, false); 97933d722a9Sopenharmony_ci if types.needs_indirect_abi(&arg.ty) { 98033d722a9Sopenharmony_ci quote!(#var #colon *mut #ty) 98133d722a9Sopenharmony_ci } else { 98233d722a9Sopenharmony_ci quote!(#var #colon #ty) 98333d722a9Sopenharmony_ci } 98433d722a9Sopenharmony_ci }); 98533d722a9Sopenharmony_ci let all_args = receiver.into_iter().chain(args); 98633d722a9Sopenharmony_ci 98733d722a9Sopenharmony_ci let arg_vars = sig.args.iter().map(|arg| { 98833d722a9Sopenharmony_ci let var = &arg.name.rust; 98933d722a9Sopenharmony_ci let span = var.span(); 99033d722a9Sopenharmony_ci match &arg.ty { 99133d722a9Sopenharmony_ci Type::Ident(i) if i.rust == RustString => { 99233d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_string())) 99333d722a9Sopenharmony_ci } 99433d722a9Sopenharmony_ci Type::RustBox(_) => quote_spanned!(span=> ::cxx::alloc::boxed::Box::from_raw(#var)), 99533d722a9Sopenharmony_ci Type::RustVec(vec) => { 99633d722a9Sopenharmony_ci if vec.inner == RustString { 99733d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_vec_string())) 99833d722a9Sopenharmony_ci } else { 99933d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::core::mem::take((*#var).as_mut_vec())) 100033d722a9Sopenharmony_ci } 100133d722a9Sopenharmony_ci } 100233d722a9Sopenharmony_ci Type::UniquePtr(_) => quote_spanned!(span=> ::cxx::UniquePtr::from_raw(#var)), 100333d722a9Sopenharmony_ci Type::Ref(ty) => match &ty.inner { 100433d722a9Sopenharmony_ci Type::Ident(i) if i.rust == RustString => match ty.mutable { 100533d722a9Sopenharmony_ci false => quote_spanned!(span=> #var.as_string()), 100633d722a9Sopenharmony_ci true => quote_spanned!(span=> #var.as_mut_string()), 100733d722a9Sopenharmony_ci }, 100833d722a9Sopenharmony_ci Type::RustVec(vec) if vec.inner == RustString => match ty.mutable { 100933d722a9Sopenharmony_ci false => quote_spanned!(span=> #var.as_vec_string()), 101033d722a9Sopenharmony_ci true => quote_spanned!(span=> #var.as_mut_vec_string()), 101133d722a9Sopenharmony_ci }, 101233d722a9Sopenharmony_ci Type::RustVec(_) => match ty.mutable { 101333d722a9Sopenharmony_ci false => quote_spanned!(span=> #var.as_vec()), 101433d722a9Sopenharmony_ci true => quote_spanned!(span=> #var.as_mut_vec()), 101533d722a9Sopenharmony_ci }, 101633d722a9Sopenharmony_ci _ => quote!(#var), 101733d722a9Sopenharmony_ci }, 101833d722a9Sopenharmony_ci Type::Str(_) => quote_spanned!(span=> #var.as_str()), 101933d722a9Sopenharmony_ci Type::SliceRef(slice) => { 102033d722a9Sopenharmony_ci let inner = &slice.inner; 102133d722a9Sopenharmony_ci match slice.mutable { 102233d722a9Sopenharmony_ci false => quote_spanned!(span=> #var.as_slice::<#inner>()), 102333d722a9Sopenharmony_ci true => quote_spanned!(span=> #var.as_mut_slice::<#inner>()), 102433d722a9Sopenharmony_ci } 102533d722a9Sopenharmony_ci } 102633d722a9Sopenharmony_ci ty if types.needs_indirect_abi(ty) => { 102733d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::core::ptr::read(#var)) 102833d722a9Sopenharmony_ci } 102933d722a9Sopenharmony_ci _ => quote!(#var), 103033d722a9Sopenharmony_ci } 103133d722a9Sopenharmony_ci }); 103233d722a9Sopenharmony_ci let vars: Vec<_> = receiver_var.into_iter().chain(arg_vars).collect(); 103333d722a9Sopenharmony_ci 103433d722a9Sopenharmony_ci let wrap_super = invoke.map(|invoke| expand_rust_function_shim_super(sig, &local_name, invoke)); 103533d722a9Sopenharmony_ci 103633d722a9Sopenharmony_ci let mut requires_closure; 103733d722a9Sopenharmony_ci let mut call = match invoke { 103833d722a9Sopenharmony_ci Some(_) => { 103933d722a9Sopenharmony_ci requires_closure = false; 104033d722a9Sopenharmony_ci quote!(#local_name) 104133d722a9Sopenharmony_ci } 104233d722a9Sopenharmony_ci None => { 104333d722a9Sopenharmony_ci requires_closure = true; 104433d722a9Sopenharmony_ci quote!(::cxx::core::mem::transmute::<*const (), #sig>(__extern)) 104533d722a9Sopenharmony_ci } 104633d722a9Sopenharmony_ci }; 104733d722a9Sopenharmony_ci requires_closure |= !vars.is_empty(); 104833d722a9Sopenharmony_ci call.extend(quote! { (#(#vars),*) }); 104933d722a9Sopenharmony_ci 105033d722a9Sopenharmony_ci let span = body_span; 105133d722a9Sopenharmony_ci let conversion = sig.ret.as_ref().and_then(|ret| match ret { 105233d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => { 105333d722a9Sopenharmony_ci Some(quote_spanned!(span=> ::cxx::private::RustString::from)) 105433d722a9Sopenharmony_ci } 105533d722a9Sopenharmony_ci Type::RustBox(_) => Some(quote_spanned!(span=> ::cxx::alloc::boxed::Box::into_raw)), 105633d722a9Sopenharmony_ci Type::RustVec(vec) => { 105733d722a9Sopenharmony_ci if vec.inner == RustString { 105833d722a9Sopenharmony_ci Some(quote_spanned!(span=> ::cxx::private::RustVec::from_vec_string)) 105933d722a9Sopenharmony_ci } else { 106033d722a9Sopenharmony_ci Some(quote_spanned!(span=> ::cxx::private::RustVec::from)) 106133d722a9Sopenharmony_ci } 106233d722a9Sopenharmony_ci } 106333d722a9Sopenharmony_ci Type::UniquePtr(_) => Some(quote_spanned!(span=> ::cxx::UniquePtr::into_raw)), 106433d722a9Sopenharmony_ci Type::Ref(ty) => match &ty.inner { 106533d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => match ty.mutable { 106633d722a9Sopenharmony_ci false => Some(quote_spanned!(span=> ::cxx::private::RustString::from_ref)), 106733d722a9Sopenharmony_ci true => Some(quote_spanned!(span=> ::cxx::private::RustString::from_mut)), 106833d722a9Sopenharmony_ci }, 106933d722a9Sopenharmony_ci Type::RustVec(vec) if vec.inner == RustString => match ty.mutable { 107033d722a9Sopenharmony_ci false => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_ref_vec_string)), 107133d722a9Sopenharmony_ci true => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_mut_vec_string)), 107233d722a9Sopenharmony_ci }, 107333d722a9Sopenharmony_ci Type::RustVec(_) => match ty.mutable { 107433d722a9Sopenharmony_ci false => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_ref)), 107533d722a9Sopenharmony_ci true => Some(quote_spanned!(span=> ::cxx::private::RustVec::from_mut)), 107633d722a9Sopenharmony_ci }, 107733d722a9Sopenharmony_ci _ => None, 107833d722a9Sopenharmony_ci }, 107933d722a9Sopenharmony_ci Type::Str(_) => Some(quote_spanned!(span=> ::cxx::private::RustStr::from)), 108033d722a9Sopenharmony_ci Type::SliceRef(ty) => match ty.mutable { 108133d722a9Sopenharmony_ci false => Some(quote_spanned!(span=> ::cxx::private::RustSlice::from_ref)), 108233d722a9Sopenharmony_ci true => Some(quote_spanned!(span=> ::cxx::private::RustSlice::from_mut)), 108333d722a9Sopenharmony_ci }, 108433d722a9Sopenharmony_ci _ => None, 108533d722a9Sopenharmony_ci }); 108633d722a9Sopenharmony_ci 108733d722a9Sopenharmony_ci let mut expr = match conversion { 108833d722a9Sopenharmony_ci None => call, 108933d722a9Sopenharmony_ci Some(conversion) if !sig.throws => { 109033d722a9Sopenharmony_ci requires_closure = true; 109133d722a9Sopenharmony_ci quote_spanned!(span=> #conversion(#call)) 109233d722a9Sopenharmony_ci } 109333d722a9Sopenharmony_ci Some(conversion) => { 109433d722a9Sopenharmony_ci requires_closure = true; 109533d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::core::result::Result::map(#call, #conversion)) 109633d722a9Sopenharmony_ci } 109733d722a9Sopenharmony_ci }; 109833d722a9Sopenharmony_ci 109933d722a9Sopenharmony_ci let mut outparam = None; 110033d722a9Sopenharmony_ci let indirect_return = indirect_return(sig, types); 110133d722a9Sopenharmony_ci if indirect_return { 110233d722a9Sopenharmony_ci let ret = expand_extern_type(sig.ret.as_ref().unwrap(), types, false); 110333d722a9Sopenharmony_ci outparam = Some(quote_spanned!(span=> __return: *mut #ret,)); 110433d722a9Sopenharmony_ci } 110533d722a9Sopenharmony_ci if sig.throws { 110633d722a9Sopenharmony_ci let out = match sig.ret { 110733d722a9Sopenharmony_ci Some(_) => quote_spanned!(span=> __return), 110833d722a9Sopenharmony_ci None => quote_spanned!(span=> &mut ()), 110933d722a9Sopenharmony_ci }; 111033d722a9Sopenharmony_ci requires_closure = true; 111133d722a9Sopenharmony_ci expr = quote_spanned!(span=> ::cxx::private::r#try(#out, #expr)); 111233d722a9Sopenharmony_ci } else if indirect_return { 111333d722a9Sopenharmony_ci requires_closure = true; 111433d722a9Sopenharmony_ci expr = quote_spanned!(span=> ::cxx::core::ptr::write(__return, #expr)); 111533d722a9Sopenharmony_ci } 111633d722a9Sopenharmony_ci 111733d722a9Sopenharmony_ci let closure = if requires_closure { 111833d722a9Sopenharmony_ci quote_spanned!(span=> move || #expr) 111933d722a9Sopenharmony_ci } else { 112033d722a9Sopenharmony_ci quote!(#local_name) 112133d722a9Sopenharmony_ci }; 112233d722a9Sopenharmony_ci 112333d722a9Sopenharmony_ci expr = quote_spanned!(span=> ::cxx::private::prevent_unwind(__fn, #closure)); 112433d722a9Sopenharmony_ci 112533d722a9Sopenharmony_ci let ret = if sig.throws { 112633d722a9Sopenharmony_ci quote!(-> ::cxx::private::Result) 112733d722a9Sopenharmony_ci } else { 112833d722a9Sopenharmony_ci expand_extern_return_type(&sig.ret, types, false) 112933d722a9Sopenharmony_ci }; 113033d722a9Sopenharmony_ci 113133d722a9Sopenharmony_ci let pointer = match invoke { 113233d722a9Sopenharmony_ci None => Some(quote_spanned!(span=> __extern: *const ())), 113333d722a9Sopenharmony_ci Some(_) => None, 113433d722a9Sopenharmony_ci }; 113533d722a9Sopenharmony_ci 113633d722a9Sopenharmony_ci quote_spanned! {span=> 113733d722a9Sopenharmony_ci #attrs 113833d722a9Sopenharmony_ci #[doc(hidden)] 113933d722a9Sopenharmony_ci #[export_name = #link_name] 114033d722a9Sopenharmony_ci unsafe extern "C" fn #local_name #generics(#(#all_args,)* #outparam #pointer) #ret { 114133d722a9Sopenharmony_ci let __fn = ::cxx::private::concat!(::cxx::private::module_path!(), #prevent_unwind_label); 114233d722a9Sopenharmony_ci #wrap_super 114333d722a9Sopenharmony_ci #expr 114433d722a9Sopenharmony_ci } 114533d722a9Sopenharmony_ci } 114633d722a9Sopenharmony_ci} 114733d722a9Sopenharmony_ci 114833d722a9Sopenharmony_ci// A wrapper like `fn f(x: Arg) { super::f(x) }` just to ensure we have the 114933d722a9Sopenharmony_ci// accurate unsafety declaration and no problematic elided lifetimes. 115033d722a9Sopenharmony_cifn expand_rust_function_shim_super( 115133d722a9Sopenharmony_ci sig: &Signature, 115233d722a9Sopenharmony_ci local_name: &Ident, 115333d722a9Sopenharmony_ci invoke: &Ident, 115433d722a9Sopenharmony_ci) -> TokenStream { 115533d722a9Sopenharmony_ci let unsafety = sig.unsafety; 115633d722a9Sopenharmony_ci let generics = &sig.generics; 115733d722a9Sopenharmony_ci 115833d722a9Sopenharmony_ci let receiver_var = sig 115933d722a9Sopenharmony_ci .receiver 116033d722a9Sopenharmony_ci .as_ref() 116133d722a9Sopenharmony_ci .map(|receiver| Ident::new("__self", receiver.var.span)); 116233d722a9Sopenharmony_ci let receiver = sig.receiver.iter().map(|receiver| { 116333d722a9Sopenharmony_ci let receiver_type = receiver.ty(); 116433d722a9Sopenharmony_ci quote!(#receiver_var: #receiver_type) 116533d722a9Sopenharmony_ci }); 116633d722a9Sopenharmony_ci let args = sig.args.iter().map(|arg| quote!(#arg)); 116733d722a9Sopenharmony_ci let all_args = receiver.chain(args); 116833d722a9Sopenharmony_ci 116933d722a9Sopenharmony_ci let ret = if let Some((result, _langle, rangle)) = sig.throws_tokens { 117033d722a9Sopenharmony_ci let ok = match &sig.ret { 117133d722a9Sopenharmony_ci Some(ret) => quote!(#ret), 117233d722a9Sopenharmony_ci None => quote!(()), 117333d722a9Sopenharmony_ci }; 117433d722a9Sopenharmony_ci // Set spans that result in the `Result<...>` written by the user being 117533d722a9Sopenharmony_ci // highlighted as the cause if their error type has no Display impl. 117633d722a9Sopenharmony_ci let result_begin = quote_spanned!(result.span=> ::cxx::core::result::Result<#ok, impl); 117733d722a9Sopenharmony_ci let result_end = quote_spanned!(rangle.span=> ::cxx::core::fmt::Display>); 117833d722a9Sopenharmony_ci quote!(-> #result_begin #result_end) 117933d722a9Sopenharmony_ci } else { 118033d722a9Sopenharmony_ci expand_return_type(&sig.ret) 118133d722a9Sopenharmony_ci }; 118233d722a9Sopenharmony_ci 118333d722a9Sopenharmony_ci let arg_vars = sig.args.iter().map(|arg| &arg.name.rust); 118433d722a9Sopenharmony_ci let vars = receiver_var.iter().chain(arg_vars); 118533d722a9Sopenharmony_ci 118633d722a9Sopenharmony_ci let span = invoke.span(); 118733d722a9Sopenharmony_ci let call = match &sig.receiver { 118833d722a9Sopenharmony_ci None => quote_spanned!(span=> super::#invoke), 118933d722a9Sopenharmony_ci Some(receiver) => { 119033d722a9Sopenharmony_ci let receiver_type = &receiver.ty.rust; 119133d722a9Sopenharmony_ci quote_spanned!(span=> #receiver_type::#invoke) 119233d722a9Sopenharmony_ci } 119333d722a9Sopenharmony_ci }; 119433d722a9Sopenharmony_ci 119533d722a9Sopenharmony_ci quote_spanned! {span=> 119633d722a9Sopenharmony_ci #unsafety fn #local_name #generics(#(#all_args,)*) #ret { 119733d722a9Sopenharmony_ci #call(#(#vars,)*) 119833d722a9Sopenharmony_ci } 119933d722a9Sopenharmony_ci } 120033d722a9Sopenharmony_ci} 120133d722a9Sopenharmony_ci 120233d722a9Sopenharmony_cifn expand_type_alias(alias: &TypeAlias) -> TokenStream { 120333d722a9Sopenharmony_ci let doc = &alias.doc; 120433d722a9Sopenharmony_ci let attrs = &alias.attrs; 120533d722a9Sopenharmony_ci let visibility = alias.visibility; 120633d722a9Sopenharmony_ci let type_token = alias.type_token; 120733d722a9Sopenharmony_ci let ident = &alias.name.rust; 120833d722a9Sopenharmony_ci let generics = &alias.generics; 120933d722a9Sopenharmony_ci let eq_token = alias.eq_token; 121033d722a9Sopenharmony_ci let ty = &alias.ty; 121133d722a9Sopenharmony_ci let semi_token = alias.semi_token; 121233d722a9Sopenharmony_ci 121333d722a9Sopenharmony_ci quote! { 121433d722a9Sopenharmony_ci #doc 121533d722a9Sopenharmony_ci #attrs 121633d722a9Sopenharmony_ci #visibility #type_token #ident #generics #eq_token #ty #semi_token 121733d722a9Sopenharmony_ci } 121833d722a9Sopenharmony_ci} 121933d722a9Sopenharmony_ci 122033d722a9Sopenharmony_cifn expand_type_alias_verify(alias: &TypeAlias, types: &Types) -> TokenStream { 122133d722a9Sopenharmony_ci let ident = &alias.name.rust; 122233d722a9Sopenharmony_ci let type_id = type_id(&alias.name); 122333d722a9Sopenharmony_ci let begin_span = alias.type_token.span; 122433d722a9Sopenharmony_ci let end_span = alias.semi_token.span; 122533d722a9Sopenharmony_ci let begin = quote_spanned!(begin_span=> ::cxx::private::verify_extern_type::<); 122633d722a9Sopenharmony_ci let end = quote_spanned!(end_span=> >); 122733d722a9Sopenharmony_ci 122833d722a9Sopenharmony_ci let mut verify = quote! { 122933d722a9Sopenharmony_ci const _: fn() = #begin #ident, #type_id #end; 123033d722a9Sopenharmony_ci }; 123133d722a9Sopenharmony_ci 123233d722a9Sopenharmony_ci if types.required_trivial.contains_key(&alias.name.rust) { 123333d722a9Sopenharmony_ci let begin = quote_spanned!(begin_span=> ::cxx::private::verify_extern_kind::<); 123433d722a9Sopenharmony_ci verify.extend(quote! { 123533d722a9Sopenharmony_ci const _: fn() = #begin #ident, ::cxx::kind::Trivial #end; 123633d722a9Sopenharmony_ci }); 123733d722a9Sopenharmony_ci } 123833d722a9Sopenharmony_ci 123933d722a9Sopenharmony_ci verify 124033d722a9Sopenharmony_ci} 124133d722a9Sopenharmony_ci 124233d722a9Sopenharmony_cifn type_id(name: &Pair) -> TokenStream { 124333d722a9Sopenharmony_ci let namespace_segments = name.namespace.iter(); 124433d722a9Sopenharmony_ci let mut segments = Vec::with_capacity(namespace_segments.len() + 1); 124533d722a9Sopenharmony_ci segments.extend(namespace_segments.cloned()); 124633d722a9Sopenharmony_ci segments.push(Ident::new(&name.cxx.to_string(), Span::call_site())); 124733d722a9Sopenharmony_ci let qualified = QualifiedName { segments }; 124833d722a9Sopenharmony_ci crate::type_id::expand(Crate::Cxx, qualified) 124933d722a9Sopenharmony_ci} 125033d722a9Sopenharmony_ci 125133d722a9Sopenharmony_cifn expand_rust_box(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { 125233d722a9Sopenharmony_ci let ident = key.rust; 125333d722a9Sopenharmony_ci let resolve = types.resolve(ident); 125433d722a9Sopenharmony_ci let link_prefix = format!("cxxbridge1$box${}$", resolve.name.to_symbol()); 125533d722a9Sopenharmony_ci let link_alloc = format!("{}alloc", link_prefix); 125633d722a9Sopenharmony_ci let link_dealloc = format!("{}dealloc", link_prefix); 125733d722a9Sopenharmony_ci let link_drop = format!("{}drop", link_prefix); 125833d722a9Sopenharmony_ci 125933d722a9Sopenharmony_ci let local_prefix = format_ident!("{}__box_", ident); 126033d722a9Sopenharmony_ci let local_alloc = format_ident!("{}alloc", local_prefix); 126133d722a9Sopenharmony_ci let local_dealloc = format_ident!("{}dealloc", local_prefix); 126233d722a9Sopenharmony_ci let local_drop = format_ident!("{}drop", local_prefix); 126333d722a9Sopenharmony_ci 126433d722a9Sopenharmony_ci let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); 126533d722a9Sopenharmony_ci 126633d722a9Sopenharmony_ci let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); 126733d722a9Sopenharmony_ci let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join()); 126833d722a9Sopenharmony_ci let unsafe_token = format_ident!("unsafe", span = begin_span); 126933d722a9Sopenharmony_ci let prevent_unwind_drop_label = format!("::{} as Drop>::drop", ident); 127033d722a9Sopenharmony_ci 127133d722a9Sopenharmony_ci quote_spanned! {end_span=> 127233d722a9Sopenharmony_ci #[doc(hidden)] 127333d722a9Sopenharmony_ci #unsafe_token impl #impl_generics ::cxx::private::ImplBox for #ident #ty_generics {} 127433d722a9Sopenharmony_ci #[doc(hidden)] 127533d722a9Sopenharmony_ci #[export_name = #link_alloc] 127633d722a9Sopenharmony_ci unsafe extern "C" fn #local_alloc #impl_generics() -> *mut ::cxx::core::mem::MaybeUninit<#ident #ty_generics> { 127733d722a9Sopenharmony_ci // No prevent_unwind: the global allocator is not allowed to panic. 127833d722a9Sopenharmony_ci // 127933d722a9Sopenharmony_ci // TODO: replace with Box::new_uninit when stable. 128033d722a9Sopenharmony_ci // https://doc.rust-lang.org/std/boxed/struct.Box.html#method.new_uninit 128133d722a9Sopenharmony_ci // https://github.com/rust-lang/rust/issues/63291 128233d722a9Sopenharmony_ci ::cxx::alloc::boxed::Box::into_raw(::cxx::alloc::boxed::Box::new(::cxx::core::mem::MaybeUninit::uninit())) 128333d722a9Sopenharmony_ci } 128433d722a9Sopenharmony_ci #[doc(hidden)] 128533d722a9Sopenharmony_ci #[export_name = #link_dealloc] 128633d722a9Sopenharmony_ci unsafe extern "C" fn #local_dealloc #impl_generics(ptr: *mut ::cxx::core::mem::MaybeUninit<#ident #ty_generics>) { 128733d722a9Sopenharmony_ci // No prevent_unwind: the global allocator is not allowed to panic. 128833d722a9Sopenharmony_ci let _ = ::cxx::alloc::boxed::Box::from_raw(ptr); 128933d722a9Sopenharmony_ci } 129033d722a9Sopenharmony_ci #[doc(hidden)] 129133d722a9Sopenharmony_ci #[export_name = #link_drop] 129233d722a9Sopenharmony_ci unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::cxx::alloc::boxed::Box<#ident #ty_generics>) { 129333d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label); 129433d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || ::cxx::core::ptr::drop_in_place(this)); 129533d722a9Sopenharmony_ci } 129633d722a9Sopenharmony_ci } 129733d722a9Sopenharmony_ci} 129833d722a9Sopenharmony_ci 129933d722a9Sopenharmony_cifn expand_rust_vec(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { 130033d722a9Sopenharmony_ci let elem = key.rust; 130133d722a9Sopenharmony_ci let resolve = types.resolve(elem); 130233d722a9Sopenharmony_ci let link_prefix = format!("cxxbridge1$rust_vec${}$", resolve.name.to_symbol()); 130333d722a9Sopenharmony_ci let link_new = format!("{}new", link_prefix); 130433d722a9Sopenharmony_ci let link_drop = format!("{}drop", link_prefix); 130533d722a9Sopenharmony_ci let link_len = format!("{}len", link_prefix); 130633d722a9Sopenharmony_ci let link_capacity = format!("{}capacity", link_prefix); 130733d722a9Sopenharmony_ci let link_data = format!("{}data", link_prefix); 130833d722a9Sopenharmony_ci let link_reserve_total = format!("{}reserve_total", link_prefix); 130933d722a9Sopenharmony_ci let link_set_len = format!("{}set_len", link_prefix); 131033d722a9Sopenharmony_ci let link_truncate = format!("{}truncate", link_prefix); 131133d722a9Sopenharmony_ci 131233d722a9Sopenharmony_ci let local_prefix = format_ident!("{}__vec_", elem); 131333d722a9Sopenharmony_ci let local_new = format_ident!("{}new", local_prefix); 131433d722a9Sopenharmony_ci let local_drop = format_ident!("{}drop", local_prefix); 131533d722a9Sopenharmony_ci let local_len = format_ident!("{}len", local_prefix); 131633d722a9Sopenharmony_ci let local_capacity = format_ident!("{}capacity", local_prefix); 131733d722a9Sopenharmony_ci let local_data = format_ident!("{}data", local_prefix); 131833d722a9Sopenharmony_ci let local_reserve_total = format_ident!("{}reserve_total", local_prefix); 131933d722a9Sopenharmony_ci let local_set_len = format_ident!("{}set_len", local_prefix); 132033d722a9Sopenharmony_ci let local_truncate = format_ident!("{}truncate", local_prefix); 132133d722a9Sopenharmony_ci 132233d722a9Sopenharmony_ci let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); 132333d722a9Sopenharmony_ci 132433d722a9Sopenharmony_ci let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); 132533d722a9Sopenharmony_ci let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join()); 132633d722a9Sopenharmony_ci let unsafe_token = format_ident!("unsafe", span = begin_span); 132733d722a9Sopenharmony_ci let prevent_unwind_drop_label = format!("::{} as Drop>::drop", elem); 132833d722a9Sopenharmony_ci 132933d722a9Sopenharmony_ci quote_spanned! {end_span=> 133033d722a9Sopenharmony_ci #[doc(hidden)] 133133d722a9Sopenharmony_ci #unsafe_token impl #impl_generics ::cxx::private::ImplVec for #elem #ty_generics {} 133233d722a9Sopenharmony_ci #[doc(hidden)] 133333d722a9Sopenharmony_ci #[export_name = #link_new] 133433d722a9Sopenharmony_ci unsafe extern "C" fn #local_new #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) { 133533d722a9Sopenharmony_ci // No prevent_unwind: cannot panic. 133633d722a9Sopenharmony_ci ::cxx::core::ptr::write(this, ::cxx::private::RustVec::new()); 133733d722a9Sopenharmony_ci } 133833d722a9Sopenharmony_ci #[doc(hidden)] 133933d722a9Sopenharmony_ci #[export_name = #link_drop] 134033d722a9Sopenharmony_ci unsafe extern "C" fn #local_drop #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>) { 134133d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label); 134233d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || ::cxx::core::ptr::drop_in_place(this)); 134333d722a9Sopenharmony_ci } 134433d722a9Sopenharmony_ci #[doc(hidden)] 134533d722a9Sopenharmony_ci #[export_name = #link_len] 134633d722a9Sopenharmony_ci unsafe extern "C" fn #local_len #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> usize { 134733d722a9Sopenharmony_ci // No prevent_unwind: cannot panic. 134833d722a9Sopenharmony_ci (*this).len() 134933d722a9Sopenharmony_ci } 135033d722a9Sopenharmony_ci #[doc(hidden)] 135133d722a9Sopenharmony_ci #[export_name = #link_capacity] 135233d722a9Sopenharmony_ci unsafe extern "C" fn #local_capacity #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> usize { 135333d722a9Sopenharmony_ci // No prevent_unwind: cannot panic. 135433d722a9Sopenharmony_ci (*this).capacity() 135533d722a9Sopenharmony_ci } 135633d722a9Sopenharmony_ci #[doc(hidden)] 135733d722a9Sopenharmony_ci #[export_name = #link_data] 135833d722a9Sopenharmony_ci unsafe extern "C" fn #local_data #impl_generics(this: *const ::cxx::private::RustVec<#elem #ty_generics>) -> *const #elem #ty_generics { 135933d722a9Sopenharmony_ci // No prevent_unwind: cannot panic. 136033d722a9Sopenharmony_ci (*this).as_ptr() 136133d722a9Sopenharmony_ci } 136233d722a9Sopenharmony_ci #[doc(hidden)] 136333d722a9Sopenharmony_ci #[export_name = #link_reserve_total] 136433d722a9Sopenharmony_ci unsafe extern "C" fn #local_reserve_total #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, new_cap: usize) { 136533d722a9Sopenharmony_ci // No prevent_unwind: the global allocator is not allowed to panic. 136633d722a9Sopenharmony_ci (*this).reserve_total(new_cap); 136733d722a9Sopenharmony_ci } 136833d722a9Sopenharmony_ci #[doc(hidden)] 136933d722a9Sopenharmony_ci #[export_name = #link_set_len] 137033d722a9Sopenharmony_ci unsafe extern "C" fn #local_set_len #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, len: usize) { 137133d722a9Sopenharmony_ci // No prevent_unwind: cannot panic. 137233d722a9Sopenharmony_ci (*this).set_len(len); 137333d722a9Sopenharmony_ci } 137433d722a9Sopenharmony_ci #[doc(hidden)] 137533d722a9Sopenharmony_ci #[export_name = #link_truncate] 137633d722a9Sopenharmony_ci unsafe extern "C" fn #local_truncate #impl_generics(this: *mut ::cxx::private::RustVec<#elem #ty_generics>, len: usize) { 137733d722a9Sopenharmony_ci let __fn = concat!("<", module_path!(), #prevent_unwind_drop_label); 137833d722a9Sopenharmony_ci ::cxx::private::prevent_unwind(__fn, || (*this).truncate(len)); 137933d722a9Sopenharmony_ci } 138033d722a9Sopenharmony_ci } 138133d722a9Sopenharmony_ci} 138233d722a9Sopenharmony_ci 138333d722a9Sopenharmony_cifn expand_unique_ptr( 138433d722a9Sopenharmony_ci key: NamedImplKey, 138533d722a9Sopenharmony_ci types: &Types, 138633d722a9Sopenharmony_ci explicit_impl: Option<&Impl>, 138733d722a9Sopenharmony_ci) -> TokenStream { 138833d722a9Sopenharmony_ci let ident = key.rust; 138933d722a9Sopenharmony_ci let name = ident.to_string(); 139033d722a9Sopenharmony_ci let resolve = types.resolve(ident); 139133d722a9Sopenharmony_ci let prefix = format!("cxxbridge1$unique_ptr${}$", resolve.name.to_symbol()); 139233d722a9Sopenharmony_ci let link_null = format!("{}null", prefix); 139333d722a9Sopenharmony_ci let link_uninit = format!("{}uninit", prefix); 139433d722a9Sopenharmony_ci let link_raw = format!("{}raw", prefix); 139533d722a9Sopenharmony_ci let link_get = format!("{}get", prefix); 139633d722a9Sopenharmony_ci let link_release = format!("{}release", prefix); 139733d722a9Sopenharmony_ci let link_drop = format!("{}drop", prefix); 139833d722a9Sopenharmony_ci 139933d722a9Sopenharmony_ci let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); 140033d722a9Sopenharmony_ci 140133d722a9Sopenharmony_ci let can_construct_from_value = types.is_maybe_trivial(ident); 140233d722a9Sopenharmony_ci let new_method = if can_construct_from_value { 140333d722a9Sopenharmony_ci Some(quote! { 140433d722a9Sopenharmony_ci fn __new(value: Self) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> { 140533d722a9Sopenharmony_ci extern "C" { 140633d722a9Sopenharmony_ci #[link_name = #link_uninit] 140733d722a9Sopenharmony_ci fn __uninit(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::core::ffi::c_void; 140833d722a9Sopenharmony_ci } 140933d722a9Sopenharmony_ci let mut repr = ::cxx::core::mem::MaybeUninit::uninit(); 141033d722a9Sopenharmony_ci unsafe { __uninit(&mut repr).cast::<#ident #ty_generics>().write(value) } 141133d722a9Sopenharmony_ci repr 141233d722a9Sopenharmony_ci } 141333d722a9Sopenharmony_ci }) 141433d722a9Sopenharmony_ci } else { 141533d722a9Sopenharmony_ci None 141633d722a9Sopenharmony_ci }; 141733d722a9Sopenharmony_ci 141833d722a9Sopenharmony_ci let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); 141933d722a9Sopenharmony_ci let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join()); 142033d722a9Sopenharmony_ci let unsafe_token = format_ident!("unsafe", span = begin_span); 142133d722a9Sopenharmony_ci 142233d722a9Sopenharmony_ci quote_spanned! {end_span=> 142333d722a9Sopenharmony_ci #unsafe_token impl #impl_generics ::cxx::private::UniquePtrTarget for #ident #ty_generics { 142433d722a9Sopenharmony_ci fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result { 142533d722a9Sopenharmony_ci f.write_str(#name) 142633d722a9Sopenharmony_ci } 142733d722a9Sopenharmony_ci fn __null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> { 142833d722a9Sopenharmony_ci extern "C" { 142933d722a9Sopenharmony_ci #[link_name = #link_null] 143033d722a9Sopenharmony_ci fn __null(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>); 143133d722a9Sopenharmony_ci } 143233d722a9Sopenharmony_ci let mut repr = ::cxx::core::mem::MaybeUninit::uninit(); 143333d722a9Sopenharmony_ci unsafe { __null(&mut repr) } 143433d722a9Sopenharmony_ci repr 143533d722a9Sopenharmony_ci } 143633d722a9Sopenharmony_ci #new_method 143733d722a9Sopenharmony_ci unsafe fn __raw(raw: *mut Self) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> { 143833d722a9Sopenharmony_ci extern "C" { 143933d722a9Sopenharmony_ci #[link_name = #link_raw] 144033d722a9Sopenharmony_ci fn __raw(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::core::ffi::c_void); 144133d722a9Sopenharmony_ci } 144233d722a9Sopenharmony_ci let mut repr = ::cxx::core::mem::MaybeUninit::uninit(); 144333d722a9Sopenharmony_ci __raw(&mut repr, raw.cast()); 144433d722a9Sopenharmony_ci repr 144533d722a9Sopenharmony_ci } 144633d722a9Sopenharmony_ci unsafe fn __get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const Self { 144733d722a9Sopenharmony_ci extern "C" { 144833d722a9Sopenharmony_ci #[link_name = #link_get] 144933d722a9Sopenharmony_ci fn __get(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::core::ffi::c_void; 145033d722a9Sopenharmony_ci } 145133d722a9Sopenharmony_ci __get(&repr).cast() 145233d722a9Sopenharmony_ci } 145333d722a9Sopenharmony_ci unsafe fn __release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut Self { 145433d722a9Sopenharmony_ci extern "C" { 145533d722a9Sopenharmony_ci #[link_name = #link_release] 145633d722a9Sopenharmony_ci fn __release(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::core::ffi::c_void; 145733d722a9Sopenharmony_ci } 145833d722a9Sopenharmony_ci __release(&mut repr).cast() 145933d722a9Sopenharmony_ci } 146033d722a9Sopenharmony_ci unsafe fn __drop(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) { 146133d722a9Sopenharmony_ci extern "C" { 146233d722a9Sopenharmony_ci #[link_name = #link_drop] 146333d722a9Sopenharmony_ci fn __drop(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>); 146433d722a9Sopenharmony_ci } 146533d722a9Sopenharmony_ci __drop(&mut repr); 146633d722a9Sopenharmony_ci } 146733d722a9Sopenharmony_ci } 146833d722a9Sopenharmony_ci } 146933d722a9Sopenharmony_ci} 147033d722a9Sopenharmony_ci 147133d722a9Sopenharmony_cifn expand_shared_ptr( 147233d722a9Sopenharmony_ci key: NamedImplKey, 147333d722a9Sopenharmony_ci types: &Types, 147433d722a9Sopenharmony_ci explicit_impl: Option<&Impl>, 147533d722a9Sopenharmony_ci) -> TokenStream { 147633d722a9Sopenharmony_ci let ident = key.rust; 147733d722a9Sopenharmony_ci let name = ident.to_string(); 147833d722a9Sopenharmony_ci let resolve = types.resolve(ident); 147933d722a9Sopenharmony_ci let prefix = format!("cxxbridge1$shared_ptr${}$", resolve.name.to_symbol()); 148033d722a9Sopenharmony_ci let link_null = format!("{}null", prefix); 148133d722a9Sopenharmony_ci let link_uninit = format!("{}uninit", prefix); 148233d722a9Sopenharmony_ci let link_clone = format!("{}clone", prefix); 148333d722a9Sopenharmony_ci let link_get = format!("{}get", prefix); 148433d722a9Sopenharmony_ci let link_drop = format!("{}drop", prefix); 148533d722a9Sopenharmony_ci 148633d722a9Sopenharmony_ci let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); 148733d722a9Sopenharmony_ci 148833d722a9Sopenharmony_ci let can_construct_from_value = types.is_maybe_trivial(ident); 148933d722a9Sopenharmony_ci let new_method = if can_construct_from_value { 149033d722a9Sopenharmony_ci Some(quote! { 149133d722a9Sopenharmony_ci unsafe fn __new(value: Self, new: *mut ::cxx::core::ffi::c_void) { 149233d722a9Sopenharmony_ci extern "C" { 149333d722a9Sopenharmony_ci #[link_name = #link_uninit] 149433d722a9Sopenharmony_ci fn __uninit(new: *mut ::cxx::core::ffi::c_void) -> *mut ::cxx::core::ffi::c_void; 149533d722a9Sopenharmony_ci } 149633d722a9Sopenharmony_ci __uninit(new).cast::<#ident #ty_generics>().write(value); 149733d722a9Sopenharmony_ci } 149833d722a9Sopenharmony_ci }) 149933d722a9Sopenharmony_ci } else { 150033d722a9Sopenharmony_ci None 150133d722a9Sopenharmony_ci }; 150233d722a9Sopenharmony_ci 150333d722a9Sopenharmony_ci let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); 150433d722a9Sopenharmony_ci let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join()); 150533d722a9Sopenharmony_ci let unsafe_token = format_ident!("unsafe", span = begin_span); 150633d722a9Sopenharmony_ci 150733d722a9Sopenharmony_ci quote_spanned! {end_span=> 150833d722a9Sopenharmony_ci #unsafe_token impl #impl_generics ::cxx::private::SharedPtrTarget for #ident #ty_generics { 150933d722a9Sopenharmony_ci fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result { 151033d722a9Sopenharmony_ci f.write_str(#name) 151133d722a9Sopenharmony_ci } 151233d722a9Sopenharmony_ci unsafe fn __null(new: *mut ::cxx::core::ffi::c_void) { 151333d722a9Sopenharmony_ci extern "C" { 151433d722a9Sopenharmony_ci #[link_name = #link_null] 151533d722a9Sopenharmony_ci fn __null(new: *mut ::cxx::core::ffi::c_void); 151633d722a9Sopenharmony_ci } 151733d722a9Sopenharmony_ci __null(new); 151833d722a9Sopenharmony_ci } 151933d722a9Sopenharmony_ci #new_method 152033d722a9Sopenharmony_ci unsafe fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void) { 152133d722a9Sopenharmony_ci extern "C" { 152233d722a9Sopenharmony_ci #[link_name = #link_clone] 152333d722a9Sopenharmony_ci fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void); 152433d722a9Sopenharmony_ci } 152533d722a9Sopenharmony_ci __clone(this, new); 152633d722a9Sopenharmony_ci } 152733d722a9Sopenharmony_ci unsafe fn __get(this: *const ::cxx::core::ffi::c_void) -> *const Self { 152833d722a9Sopenharmony_ci extern "C" { 152933d722a9Sopenharmony_ci #[link_name = #link_get] 153033d722a9Sopenharmony_ci fn __get(this: *const ::cxx::core::ffi::c_void) -> *const ::cxx::core::ffi::c_void; 153133d722a9Sopenharmony_ci } 153233d722a9Sopenharmony_ci __get(this).cast() 153333d722a9Sopenharmony_ci } 153433d722a9Sopenharmony_ci unsafe fn __drop(this: *mut ::cxx::core::ffi::c_void) { 153533d722a9Sopenharmony_ci extern "C" { 153633d722a9Sopenharmony_ci #[link_name = #link_drop] 153733d722a9Sopenharmony_ci fn __drop(this: *mut ::cxx::core::ffi::c_void); 153833d722a9Sopenharmony_ci } 153933d722a9Sopenharmony_ci __drop(this); 154033d722a9Sopenharmony_ci } 154133d722a9Sopenharmony_ci } 154233d722a9Sopenharmony_ci } 154333d722a9Sopenharmony_ci} 154433d722a9Sopenharmony_ci 154533d722a9Sopenharmony_cifn expand_weak_ptr(key: NamedImplKey, types: &Types, explicit_impl: Option<&Impl>) -> TokenStream { 154633d722a9Sopenharmony_ci let ident = key.rust; 154733d722a9Sopenharmony_ci let name = ident.to_string(); 154833d722a9Sopenharmony_ci let resolve = types.resolve(ident); 154933d722a9Sopenharmony_ci let prefix = format!("cxxbridge1$weak_ptr${}$", resolve.name.to_symbol()); 155033d722a9Sopenharmony_ci let link_null = format!("{}null", prefix); 155133d722a9Sopenharmony_ci let link_clone = format!("{}clone", prefix); 155233d722a9Sopenharmony_ci let link_downgrade = format!("{}downgrade", prefix); 155333d722a9Sopenharmony_ci let link_upgrade = format!("{}upgrade", prefix); 155433d722a9Sopenharmony_ci let link_drop = format!("{}drop", prefix); 155533d722a9Sopenharmony_ci 155633d722a9Sopenharmony_ci let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); 155733d722a9Sopenharmony_ci 155833d722a9Sopenharmony_ci let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); 155933d722a9Sopenharmony_ci let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join()); 156033d722a9Sopenharmony_ci let unsafe_token = format_ident!("unsafe", span = begin_span); 156133d722a9Sopenharmony_ci 156233d722a9Sopenharmony_ci quote_spanned! {end_span=> 156333d722a9Sopenharmony_ci #unsafe_token impl #impl_generics ::cxx::private::WeakPtrTarget for #ident #ty_generics { 156433d722a9Sopenharmony_ci fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result { 156533d722a9Sopenharmony_ci f.write_str(#name) 156633d722a9Sopenharmony_ci } 156733d722a9Sopenharmony_ci unsafe fn __null(new: *mut ::cxx::core::ffi::c_void) { 156833d722a9Sopenharmony_ci extern "C" { 156933d722a9Sopenharmony_ci #[link_name = #link_null] 157033d722a9Sopenharmony_ci fn __null(new: *mut ::cxx::core::ffi::c_void); 157133d722a9Sopenharmony_ci } 157233d722a9Sopenharmony_ci __null(new); 157333d722a9Sopenharmony_ci } 157433d722a9Sopenharmony_ci unsafe fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void) { 157533d722a9Sopenharmony_ci extern "C" { 157633d722a9Sopenharmony_ci #[link_name = #link_clone] 157733d722a9Sopenharmony_ci fn __clone(this: *const ::cxx::core::ffi::c_void, new: *mut ::cxx::core::ffi::c_void); 157833d722a9Sopenharmony_ci } 157933d722a9Sopenharmony_ci __clone(this, new); 158033d722a9Sopenharmony_ci } 158133d722a9Sopenharmony_ci unsafe fn __downgrade(shared: *const ::cxx::core::ffi::c_void, weak: *mut ::cxx::core::ffi::c_void) { 158233d722a9Sopenharmony_ci extern "C" { 158333d722a9Sopenharmony_ci #[link_name = #link_downgrade] 158433d722a9Sopenharmony_ci fn __downgrade(shared: *const ::cxx::core::ffi::c_void, weak: *mut ::cxx::core::ffi::c_void); 158533d722a9Sopenharmony_ci } 158633d722a9Sopenharmony_ci __downgrade(shared, weak); 158733d722a9Sopenharmony_ci } 158833d722a9Sopenharmony_ci unsafe fn __upgrade(weak: *const ::cxx::core::ffi::c_void, shared: *mut ::cxx::core::ffi::c_void) { 158933d722a9Sopenharmony_ci extern "C" { 159033d722a9Sopenharmony_ci #[link_name = #link_upgrade] 159133d722a9Sopenharmony_ci fn __upgrade(weak: *const ::cxx::core::ffi::c_void, shared: *mut ::cxx::core::ffi::c_void); 159233d722a9Sopenharmony_ci } 159333d722a9Sopenharmony_ci __upgrade(weak, shared); 159433d722a9Sopenharmony_ci } 159533d722a9Sopenharmony_ci unsafe fn __drop(this: *mut ::cxx::core::ffi::c_void) { 159633d722a9Sopenharmony_ci extern "C" { 159733d722a9Sopenharmony_ci #[link_name = #link_drop] 159833d722a9Sopenharmony_ci fn __drop(this: *mut ::cxx::core::ffi::c_void); 159933d722a9Sopenharmony_ci } 160033d722a9Sopenharmony_ci __drop(this); 160133d722a9Sopenharmony_ci } 160233d722a9Sopenharmony_ci } 160333d722a9Sopenharmony_ci } 160433d722a9Sopenharmony_ci} 160533d722a9Sopenharmony_ci 160633d722a9Sopenharmony_cifn expand_cxx_vector( 160733d722a9Sopenharmony_ci key: NamedImplKey, 160833d722a9Sopenharmony_ci explicit_impl: Option<&Impl>, 160933d722a9Sopenharmony_ci types: &Types, 161033d722a9Sopenharmony_ci) -> TokenStream { 161133d722a9Sopenharmony_ci let elem = key.rust; 161233d722a9Sopenharmony_ci let name = elem.to_string(); 161333d722a9Sopenharmony_ci let resolve = types.resolve(elem); 161433d722a9Sopenharmony_ci let prefix = format!("cxxbridge1$std$vector${}$", resolve.name.to_symbol()); 161533d722a9Sopenharmony_ci let link_size = format!("{}size", prefix); 161633d722a9Sopenharmony_ci let link_get_unchecked = format!("{}get_unchecked", prefix); 161733d722a9Sopenharmony_ci let link_push_back = format!("{}push_back", prefix); 161833d722a9Sopenharmony_ci let link_pop_back = format!("{}pop_back", prefix); 161933d722a9Sopenharmony_ci let unique_ptr_prefix = format!( 162033d722a9Sopenharmony_ci "cxxbridge1$unique_ptr$std$vector${}$", 162133d722a9Sopenharmony_ci resolve.name.to_symbol(), 162233d722a9Sopenharmony_ci ); 162333d722a9Sopenharmony_ci let link_unique_ptr_null = format!("{}null", unique_ptr_prefix); 162433d722a9Sopenharmony_ci let link_unique_ptr_raw = format!("{}raw", unique_ptr_prefix); 162533d722a9Sopenharmony_ci let link_unique_ptr_get = format!("{}get", unique_ptr_prefix); 162633d722a9Sopenharmony_ci let link_unique_ptr_release = format!("{}release", unique_ptr_prefix); 162733d722a9Sopenharmony_ci let link_unique_ptr_drop = format!("{}drop", unique_ptr_prefix); 162833d722a9Sopenharmony_ci 162933d722a9Sopenharmony_ci let (impl_generics, ty_generics) = generics::split_for_impl(key, explicit_impl, resolve); 163033d722a9Sopenharmony_ci 163133d722a9Sopenharmony_ci let begin_span = explicit_impl.map_or(key.begin_span, |explicit| explicit.impl_token.span); 163233d722a9Sopenharmony_ci let end_span = explicit_impl.map_or(key.end_span, |explicit| explicit.brace_token.span.join()); 163333d722a9Sopenharmony_ci let unsafe_token = format_ident!("unsafe", span = begin_span); 163433d722a9Sopenharmony_ci 163533d722a9Sopenharmony_ci let can_pass_element_by_value = types.is_maybe_trivial(elem); 163633d722a9Sopenharmony_ci let by_value_methods = if can_pass_element_by_value { 163733d722a9Sopenharmony_ci Some(quote_spanned! {end_span=> 163833d722a9Sopenharmony_ci unsafe fn __push_back( 163933d722a9Sopenharmony_ci this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>, 164033d722a9Sopenharmony_ci value: &mut ::cxx::core::mem::ManuallyDrop<Self>, 164133d722a9Sopenharmony_ci ) { 164233d722a9Sopenharmony_ci extern "C" { 164333d722a9Sopenharmony_ci #[link_name = #link_push_back] 164433d722a9Sopenharmony_ci fn __push_back #impl_generics( 164533d722a9Sopenharmony_ci this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>, 164633d722a9Sopenharmony_ci value: *mut ::cxx::core::ffi::c_void, 164733d722a9Sopenharmony_ci ); 164833d722a9Sopenharmony_ci } 164933d722a9Sopenharmony_ci __push_back(this, value as *mut ::cxx::core::mem::ManuallyDrop<Self> as *mut ::cxx::core::ffi::c_void); 165033d722a9Sopenharmony_ci } 165133d722a9Sopenharmony_ci unsafe fn __pop_back( 165233d722a9Sopenharmony_ci this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<Self>>, 165333d722a9Sopenharmony_ci out: &mut ::cxx::core::mem::MaybeUninit<Self>, 165433d722a9Sopenharmony_ci ) { 165533d722a9Sopenharmony_ci extern "C" { 165633d722a9Sopenharmony_ci #[link_name = #link_pop_back] 165733d722a9Sopenharmony_ci fn __pop_back #impl_generics( 165833d722a9Sopenharmony_ci this: ::cxx::core::pin::Pin<&mut ::cxx::CxxVector<#elem #ty_generics>>, 165933d722a9Sopenharmony_ci out: *mut ::cxx::core::ffi::c_void, 166033d722a9Sopenharmony_ci ); 166133d722a9Sopenharmony_ci } 166233d722a9Sopenharmony_ci __pop_back(this, out as *mut ::cxx::core::mem::MaybeUninit<Self> as *mut ::cxx::core::ffi::c_void); 166333d722a9Sopenharmony_ci } 166433d722a9Sopenharmony_ci }) 166533d722a9Sopenharmony_ci } else { 166633d722a9Sopenharmony_ci None 166733d722a9Sopenharmony_ci }; 166833d722a9Sopenharmony_ci 166933d722a9Sopenharmony_ci quote_spanned! {end_span=> 167033d722a9Sopenharmony_ci #unsafe_token impl #impl_generics ::cxx::private::VectorElement for #elem #ty_generics { 167133d722a9Sopenharmony_ci fn __typename(f: &mut ::cxx::core::fmt::Formatter<'_>) -> ::cxx::core::fmt::Result { 167233d722a9Sopenharmony_ci f.write_str(#name) 167333d722a9Sopenharmony_ci } 167433d722a9Sopenharmony_ci fn __vector_size(v: &::cxx::CxxVector<Self>) -> usize { 167533d722a9Sopenharmony_ci extern "C" { 167633d722a9Sopenharmony_ci #[link_name = #link_size] 167733d722a9Sopenharmony_ci fn __vector_size #impl_generics(_: &::cxx::CxxVector<#elem #ty_generics>) -> usize; 167833d722a9Sopenharmony_ci } 167933d722a9Sopenharmony_ci unsafe { __vector_size(v) } 168033d722a9Sopenharmony_ci } 168133d722a9Sopenharmony_ci unsafe fn __get_unchecked(v: *mut ::cxx::CxxVector<Self>, pos: usize) -> *mut Self { 168233d722a9Sopenharmony_ci extern "C" { 168333d722a9Sopenharmony_ci #[link_name = #link_get_unchecked] 168433d722a9Sopenharmony_ci fn __get_unchecked #impl_generics( 168533d722a9Sopenharmony_ci v: *mut ::cxx::CxxVector<#elem #ty_generics>, 168633d722a9Sopenharmony_ci pos: usize, 168733d722a9Sopenharmony_ci ) -> *mut ::cxx::core::ffi::c_void; 168833d722a9Sopenharmony_ci } 168933d722a9Sopenharmony_ci __get_unchecked(v, pos) as *mut Self 169033d722a9Sopenharmony_ci } 169133d722a9Sopenharmony_ci #by_value_methods 169233d722a9Sopenharmony_ci fn __unique_ptr_null() -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> { 169333d722a9Sopenharmony_ci extern "C" { 169433d722a9Sopenharmony_ci #[link_name = #link_unique_ptr_null] 169533d722a9Sopenharmony_ci fn __unique_ptr_null(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>); 169633d722a9Sopenharmony_ci } 169733d722a9Sopenharmony_ci let mut repr = ::cxx::core::mem::MaybeUninit::uninit(); 169833d722a9Sopenharmony_ci unsafe { __unique_ptr_null(&mut repr) } 169933d722a9Sopenharmony_ci repr 170033d722a9Sopenharmony_ci } 170133d722a9Sopenharmony_ci unsafe fn __unique_ptr_raw(raw: *mut ::cxx::CxxVector<Self>) -> ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void> { 170233d722a9Sopenharmony_ci extern "C" { 170333d722a9Sopenharmony_ci #[link_name = #link_unique_ptr_raw] 170433d722a9Sopenharmony_ci fn __unique_ptr_raw #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>, raw: *mut ::cxx::CxxVector<#elem #ty_generics>); 170533d722a9Sopenharmony_ci } 170633d722a9Sopenharmony_ci let mut repr = ::cxx::core::mem::MaybeUninit::uninit(); 170733d722a9Sopenharmony_ci __unique_ptr_raw(&mut repr, raw); 170833d722a9Sopenharmony_ci repr 170933d722a9Sopenharmony_ci } 171033d722a9Sopenharmony_ci unsafe fn __unique_ptr_get(repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<Self> { 171133d722a9Sopenharmony_ci extern "C" { 171233d722a9Sopenharmony_ci #[link_name = #link_unique_ptr_get] 171333d722a9Sopenharmony_ci fn __unique_ptr_get #impl_generics(this: *const ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *const ::cxx::CxxVector<#elem #ty_generics>; 171433d722a9Sopenharmony_ci } 171533d722a9Sopenharmony_ci __unique_ptr_get(&repr) 171633d722a9Sopenharmony_ci } 171733d722a9Sopenharmony_ci unsafe fn __unique_ptr_release(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<Self> { 171833d722a9Sopenharmony_ci extern "C" { 171933d722a9Sopenharmony_ci #[link_name = #link_unique_ptr_release] 172033d722a9Sopenharmony_ci fn __unique_ptr_release #impl_generics(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) -> *mut ::cxx::CxxVector<#elem #ty_generics>; 172133d722a9Sopenharmony_ci } 172233d722a9Sopenharmony_ci __unique_ptr_release(&mut repr) 172333d722a9Sopenharmony_ci } 172433d722a9Sopenharmony_ci unsafe fn __unique_ptr_drop(mut repr: ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>) { 172533d722a9Sopenharmony_ci extern "C" { 172633d722a9Sopenharmony_ci #[link_name = #link_unique_ptr_drop] 172733d722a9Sopenharmony_ci fn __unique_ptr_drop(this: *mut ::cxx::core::mem::MaybeUninit<*mut ::cxx::core::ffi::c_void>); 172833d722a9Sopenharmony_ci } 172933d722a9Sopenharmony_ci __unique_ptr_drop(&mut repr); 173033d722a9Sopenharmony_ci } 173133d722a9Sopenharmony_ci } 173233d722a9Sopenharmony_ci } 173333d722a9Sopenharmony_ci} 173433d722a9Sopenharmony_ci 173533d722a9Sopenharmony_cifn expand_return_type(ret: &Option<Type>) -> TokenStream { 173633d722a9Sopenharmony_ci match ret { 173733d722a9Sopenharmony_ci Some(ret) => quote!(-> #ret), 173833d722a9Sopenharmony_ci None => TokenStream::new(), 173933d722a9Sopenharmony_ci } 174033d722a9Sopenharmony_ci} 174133d722a9Sopenharmony_ci 174233d722a9Sopenharmony_cifn indirect_return(sig: &Signature, types: &Types) -> bool { 174333d722a9Sopenharmony_ci sig.ret 174433d722a9Sopenharmony_ci .as_ref() 174533d722a9Sopenharmony_ci .map_or(false, |ret| sig.throws || types.needs_indirect_abi(ret)) 174633d722a9Sopenharmony_ci} 174733d722a9Sopenharmony_ci 174833d722a9Sopenharmony_cifn expand_extern_type(ty: &Type, types: &Types, proper: bool) -> TokenStream { 174933d722a9Sopenharmony_ci match ty { 175033d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => { 175133d722a9Sopenharmony_ci let span = ident.rust.span(); 175233d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::private::RustString) 175333d722a9Sopenharmony_ci } 175433d722a9Sopenharmony_ci Type::RustBox(ty) | Type::UniquePtr(ty) => { 175533d722a9Sopenharmony_ci let span = ty.name.span(); 175633d722a9Sopenharmony_ci if proper && types.is_considered_improper_ctype(&ty.inner) { 175733d722a9Sopenharmony_ci quote_spanned!(span=> *mut ::cxx::core::ffi::c_void) 175833d722a9Sopenharmony_ci } else { 175933d722a9Sopenharmony_ci let inner = expand_extern_type(&ty.inner, types, proper); 176033d722a9Sopenharmony_ci quote_spanned!(span=> *mut #inner) 176133d722a9Sopenharmony_ci } 176233d722a9Sopenharmony_ci } 176333d722a9Sopenharmony_ci Type::RustVec(ty) => { 176433d722a9Sopenharmony_ci let span = ty.name.span(); 176533d722a9Sopenharmony_ci let langle = ty.langle; 176633d722a9Sopenharmony_ci let elem = expand_extern_type(&ty.inner, types, proper); 176733d722a9Sopenharmony_ci let rangle = ty.rangle; 176833d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::private::RustVec #langle #elem #rangle) 176933d722a9Sopenharmony_ci } 177033d722a9Sopenharmony_ci Type::Ref(ty) => { 177133d722a9Sopenharmony_ci let ampersand = ty.ampersand; 177233d722a9Sopenharmony_ci let lifetime = &ty.lifetime; 177333d722a9Sopenharmony_ci let mutability = ty.mutability; 177433d722a9Sopenharmony_ci match &ty.inner { 177533d722a9Sopenharmony_ci Type::Ident(ident) if ident.rust == RustString => { 177633d722a9Sopenharmony_ci let span = ident.rust.span(); 177733d722a9Sopenharmony_ci quote_spanned!(span=> #ampersand #lifetime #mutability ::cxx::private::RustString) 177833d722a9Sopenharmony_ci } 177933d722a9Sopenharmony_ci Type::RustVec(ty) => { 178033d722a9Sopenharmony_ci let span = ty.name.span(); 178133d722a9Sopenharmony_ci let langle = ty.langle; 178233d722a9Sopenharmony_ci let inner = expand_extern_type(&ty.inner, types, proper); 178333d722a9Sopenharmony_ci let rangle = ty.rangle; 178433d722a9Sopenharmony_ci quote_spanned!(span=> #ampersand #lifetime #mutability ::cxx::private::RustVec #langle #inner #rangle) 178533d722a9Sopenharmony_ci } 178633d722a9Sopenharmony_ci inner if proper && types.is_considered_improper_ctype(inner) => { 178733d722a9Sopenharmony_ci let star = Token; 178833d722a9Sopenharmony_ci match ty.mutable { 178933d722a9Sopenharmony_ci false => quote!(#star const ::cxx::core::ffi::c_void), 179033d722a9Sopenharmony_ci true => quote!(#star #mutability ::cxx::core::ffi::c_void), 179133d722a9Sopenharmony_ci } 179233d722a9Sopenharmony_ci } 179333d722a9Sopenharmony_ci _ => quote!(#ty), 179433d722a9Sopenharmony_ci } 179533d722a9Sopenharmony_ci } 179633d722a9Sopenharmony_ci Type::Ptr(ty) => { 179733d722a9Sopenharmony_ci if proper && types.is_considered_improper_ctype(&ty.inner) { 179833d722a9Sopenharmony_ci let star = ty.star; 179933d722a9Sopenharmony_ci let mutability = ty.mutability; 180033d722a9Sopenharmony_ci let constness = ty.constness; 180133d722a9Sopenharmony_ci quote!(#star #mutability #constness ::cxx::core::ffi::c_void) 180233d722a9Sopenharmony_ci } else { 180333d722a9Sopenharmony_ci quote!(#ty) 180433d722a9Sopenharmony_ci } 180533d722a9Sopenharmony_ci } 180633d722a9Sopenharmony_ci Type::Str(ty) => { 180733d722a9Sopenharmony_ci let span = ty.ampersand.span; 180833d722a9Sopenharmony_ci let rust_str = Ident::new("RustStr", syn::spanned::Spanned::span(&ty.inner)); 180933d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::private::#rust_str) 181033d722a9Sopenharmony_ci } 181133d722a9Sopenharmony_ci Type::SliceRef(ty) => { 181233d722a9Sopenharmony_ci let span = ty.ampersand.span; 181333d722a9Sopenharmony_ci let rust_slice = Ident::new("RustSlice", ty.bracket.span.join()); 181433d722a9Sopenharmony_ci quote_spanned!(span=> ::cxx::private::#rust_slice) 181533d722a9Sopenharmony_ci } 181633d722a9Sopenharmony_ci _ => quote!(#ty), 181733d722a9Sopenharmony_ci } 181833d722a9Sopenharmony_ci} 181933d722a9Sopenharmony_ci 182033d722a9Sopenharmony_cifn expand_extern_return_type(ret: &Option<Type>, types: &Types, proper: bool) -> TokenStream { 182133d722a9Sopenharmony_ci let ret = match ret { 182233d722a9Sopenharmony_ci Some(ret) if !types.needs_indirect_abi(ret) => ret, 182333d722a9Sopenharmony_ci _ => return TokenStream::new(), 182433d722a9Sopenharmony_ci }; 182533d722a9Sopenharmony_ci let ty = expand_extern_type(ret, types, proper); 182633d722a9Sopenharmony_ci quote!(-> #ty) 182733d722a9Sopenharmony_ci} 1828