133d722a9Sopenharmony_ciuse crate::gen::block::Block; 233d722a9Sopenharmony_ciuse crate::gen::nested::NamespaceEntries; 333d722a9Sopenharmony_ciuse crate::gen::out::OutFile; 433d722a9Sopenharmony_ciuse crate::gen::{builtin, include, Opt}; 533d722a9Sopenharmony_ciuse crate::syntax::atom::Atom::{self, *}; 633d722a9Sopenharmony_ciuse crate::syntax::instantiate::{ImplKey, NamedImplKey}; 733d722a9Sopenharmony_ciuse crate::syntax::map::UnorderedMap as Map; 833d722a9Sopenharmony_ciuse crate::syntax::set::UnorderedSet; 933d722a9Sopenharmony_ciuse crate::syntax::symbol::{self, Symbol}; 1033d722a9Sopenharmony_ciuse crate::syntax::trivial::{self, TrivialReason}; 1133d722a9Sopenharmony_ciuse crate::syntax::{ 1233d722a9Sopenharmony_ci derive, mangle, Api, Doc, Enum, EnumRepr, ExternFn, ExternType, Pair, Signature, Struct, Trait, 1333d722a9Sopenharmony_ci Type, TypeAlias, Types, Var, 1433d722a9Sopenharmony_ci}; 1533d722a9Sopenharmony_ciuse proc_macro2::Ident; 1633d722a9Sopenharmony_ci 1733d722a9Sopenharmony_cipub(super) fn gen(apis: &[Api], types: &Types, opt: &Opt, header: bool) -> Vec<u8> { 1833d722a9Sopenharmony_ci let mut out_file = OutFile::new(header, opt, types); 1933d722a9Sopenharmony_ci let out = &mut out_file; 2033d722a9Sopenharmony_ci 2133d722a9Sopenharmony_ci pick_includes_and_builtins(out, apis); 2233d722a9Sopenharmony_ci out.include.extend(&opt.include); 2333d722a9Sopenharmony_ci 2433d722a9Sopenharmony_ci write_forward_declarations(out, apis); 2533d722a9Sopenharmony_ci write_data_structures(out, apis); 2633d722a9Sopenharmony_ci write_functions(out, apis); 2733d722a9Sopenharmony_ci write_generic_instantiations(out); 2833d722a9Sopenharmony_ci 2933d722a9Sopenharmony_ci builtin::write(out); 3033d722a9Sopenharmony_ci include::write(out); 3133d722a9Sopenharmony_ci 3233d722a9Sopenharmony_ci out_file.content() 3333d722a9Sopenharmony_ci} 3433d722a9Sopenharmony_ci 3533d722a9Sopenharmony_cifn write_forward_declarations(out: &mut OutFile, apis: &[Api]) { 3633d722a9Sopenharmony_ci let needs_forward_declaration = |api: &&Api| match api { 3733d722a9Sopenharmony_ci Api::Struct(_) | Api::CxxType(_) | Api::RustType(_) => true, 3833d722a9Sopenharmony_ci Api::Enum(enm) => !out.types.cxx.contains(&enm.name.rust), 3933d722a9Sopenharmony_ci _ => false, 4033d722a9Sopenharmony_ci }; 4133d722a9Sopenharmony_ci 4233d722a9Sopenharmony_ci let apis_by_namespace = 4333d722a9Sopenharmony_ci NamespaceEntries::new(apis.iter().filter(needs_forward_declaration).collect()); 4433d722a9Sopenharmony_ci 4533d722a9Sopenharmony_ci write(out, &apis_by_namespace, 0); 4633d722a9Sopenharmony_ci 4733d722a9Sopenharmony_ci fn write(out: &mut OutFile, ns_entries: &NamespaceEntries, indent: usize) { 4833d722a9Sopenharmony_ci let apis = ns_entries.direct_content(); 4933d722a9Sopenharmony_ci 5033d722a9Sopenharmony_ci for api in apis { 5133d722a9Sopenharmony_ci write!(out, "{:1$}", "", indent); 5233d722a9Sopenharmony_ci match api { 5333d722a9Sopenharmony_ci Api::Struct(strct) => write_struct_decl(out, &strct.name), 5433d722a9Sopenharmony_ci Api::Enum(enm) => write_enum_decl(out, enm), 5533d722a9Sopenharmony_ci Api::CxxType(ety) => write_struct_using(out, &ety.name), 5633d722a9Sopenharmony_ci Api::RustType(ety) => write_struct_decl(out, &ety.name), 5733d722a9Sopenharmony_ci _ => unreachable!(), 5833d722a9Sopenharmony_ci } 5933d722a9Sopenharmony_ci } 6033d722a9Sopenharmony_ci 6133d722a9Sopenharmony_ci for (namespace, nested_ns_entries) in ns_entries.nested_content() { 6233d722a9Sopenharmony_ci writeln!(out, "{:2$}namespace {} {{", "", namespace, indent); 6333d722a9Sopenharmony_ci write(out, nested_ns_entries, indent + 2); 6433d722a9Sopenharmony_ci writeln!(out, "{:1$}}}", "", indent); 6533d722a9Sopenharmony_ci } 6633d722a9Sopenharmony_ci } 6733d722a9Sopenharmony_ci} 6833d722a9Sopenharmony_ci 6933d722a9Sopenharmony_cifn write_data_structures<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) { 7033d722a9Sopenharmony_ci let mut methods_for_type = Map::new(); 7133d722a9Sopenharmony_ci for api in apis { 7233d722a9Sopenharmony_ci if let Api::CxxFunction(efn) | Api::RustFunction(efn) = api { 7333d722a9Sopenharmony_ci if let Some(receiver) = &efn.sig.receiver { 7433d722a9Sopenharmony_ci methods_for_type 7533d722a9Sopenharmony_ci .entry(&receiver.ty.rust) 7633d722a9Sopenharmony_ci .or_insert_with(Vec::new) 7733d722a9Sopenharmony_ci .push(efn); 7833d722a9Sopenharmony_ci } 7933d722a9Sopenharmony_ci } 8033d722a9Sopenharmony_ci } 8133d722a9Sopenharmony_ci 8233d722a9Sopenharmony_ci let mut structs_written = UnorderedSet::new(); 8333d722a9Sopenharmony_ci let mut toposorted_structs = out.types.toposorted_structs.iter(); 8433d722a9Sopenharmony_ci for api in apis { 8533d722a9Sopenharmony_ci match api { 8633d722a9Sopenharmony_ci Api::Struct(strct) if !structs_written.contains(&strct.name.rust) => { 8733d722a9Sopenharmony_ci for next in &mut toposorted_structs { 8833d722a9Sopenharmony_ci if !out.types.cxx.contains(&strct.name.rust) { 8933d722a9Sopenharmony_ci out.next_section(); 9033d722a9Sopenharmony_ci let methods = methods_for_type 9133d722a9Sopenharmony_ci .get(&strct.name.rust) 9233d722a9Sopenharmony_ci .map(Vec::as_slice) 9333d722a9Sopenharmony_ci .unwrap_or_default(); 9433d722a9Sopenharmony_ci write_struct(out, next, methods); 9533d722a9Sopenharmony_ci } 9633d722a9Sopenharmony_ci structs_written.insert(&next.name.rust); 9733d722a9Sopenharmony_ci if next.name.rust == strct.name.rust { 9833d722a9Sopenharmony_ci break; 9933d722a9Sopenharmony_ci } 10033d722a9Sopenharmony_ci } 10133d722a9Sopenharmony_ci } 10233d722a9Sopenharmony_ci Api::Enum(enm) => { 10333d722a9Sopenharmony_ci out.next_section(); 10433d722a9Sopenharmony_ci if !out.types.cxx.contains(&enm.name.rust) { 10533d722a9Sopenharmony_ci write_enum(out, enm); 10633d722a9Sopenharmony_ci } else if !enm.variants_from_header { 10733d722a9Sopenharmony_ci check_enum(out, enm); 10833d722a9Sopenharmony_ci } 10933d722a9Sopenharmony_ci } 11033d722a9Sopenharmony_ci Api::RustType(ety) => { 11133d722a9Sopenharmony_ci out.next_section(); 11233d722a9Sopenharmony_ci let methods = methods_for_type 11333d722a9Sopenharmony_ci .get(&ety.name.rust) 11433d722a9Sopenharmony_ci .map(Vec::as_slice) 11533d722a9Sopenharmony_ci .unwrap_or_default(); 11633d722a9Sopenharmony_ci write_opaque_type(out, ety, methods); 11733d722a9Sopenharmony_ci } 11833d722a9Sopenharmony_ci _ => {} 11933d722a9Sopenharmony_ci } 12033d722a9Sopenharmony_ci } 12133d722a9Sopenharmony_ci 12233d722a9Sopenharmony_ci if out.header { 12333d722a9Sopenharmony_ci return; 12433d722a9Sopenharmony_ci } 12533d722a9Sopenharmony_ci 12633d722a9Sopenharmony_ci out.set_namespace(Default::default()); 12733d722a9Sopenharmony_ci 12833d722a9Sopenharmony_ci out.next_section(); 12933d722a9Sopenharmony_ci for api in apis { 13033d722a9Sopenharmony_ci if let Api::TypeAlias(ety) = api { 13133d722a9Sopenharmony_ci if let Some(reasons) = out.types.required_trivial.get(&ety.name.rust) { 13233d722a9Sopenharmony_ci check_trivial_extern_type(out, ety, reasons) 13333d722a9Sopenharmony_ci } 13433d722a9Sopenharmony_ci } 13533d722a9Sopenharmony_ci } 13633d722a9Sopenharmony_ci} 13733d722a9Sopenharmony_ci 13833d722a9Sopenharmony_cifn write_functions<'a>(out: &mut OutFile<'a>, apis: &'a [Api]) { 13933d722a9Sopenharmony_ci if !out.header { 14033d722a9Sopenharmony_ci for api in apis { 14133d722a9Sopenharmony_ci match api { 14233d722a9Sopenharmony_ci Api::Struct(strct) => write_struct_operator_decls(out, strct), 14333d722a9Sopenharmony_ci Api::RustType(ety) => write_opaque_type_layout_decls(out, ety), 14433d722a9Sopenharmony_ci Api::CxxFunction(efn) => write_cxx_function_shim(out, efn), 14533d722a9Sopenharmony_ci Api::RustFunction(efn) => write_rust_function_decl(out, efn), 14633d722a9Sopenharmony_ci _ => {} 14733d722a9Sopenharmony_ci } 14833d722a9Sopenharmony_ci } 14933d722a9Sopenharmony_ci 15033d722a9Sopenharmony_ci write_std_specializations(out, apis); 15133d722a9Sopenharmony_ci } 15233d722a9Sopenharmony_ci 15333d722a9Sopenharmony_ci for api in apis { 15433d722a9Sopenharmony_ci match api { 15533d722a9Sopenharmony_ci Api::Struct(strct) => write_struct_operators(out, strct), 15633d722a9Sopenharmony_ci Api::RustType(ety) => write_opaque_type_layout(out, ety), 15733d722a9Sopenharmony_ci Api::RustFunction(efn) => { 15833d722a9Sopenharmony_ci out.next_section(); 15933d722a9Sopenharmony_ci write_rust_function_shim(out, efn); 16033d722a9Sopenharmony_ci } 16133d722a9Sopenharmony_ci _ => {} 16233d722a9Sopenharmony_ci } 16333d722a9Sopenharmony_ci } 16433d722a9Sopenharmony_ci} 16533d722a9Sopenharmony_ci 16633d722a9Sopenharmony_cifn write_std_specializations(out: &mut OutFile, apis: &[Api]) { 16733d722a9Sopenharmony_ci out.set_namespace(Default::default()); 16833d722a9Sopenharmony_ci out.begin_block(Block::Namespace("std")); 16933d722a9Sopenharmony_ci 17033d722a9Sopenharmony_ci for api in apis { 17133d722a9Sopenharmony_ci if let Api::Struct(strct) = api { 17233d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::Hash) { 17333d722a9Sopenharmony_ci out.next_section(); 17433d722a9Sopenharmony_ci out.include.cstddef = true; 17533d722a9Sopenharmony_ci out.include.functional = true; 17633d722a9Sopenharmony_ci let qualified = strct.name.to_fully_qualified(); 17733d722a9Sopenharmony_ci writeln!(out, "template <> struct hash<{}> {{", qualified); 17833d722a9Sopenharmony_ci writeln!( 17933d722a9Sopenharmony_ci out, 18033d722a9Sopenharmony_ci " ::std::size_t operator()({} const &self) const noexcept {{", 18133d722a9Sopenharmony_ci qualified, 18233d722a9Sopenharmony_ci ); 18333d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "hash"); 18433d722a9Sopenharmony_ci write!(out, " return ::"); 18533d722a9Sopenharmony_ci for name in &strct.name.namespace { 18633d722a9Sopenharmony_ci write!(out, "{}::", name); 18733d722a9Sopenharmony_ci } 18833d722a9Sopenharmony_ci writeln!(out, "{}(self);", link_name); 18933d722a9Sopenharmony_ci writeln!(out, " }}"); 19033d722a9Sopenharmony_ci writeln!(out, "}};"); 19133d722a9Sopenharmony_ci } 19233d722a9Sopenharmony_ci } 19333d722a9Sopenharmony_ci } 19433d722a9Sopenharmony_ci 19533d722a9Sopenharmony_ci out.end_block(Block::Namespace("std")); 19633d722a9Sopenharmony_ci} 19733d722a9Sopenharmony_ci 19833d722a9Sopenharmony_cifn pick_includes_and_builtins(out: &mut OutFile, apis: &[Api]) { 19933d722a9Sopenharmony_ci for api in apis { 20033d722a9Sopenharmony_ci if let Api::Include(include) = api { 20133d722a9Sopenharmony_ci out.include.insert(include); 20233d722a9Sopenharmony_ci } 20333d722a9Sopenharmony_ci } 20433d722a9Sopenharmony_ci 20533d722a9Sopenharmony_ci for ty in out.types { 20633d722a9Sopenharmony_ci match ty { 20733d722a9Sopenharmony_ci Type::Ident(ident) => match Atom::from(&ident.rust) { 20833d722a9Sopenharmony_ci Some(U8) | Some(U16) | Some(U32) | Some(U64) | Some(I8) | Some(I16) | Some(I32) 20933d722a9Sopenharmony_ci | Some(I64) => out.include.cstdint = true, 21033d722a9Sopenharmony_ci Some(Usize) => out.include.cstddef = true, 21133d722a9Sopenharmony_ci Some(Isize) => out.builtin.rust_isize = true, 21233d722a9Sopenharmony_ci Some(CxxString) => out.include.string = true, 21333d722a9Sopenharmony_ci Some(RustString) => out.builtin.rust_string = true, 21433d722a9Sopenharmony_ci Some(Bool) | Some(Char) | Some(F32) | Some(F64) | None => {} 21533d722a9Sopenharmony_ci }, 21633d722a9Sopenharmony_ci Type::RustBox(_) => out.builtin.rust_box = true, 21733d722a9Sopenharmony_ci Type::RustVec(_) => out.builtin.rust_vec = true, 21833d722a9Sopenharmony_ci Type::UniquePtr(_) => out.include.memory = true, 21933d722a9Sopenharmony_ci Type::SharedPtr(_) | Type::WeakPtr(_) => out.include.memory = true, 22033d722a9Sopenharmony_ci Type::Str(_) => out.builtin.rust_str = true, 22133d722a9Sopenharmony_ci Type::CxxVector(_) => out.include.vector = true, 22233d722a9Sopenharmony_ci Type::Fn(_) => out.builtin.rust_fn = true, 22333d722a9Sopenharmony_ci Type::SliceRef(_) => out.builtin.rust_slice = true, 22433d722a9Sopenharmony_ci Type::Array(_) => out.include.array = true, 22533d722a9Sopenharmony_ci Type::Ref(_) | Type::Void(_) | Type::Ptr(_) => {} 22633d722a9Sopenharmony_ci } 22733d722a9Sopenharmony_ci } 22833d722a9Sopenharmony_ci} 22933d722a9Sopenharmony_ci 23033d722a9Sopenharmony_cifn write_doc(out: &mut OutFile, indent: &str, doc: &Doc) { 23133d722a9Sopenharmony_ci let mut lines = 0; 23233d722a9Sopenharmony_ci for line in doc.to_string().lines() { 23333d722a9Sopenharmony_ci if out.opt.doxygen { 23433d722a9Sopenharmony_ci writeln!(out, "{}///{}", indent, line); 23533d722a9Sopenharmony_ci } else { 23633d722a9Sopenharmony_ci writeln!(out, "{}//{}", indent, line); 23733d722a9Sopenharmony_ci } 23833d722a9Sopenharmony_ci lines += 1; 23933d722a9Sopenharmony_ci } 24033d722a9Sopenharmony_ci // According to https://www.doxygen.nl/manual/docblocks.html, Doxygen only 24133d722a9Sopenharmony_ci // interprets `///` as a Doxygen comment block if there are at least 2 of 24233d722a9Sopenharmony_ci // them. In Rust, a single `///` is definitely still documentation so we 24333d722a9Sopenharmony_ci // make sure to propagate that as a Doxygen comment. 24433d722a9Sopenharmony_ci if out.opt.doxygen && lines == 1 { 24533d722a9Sopenharmony_ci writeln!(out, "{}///", indent); 24633d722a9Sopenharmony_ci } 24733d722a9Sopenharmony_ci} 24833d722a9Sopenharmony_ci 24933d722a9Sopenharmony_cifn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&ExternFn]) { 25033d722a9Sopenharmony_ci let operator_eq = derive::contains(&strct.derives, Trait::PartialEq); 25133d722a9Sopenharmony_ci let operator_ord = derive::contains(&strct.derives, Trait::PartialOrd); 25233d722a9Sopenharmony_ci 25333d722a9Sopenharmony_ci out.set_namespace(&strct.name.namespace); 25433d722a9Sopenharmony_ci let guard = format!("CXXBRIDGE1_STRUCT_{}", strct.name.to_symbol()); 25533d722a9Sopenharmony_ci writeln!(out, "#ifndef {}", guard); 25633d722a9Sopenharmony_ci writeln!(out, "#define {}", guard); 25733d722a9Sopenharmony_ci write_doc(out, "", &strct.doc); 25833d722a9Sopenharmony_ci writeln!(out, "struct {} final {{", strct.name.cxx); 25933d722a9Sopenharmony_ci 26033d722a9Sopenharmony_ci for field in &strct.fields { 26133d722a9Sopenharmony_ci write_doc(out, " ", &field.doc); 26233d722a9Sopenharmony_ci write!(out, " "); 26333d722a9Sopenharmony_ci write_type_space(out, &field.ty); 26433d722a9Sopenharmony_ci writeln!(out, "{};", field.name.cxx); 26533d722a9Sopenharmony_ci } 26633d722a9Sopenharmony_ci 26733d722a9Sopenharmony_ci out.next_section(); 26833d722a9Sopenharmony_ci 26933d722a9Sopenharmony_ci for method in methods { 27033d722a9Sopenharmony_ci if !method.doc.is_empty() { 27133d722a9Sopenharmony_ci out.next_section(); 27233d722a9Sopenharmony_ci } 27333d722a9Sopenharmony_ci write_doc(out, " ", &method.doc); 27433d722a9Sopenharmony_ci write!(out, " "); 27533d722a9Sopenharmony_ci let sig = &method.sig; 27633d722a9Sopenharmony_ci let local_name = method.name.cxx.to_string(); 27733d722a9Sopenharmony_ci let indirect_call = false; 27833d722a9Sopenharmony_ci write_rust_function_shim_decl(out, &local_name, sig, indirect_call); 27933d722a9Sopenharmony_ci writeln!(out, ";"); 28033d722a9Sopenharmony_ci if !method.doc.is_empty() { 28133d722a9Sopenharmony_ci out.next_section(); 28233d722a9Sopenharmony_ci } 28333d722a9Sopenharmony_ci } 28433d722a9Sopenharmony_ci 28533d722a9Sopenharmony_ci if operator_eq { 28633d722a9Sopenharmony_ci writeln!( 28733d722a9Sopenharmony_ci out, 28833d722a9Sopenharmony_ci " bool operator==({} const &) const noexcept;", 28933d722a9Sopenharmony_ci strct.name.cxx, 29033d722a9Sopenharmony_ci ); 29133d722a9Sopenharmony_ci writeln!( 29233d722a9Sopenharmony_ci out, 29333d722a9Sopenharmony_ci " bool operator!=({} const &) const noexcept;", 29433d722a9Sopenharmony_ci strct.name.cxx, 29533d722a9Sopenharmony_ci ); 29633d722a9Sopenharmony_ci } 29733d722a9Sopenharmony_ci 29833d722a9Sopenharmony_ci if operator_ord { 29933d722a9Sopenharmony_ci writeln!( 30033d722a9Sopenharmony_ci out, 30133d722a9Sopenharmony_ci " bool operator<({} const &) const noexcept;", 30233d722a9Sopenharmony_ci strct.name.cxx, 30333d722a9Sopenharmony_ci ); 30433d722a9Sopenharmony_ci writeln!( 30533d722a9Sopenharmony_ci out, 30633d722a9Sopenharmony_ci " bool operator<=({} const &) const noexcept;", 30733d722a9Sopenharmony_ci strct.name.cxx, 30833d722a9Sopenharmony_ci ); 30933d722a9Sopenharmony_ci writeln!( 31033d722a9Sopenharmony_ci out, 31133d722a9Sopenharmony_ci " bool operator>({} const &) const noexcept;", 31233d722a9Sopenharmony_ci strct.name.cxx, 31333d722a9Sopenharmony_ci ); 31433d722a9Sopenharmony_ci writeln!( 31533d722a9Sopenharmony_ci out, 31633d722a9Sopenharmony_ci " bool operator>=({} const &) const noexcept;", 31733d722a9Sopenharmony_ci strct.name.cxx, 31833d722a9Sopenharmony_ci ); 31933d722a9Sopenharmony_ci } 32033d722a9Sopenharmony_ci 32133d722a9Sopenharmony_ci out.include.type_traits = true; 32233d722a9Sopenharmony_ci writeln!(out, " using IsRelocatable = ::std::true_type;"); 32333d722a9Sopenharmony_ci 32433d722a9Sopenharmony_ci writeln!(out, "}};"); 32533d722a9Sopenharmony_ci writeln!(out, "#endif // {}", guard); 32633d722a9Sopenharmony_ci} 32733d722a9Sopenharmony_ci 32833d722a9Sopenharmony_cifn write_struct_decl(out: &mut OutFile, ident: &Pair) { 32933d722a9Sopenharmony_ci writeln!(out, "struct {};", ident.cxx); 33033d722a9Sopenharmony_ci} 33133d722a9Sopenharmony_ci 33233d722a9Sopenharmony_cifn write_enum_decl(out: &mut OutFile, enm: &Enum) { 33333d722a9Sopenharmony_ci let repr = match &enm.repr { 33433d722a9Sopenharmony_ci #[cfg(feature = "experimental-enum-variants-from-header")] 33533d722a9Sopenharmony_ci EnumRepr::Foreign { .. } => return, 33633d722a9Sopenharmony_ci EnumRepr::Native { atom, .. } => *atom, 33733d722a9Sopenharmony_ci }; 33833d722a9Sopenharmony_ci write!(out, "enum class {} : ", enm.name.cxx); 33933d722a9Sopenharmony_ci write_atom(out, repr); 34033d722a9Sopenharmony_ci writeln!(out, ";"); 34133d722a9Sopenharmony_ci} 34233d722a9Sopenharmony_ci 34333d722a9Sopenharmony_cifn write_struct_using(out: &mut OutFile, ident: &Pair) { 34433d722a9Sopenharmony_ci writeln!(out, "using {} = {};", ident.cxx, ident.to_fully_qualified()); 34533d722a9Sopenharmony_ci} 34633d722a9Sopenharmony_ci 34733d722a9Sopenharmony_cifn write_opaque_type<'a>(out: &mut OutFile<'a>, ety: &'a ExternType, methods: &[&ExternFn]) { 34833d722a9Sopenharmony_ci out.set_namespace(&ety.name.namespace); 34933d722a9Sopenharmony_ci let guard = format!("CXXBRIDGE1_STRUCT_{}", ety.name.to_symbol()); 35033d722a9Sopenharmony_ci writeln!(out, "#ifndef {}", guard); 35133d722a9Sopenharmony_ci writeln!(out, "#define {}", guard); 35233d722a9Sopenharmony_ci write_doc(out, "", &ety.doc); 35333d722a9Sopenharmony_ci 35433d722a9Sopenharmony_ci out.builtin.opaque = true; 35533d722a9Sopenharmony_ci writeln!( 35633d722a9Sopenharmony_ci out, 35733d722a9Sopenharmony_ci "struct {} final : public ::rust::Opaque {{", 35833d722a9Sopenharmony_ci ety.name.cxx, 35933d722a9Sopenharmony_ci ); 36033d722a9Sopenharmony_ci 36133d722a9Sopenharmony_ci for (i, method) in methods.iter().enumerate() { 36233d722a9Sopenharmony_ci if i > 0 && !method.doc.is_empty() { 36333d722a9Sopenharmony_ci out.next_section(); 36433d722a9Sopenharmony_ci } 36533d722a9Sopenharmony_ci write_doc(out, " ", &method.doc); 36633d722a9Sopenharmony_ci write!(out, " "); 36733d722a9Sopenharmony_ci let sig = &method.sig; 36833d722a9Sopenharmony_ci let local_name = method.name.cxx.to_string(); 36933d722a9Sopenharmony_ci let indirect_call = false; 37033d722a9Sopenharmony_ci write_rust_function_shim_decl(out, &local_name, sig, indirect_call); 37133d722a9Sopenharmony_ci writeln!(out, ";"); 37233d722a9Sopenharmony_ci if !method.doc.is_empty() { 37333d722a9Sopenharmony_ci out.next_section(); 37433d722a9Sopenharmony_ci } 37533d722a9Sopenharmony_ci } 37633d722a9Sopenharmony_ci 37733d722a9Sopenharmony_ci writeln!(out, " ~{}() = delete;", ety.name.cxx); 37833d722a9Sopenharmony_ci writeln!(out); 37933d722a9Sopenharmony_ci 38033d722a9Sopenharmony_ci out.builtin.layout = true; 38133d722a9Sopenharmony_ci out.include.cstddef = true; 38233d722a9Sopenharmony_ci writeln!(out, "private:"); 38333d722a9Sopenharmony_ci writeln!(out, " friend ::rust::layout;"); 38433d722a9Sopenharmony_ci writeln!(out, " struct layout {{"); 38533d722a9Sopenharmony_ci writeln!(out, " static ::std::size_t size() noexcept;"); 38633d722a9Sopenharmony_ci writeln!(out, " static ::std::size_t align() noexcept;"); 38733d722a9Sopenharmony_ci writeln!(out, " }};"); 38833d722a9Sopenharmony_ci writeln!(out, "}};"); 38933d722a9Sopenharmony_ci writeln!(out, "#endif // {}", guard); 39033d722a9Sopenharmony_ci} 39133d722a9Sopenharmony_ci 39233d722a9Sopenharmony_cifn write_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) { 39333d722a9Sopenharmony_ci let repr = match &enm.repr { 39433d722a9Sopenharmony_ci #[cfg(feature = "experimental-enum-variants-from-header")] 39533d722a9Sopenharmony_ci EnumRepr::Foreign { .. } => return, 39633d722a9Sopenharmony_ci EnumRepr::Native { atom, .. } => *atom, 39733d722a9Sopenharmony_ci }; 39833d722a9Sopenharmony_ci out.set_namespace(&enm.name.namespace); 39933d722a9Sopenharmony_ci let guard = format!("CXXBRIDGE1_ENUM_{}", enm.name.to_symbol()); 40033d722a9Sopenharmony_ci writeln!(out, "#ifndef {}", guard); 40133d722a9Sopenharmony_ci writeln!(out, "#define {}", guard); 40233d722a9Sopenharmony_ci write_doc(out, "", &enm.doc); 40333d722a9Sopenharmony_ci write!(out, "enum class {} : ", enm.name.cxx); 40433d722a9Sopenharmony_ci write_atom(out, repr); 40533d722a9Sopenharmony_ci writeln!(out, " {{"); 40633d722a9Sopenharmony_ci for variant in &enm.variants { 40733d722a9Sopenharmony_ci write_doc(out, " ", &variant.doc); 40833d722a9Sopenharmony_ci writeln!(out, " {} = {},", variant.name.cxx, variant.discriminant); 40933d722a9Sopenharmony_ci } 41033d722a9Sopenharmony_ci writeln!(out, "}};"); 41133d722a9Sopenharmony_ci writeln!(out, "#endif // {}", guard); 41233d722a9Sopenharmony_ci} 41333d722a9Sopenharmony_ci 41433d722a9Sopenharmony_cifn check_enum<'a>(out: &mut OutFile<'a>, enm: &'a Enum) { 41533d722a9Sopenharmony_ci let repr = match &enm.repr { 41633d722a9Sopenharmony_ci #[cfg(feature = "experimental-enum-variants-from-header")] 41733d722a9Sopenharmony_ci EnumRepr::Foreign { .. } => return, 41833d722a9Sopenharmony_ci EnumRepr::Native { atom, .. } => *atom, 41933d722a9Sopenharmony_ci }; 42033d722a9Sopenharmony_ci out.set_namespace(&enm.name.namespace); 42133d722a9Sopenharmony_ci out.include.type_traits = true; 42233d722a9Sopenharmony_ci writeln!( 42333d722a9Sopenharmony_ci out, 42433d722a9Sopenharmony_ci "static_assert(::std::is_enum<{}>::value, \"expected enum\");", 42533d722a9Sopenharmony_ci enm.name.cxx, 42633d722a9Sopenharmony_ci ); 42733d722a9Sopenharmony_ci write!(out, "static_assert(sizeof({}) == sizeof(", enm.name.cxx); 42833d722a9Sopenharmony_ci write_atom(out, repr); 42933d722a9Sopenharmony_ci writeln!(out, "), \"incorrect size\");"); 43033d722a9Sopenharmony_ci for variant in &enm.variants { 43133d722a9Sopenharmony_ci write!(out, "static_assert(static_cast<"); 43233d722a9Sopenharmony_ci write_atom(out, repr); 43333d722a9Sopenharmony_ci writeln!( 43433d722a9Sopenharmony_ci out, 43533d722a9Sopenharmony_ci ">({}::{}) == {}, \"disagrees with the value in #[cxx::bridge]\");", 43633d722a9Sopenharmony_ci enm.name.cxx, variant.name.cxx, variant.discriminant, 43733d722a9Sopenharmony_ci ); 43833d722a9Sopenharmony_ci } 43933d722a9Sopenharmony_ci} 44033d722a9Sopenharmony_ci 44133d722a9Sopenharmony_cifn check_trivial_extern_type(out: &mut OutFile, alias: &TypeAlias, reasons: &[TrivialReason]) { 44233d722a9Sopenharmony_ci // NOTE: The following static assertion is just nice-to-have and not 44333d722a9Sopenharmony_ci // necessary for soundness. That's because triviality is always declared by 44433d722a9Sopenharmony_ci // the user in the form of an unsafe impl of cxx::ExternType: 44533d722a9Sopenharmony_ci // 44633d722a9Sopenharmony_ci // unsafe impl ExternType for MyType { 44733d722a9Sopenharmony_ci // type Id = cxx::type_id!("..."); 44833d722a9Sopenharmony_ci // type Kind = cxx::kind::Trivial; 44933d722a9Sopenharmony_ci // } 45033d722a9Sopenharmony_ci // 45133d722a9Sopenharmony_ci // Since the user went on the record with their unsafe impl to unsafely 45233d722a9Sopenharmony_ci // claim they KNOW that the type is trivial, it's fine for that to be on 45333d722a9Sopenharmony_ci // them if that were wrong. However, in practice correctly reasoning about 45433d722a9Sopenharmony_ci // the relocatability of C++ types is challenging, particularly if the type 45533d722a9Sopenharmony_ci // definition were to change over time, so for now we add this check. 45633d722a9Sopenharmony_ci // 45733d722a9Sopenharmony_ci // There may be legitimate reasons to opt out of this assertion for support 45833d722a9Sopenharmony_ci // of types that the programmer knows are soundly Rust-movable despite not 45933d722a9Sopenharmony_ci // being recognized as such by the C++ type system due to a move constructor 46033d722a9Sopenharmony_ci // or destructor. To opt out of the relocatability check, they need to do 46133d722a9Sopenharmony_ci // one of the following things in any header used by `include!` in their 46233d722a9Sopenharmony_ci // bridge. 46333d722a9Sopenharmony_ci // 46433d722a9Sopenharmony_ci // --- if they define the type: 46533d722a9Sopenharmony_ci // struct MyType { 46633d722a9Sopenharmony_ci // ... 46733d722a9Sopenharmony_ci // + using IsRelocatable = std::true_type; 46833d722a9Sopenharmony_ci // }; 46933d722a9Sopenharmony_ci // 47033d722a9Sopenharmony_ci // --- otherwise: 47133d722a9Sopenharmony_ci // + template <> 47233d722a9Sopenharmony_ci // + struct rust::IsRelocatable<MyType> : std::true_type {}; 47333d722a9Sopenharmony_ci // 47433d722a9Sopenharmony_ci 47533d722a9Sopenharmony_ci let id = alias.name.to_fully_qualified(); 47633d722a9Sopenharmony_ci out.builtin.relocatable = true; 47733d722a9Sopenharmony_ci writeln!(out, "static_assert("); 47833d722a9Sopenharmony_ci if reasons 47933d722a9Sopenharmony_ci .iter() 48033d722a9Sopenharmony_ci .all(|r| matches!(r, TrivialReason::StructField(_) | TrivialReason::VecElement)) 48133d722a9Sopenharmony_ci { 48233d722a9Sopenharmony_ci // If the type is only used as a struct field or Vec element, not as 48333d722a9Sopenharmony_ci // by-value function argument or return value, then C array of trivially 48433d722a9Sopenharmony_ci // relocatable type is also permissible. 48533d722a9Sopenharmony_ci // 48633d722a9Sopenharmony_ci // --- means something sane: 48733d722a9Sopenharmony_ci // struct T { char buf[N]; }; 48833d722a9Sopenharmony_ci // 48933d722a9Sopenharmony_ci // --- means something totally different: 49033d722a9Sopenharmony_ci // void f(char buf[N]); 49133d722a9Sopenharmony_ci // 49233d722a9Sopenharmony_ci out.builtin.relocatable_or_array = true; 49333d722a9Sopenharmony_ci writeln!(out, " ::rust::IsRelocatableOrArray<{}>::value,", id); 49433d722a9Sopenharmony_ci } else { 49533d722a9Sopenharmony_ci writeln!(out, " ::rust::IsRelocatable<{}>::value,", id); 49633d722a9Sopenharmony_ci } 49733d722a9Sopenharmony_ci writeln!( 49833d722a9Sopenharmony_ci out, 49933d722a9Sopenharmony_ci " \"type {} should be trivially move constructible and trivially destructible in C++ to be used as {} in Rust\");", 50033d722a9Sopenharmony_ci id.trim_start_matches("::"), 50133d722a9Sopenharmony_ci trivial::as_what(&alias.name, reasons), 50233d722a9Sopenharmony_ci ); 50333d722a9Sopenharmony_ci} 50433d722a9Sopenharmony_ci 50533d722a9Sopenharmony_cifn write_struct_operator_decls<'a>(out: &mut OutFile<'a>, strct: &'a Struct) { 50633d722a9Sopenharmony_ci out.set_namespace(&strct.name.namespace); 50733d722a9Sopenharmony_ci out.begin_block(Block::ExternC); 50833d722a9Sopenharmony_ci 50933d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::PartialEq) { 51033d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "eq"); 51133d722a9Sopenharmony_ci writeln!( 51233d722a9Sopenharmony_ci out, 51333d722a9Sopenharmony_ci "bool {}({1} const &, {1} const &) noexcept;", 51433d722a9Sopenharmony_ci link_name, strct.name.cxx, 51533d722a9Sopenharmony_ci ); 51633d722a9Sopenharmony_ci 51733d722a9Sopenharmony_ci if !derive::contains(&strct.derives, Trait::Eq) { 51833d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "ne"); 51933d722a9Sopenharmony_ci writeln!( 52033d722a9Sopenharmony_ci out, 52133d722a9Sopenharmony_ci "bool {}({1} const &, {1} const &) noexcept;", 52233d722a9Sopenharmony_ci link_name, strct.name.cxx, 52333d722a9Sopenharmony_ci ); 52433d722a9Sopenharmony_ci } 52533d722a9Sopenharmony_ci } 52633d722a9Sopenharmony_ci 52733d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::PartialOrd) { 52833d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "lt"); 52933d722a9Sopenharmony_ci writeln!( 53033d722a9Sopenharmony_ci out, 53133d722a9Sopenharmony_ci "bool {}({1} const &, {1} const &) noexcept;", 53233d722a9Sopenharmony_ci link_name, strct.name.cxx, 53333d722a9Sopenharmony_ci ); 53433d722a9Sopenharmony_ci 53533d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "le"); 53633d722a9Sopenharmony_ci writeln!( 53733d722a9Sopenharmony_ci out, 53833d722a9Sopenharmony_ci "bool {}({1} const &, {1} const &) noexcept;", 53933d722a9Sopenharmony_ci link_name, strct.name.cxx, 54033d722a9Sopenharmony_ci ); 54133d722a9Sopenharmony_ci 54233d722a9Sopenharmony_ci if !derive::contains(&strct.derives, Trait::Ord) { 54333d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "gt"); 54433d722a9Sopenharmony_ci writeln!( 54533d722a9Sopenharmony_ci out, 54633d722a9Sopenharmony_ci "bool {}({1} const &, {1} const &) noexcept;", 54733d722a9Sopenharmony_ci link_name, strct.name.cxx, 54833d722a9Sopenharmony_ci ); 54933d722a9Sopenharmony_ci 55033d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "ge"); 55133d722a9Sopenharmony_ci writeln!( 55233d722a9Sopenharmony_ci out, 55333d722a9Sopenharmony_ci "bool {}({1} const &, {1} const &) noexcept;", 55433d722a9Sopenharmony_ci link_name, strct.name.cxx, 55533d722a9Sopenharmony_ci ); 55633d722a9Sopenharmony_ci } 55733d722a9Sopenharmony_ci } 55833d722a9Sopenharmony_ci 55933d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::Hash) { 56033d722a9Sopenharmony_ci out.include.cstddef = true; 56133d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "hash"); 56233d722a9Sopenharmony_ci writeln!( 56333d722a9Sopenharmony_ci out, 56433d722a9Sopenharmony_ci "::std::size_t {}({} const &) noexcept;", 56533d722a9Sopenharmony_ci link_name, strct.name.cxx, 56633d722a9Sopenharmony_ci ); 56733d722a9Sopenharmony_ci } 56833d722a9Sopenharmony_ci 56933d722a9Sopenharmony_ci out.end_block(Block::ExternC); 57033d722a9Sopenharmony_ci} 57133d722a9Sopenharmony_ci 57233d722a9Sopenharmony_cifn write_struct_operators<'a>(out: &mut OutFile<'a>, strct: &'a Struct) { 57333d722a9Sopenharmony_ci if out.header { 57433d722a9Sopenharmony_ci return; 57533d722a9Sopenharmony_ci } 57633d722a9Sopenharmony_ci 57733d722a9Sopenharmony_ci out.set_namespace(&strct.name.namespace); 57833d722a9Sopenharmony_ci 57933d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::PartialEq) { 58033d722a9Sopenharmony_ci out.next_section(); 58133d722a9Sopenharmony_ci writeln!( 58233d722a9Sopenharmony_ci out, 58333d722a9Sopenharmony_ci "bool {0}::operator==({0} const &rhs) const noexcept {{", 58433d722a9Sopenharmony_ci strct.name.cxx, 58533d722a9Sopenharmony_ci ); 58633d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "eq"); 58733d722a9Sopenharmony_ci writeln!(out, " return {}(*this, rhs);", link_name); 58833d722a9Sopenharmony_ci writeln!(out, "}}"); 58933d722a9Sopenharmony_ci 59033d722a9Sopenharmony_ci out.next_section(); 59133d722a9Sopenharmony_ci writeln!( 59233d722a9Sopenharmony_ci out, 59333d722a9Sopenharmony_ci "bool {0}::operator!=({0} const &rhs) const noexcept {{", 59433d722a9Sopenharmony_ci strct.name.cxx, 59533d722a9Sopenharmony_ci ); 59633d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::Eq) { 59733d722a9Sopenharmony_ci writeln!(out, " return !(*this == rhs);"); 59833d722a9Sopenharmony_ci } else { 59933d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "ne"); 60033d722a9Sopenharmony_ci writeln!(out, " return {}(*this, rhs);", link_name); 60133d722a9Sopenharmony_ci } 60233d722a9Sopenharmony_ci writeln!(out, "}}"); 60333d722a9Sopenharmony_ci } 60433d722a9Sopenharmony_ci 60533d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::PartialOrd) { 60633d722a9Sopenharmony_ci out.next_section(); 60733d722a9Sopenharmony_ci writeln!( 60833d722a9Sopenharmony_ci out, 60933d722a9Sopenharmony_ci "bool {0}::operator<({0} const &rhs) const noexcept {{", 61033d722a9Sopenharmony_ci strct.name.cxx, 61133d722a9Sopenharmony_ci ); 61233d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "lt"); 61333d722a9Sopenharmony_ci writeln!(out, " return {}(*this, rhs);", link_name); 61433d722a9Sopenharmony_ci writeln!(out, "}}"); 61533d722a9Sopenharmony_ci 61633d722a9Sopenharmony_ci out.next_section(); 61733d722a9Sopenharmony_ci writeln!( 61833d722a9Sopenharmony_ci out, 61933d722a9Sopenharmony_ci "bool {0}::operator<=({0} const &rhs) const noexcept {{", 62033d722a9Sopenharmony_ci strct.name.cxx, 62133d722a9Sopenharmony_ci ); 62233d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "le"); 62333d722a9Sopenharmony_ci writeln!(out, " return {}(*this, rhs);", link_name); 62433d722a9Sopenharmony_ci writeln!(out, "}}"); 62533d722a9Sopenharmony_ci 62633d722a9Sopenharmony_ci out.next_section(); 62733d722a9Sopenharmony_ci writeln!( 62833d722a9Sopenharmony_ci out, 62933d722a9Sopenharmony_ci "bool {0}::operator>({0} const &rhs) const noexcept {{", 63033d722a9Sopenharmony_ci strct.name.cxx, 63133d722a9Sopenharmony_ci ); 63233d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::Ord) { 63333d722a9Sopenharmony_ci writeln!(out, " return !(*this <= rhs);"); 63433d722a9Sopenharmony_ci } else { 63533d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "gt"); 63633d722a9Sopenharmony_ci writeln!(out, " return {}(*this, rhs);", link_name); 63733d722a9Sopenharmony_ci } 63833d722a9Sopenharmony_ci writeln!(out, "}}"); 63933d722a9Sopenharmony_ci 64033d722a9Sopenharmony_ci out.next_section(); 64133d722a9Sopenharmony_ci writeln!( 64233d722a9Sopenharmony_ci out, 64333d722a9Sopenharmony_ci "bool {0}::operator>=({0} const &rhs) const noexcept {{", 64433d722a9Sopenharmony_ci strct.name.cxx, 64533d722a9Sopenharmony_ci ); 64633d722a9Sopenharmony_ci if derive::contains(&strct.derives, Trait::Ord) { 64733d722a9Sopenharmony_ci writeln!(out, " return !(*this < rhs);"); 64833d722a9Sopenharmony_ci } else { 64933d722a9Sopenharmony_ci let link_name = mangle::operator(&strct.name, "ge"); 65033d722a9Sopenharmony_ci writeln!(out, " return {}(*this, rhs);", link_name); 65133d722a9Sopenharmony_ci } 65233d722a9Sopenharmony_ci writeln!(out, "}}"); 65333d722a9Sopenharmony_ci } 65433d722a9Sopenharmony_ci} 65533d722a9Sopenharmony_ci 65633d722a9Sopenharmony_cifn write_opaque_type_layout_decls<'a>(out: &mut OutFile<'a>, ety: &'a ExternType) { 65733d722a9Sopenharmony_ci out.set_namespace(&ety.name.namespace); 65833d722a9Sopenharmony_ci out.begin_block(Block::ExternC); 65933d722a9Sopenharmony_ci 66033d722a9Sopenharmony_ci let link_name = mangle::operator(&ety.name, "sizeof"); 66133d722a9Sopenharmony_ci writeln!(out, "::std::size_t {}() noexcept;", link_name); 66233d722a9Sopenharmony_ci 66333d722a9Sopenharmony_ci let link_name = mangle::operator(&ety.name, "alignof"); 66433d722a9Sopenharmony_ci writeln!(out, "::std::size_t {}() noexcept;", link_name); 66533d722a9Sopenharmony_ci 66633d722a9Sopenharmony_ci out.end_block(Block::ExternC); 66733d722a9Sopenharmony_ci} 66833d722a9Sopenharmony_ci 66933d722a9Sopenharmony_cifn write_opaque_type_layout<'a>(out: &mut OutFile<'a>, ety: &'a ExternType) { 67033d722a9Sopenharmony_ci if out.header { 67133d722a9Sopenharmony_ci return; 67233d722a9Sopenharmony_ci } 67333d722a9Sopenharmony_ci 67433d722a9Sopenharmony_ci out.set_namespace(&ety.name.namespace); 67533d722a9Sopenharmony_ci 67633d722a9Sopenharmony_ci out.next_section(); 67733d722a9Sopenharmony_ci let link_name = mangle::operator(&ety.name, "sizeof"); 67833d722a9Sopenharmony_ci writeln!( 67933d722a9Sopenharmony_ci out, 68033d722a9Sopenharmony_ci "::std::size_t {}::layout::size() noexcept {{", 68133d722a9Sopenharmony_ci ety.name.cxx, 68233d722a9Sopenharmony_ci ); 68333d722a9Sopenharmony_ci writeln!(out, " return {}();", link_name); 68433d722a9Sopenharmony_ci writeln!(out, "}}"); 68533d722a9Sopenharmony_ci 68633d722a9Sopenharmony_ci out.next_section(); 68733d722a9Sopenharmony_ci let link_name = mangle::operator(&ety.name, "alignof"); 68833d722a9Sopenharmony_ci writeln!( 68933d722a9Sopenharmony_ci out, 69033d722a9Sopenharmony_ci "::std::size_t {}::layout::align() noexcept {{", 69133d722a9Sopenharmony_ci ety.name.cxx, 69233d722a9Sopenharmony_ci ); 69333d722a9Sopenharmony_ci writeln!(out, " return {}();", link_name); 69433d722a9Sopenharmony_ci writeln!(out, "}}"); 69533d722a9Sopenharmony_ci} 69633d722a9Sopenharmony_ci 69733d722a9Sopenharmony_cifn begin_function_definition(out: &mut OutFile) { 69833d722a9Sopenharmony_ci if let Some(annotation) = &out.opt.cxx_impl_annotations { 69933d722a9Sopenharmony_ci write!(out, "{} ", annotation); 70033d722a9Sopenharmony_ci } 70133d722a9Sopenharmony_ci} 70233d722a9Sopenharmony_ci 70333d722a9Sopenharmony_cifn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { 70433d722a9Sopenharmony_ci out.next_section(); 70533d722a9Sopenharmony_ci out.set_namespace(&efn.name.namespace); 70633d722a9Sopenharmony_ci out.begin_block(Block::ExternC); 70733d722a9Sopenharmony_ci begin_function_definition(out); 70833d722a9Sopenharmony_ci if efn.throws { 70933d722a9Sopenharmony_ci out.builtin.ptr_len = true; 71033d722a9Sopenharmony_ci write!(out, "::rust::repr::PtrLen "); 71133d722a9Sopenharmony_ci } else { 71233d722a9Sopenharmony_ci write_extern_return_type_space(out, &efn.ret); 71333d722a9Sopenharmony_ci } 71433d722a9Sopenharmony_ci let mangled = mangle::extern_fn(efn, out.types); 71533d722a9Sopenharmony_ci write!(out, "{}(", mangled); 71633d722a9Sopenharmony_ci if let Some(receiver) = &efn.receiver { 71733d722a9Sopenharmony_ci write!( 71833d722a9Sopenharmony_ci out, 71933d722a9Sopenharmony_ci "{}", 72033d722a9Sopenharmony_ci out.types.resolve(&receiver.ty).name.to_fully_qualified(), 72133d722a9Sopenharmony_ci ); 72233d722a9Sopenharmony_ci if !receiver.mutable { 72333d722a9Sopenharmony_ci write!(out, " const"); 72433d722a9Sopenharmony_ci } 72533d722a9Sopenharmony_ci write!(out, " &self"); 72633d722a9Sopenharmony_ci } 72733d722a9Sopenharmony_ci for (i, arg) in efn.args.iter().enumerate() { 72833d722a9Sopenharmony_ci if i > 0 || efn.receiver.is_some() { 72933d722a9Sopenharmony_ci write!(out, ", "); 73033d722a9Sopenharmony_ci } 73133d722a9Sopenharmony_ci if arg.ty == RustString { 73233d722a9Sopenharmony_ci write_type_space(out, &arg.ty); 73333d722a9Sopenharmony_ci write!(out, "const *{}", arg.name.cxx); 73433d722a9Sopenharmony_ci } else if let Type::RustVec(_) = arg.ty { 73533d722a9Sopenharmony_ci write_type_space(out, &arg.ty); 73633d722a9Sopenharmony_ci write!(out, "const *{}", arg.name.cxx); 73733d722a9Sopenharmony_ci } else { 73833d722a9Sopenharmony_ci write_extern_arg(out, arg); 73933d722a9Sopenharmony_ci } 74033d722a9Sopenharmony_ci } 74133d722a9Sopenharmony_ci let indirect_return = indirect_return(efn, out.types); 74233d722a9Sopenharmony_ci if indirect_return { 74333d722a9Sopenharmony_ci if !efn.args.is_empty() || efn.receiver.is_some() { 74433d722a9Sopenharmony_ci write!(out, ", "); 74533d722a9Sopenharmony_ci } 74633d722a9Sopenharmony_ci write_indirect_return_type_space(out, efn.ret.as_ref().unwrap()); 74733d722a9Sopenharmony_ci write!(out, "*return$"); 74833d722a9Sopenharmony_ci } 74933d722a9Sopenharmony_ci writeln!(out, ") noexcept {{"); 75033d722a9Sopenharmony_ci write!(out, " "); 75133d722a9Sopenharmony_ci write_return_type(out, &efn.ret); 75233d722a9Sopenharmony_ci match &efn.receiver { 75333d722a9Sopenharmony_ci None => write!(out, "(*{}$)(", efn.name.rust), 75433d722a9Sopenharmony_ci Some(receiver) => write!( 75533d722a9Sopenharmony_ci out, 75633d722a9Sopenharmony_ci "({}::*{}$)(", 75733d722a9Sopenharmony_ci out.types.resolve(&receiver.ty).name.to_fully_qualified(), 75833d722a9Sopenharmony_ci efn.name.rust, 75933d722a9Sopenharmony_ci ), 76033d722a9Sopenharmony_ci } 76133d722a9Sopenharmony_ci for (i, arg) in efn.args.iter().enumerate() { 76233d722a9Sopenharmony_ci if i > 0 { 76333d722a9Sopenharmony_ci write!(out, ", "); 76433d722a9Sopenharmony_ci } 76533d722a9Sopenharmony_ci write_type(out, &arg.ty); 76633d722a9Sopenharmony_ci } 76733d722a9Sopenharmony_ci write!(out, ")"); 76833d722a9Sopenharmony_ci if let Some(receiver) = &efn.receiver { 76933d722a9Sopenharmony_ci if !receiver.mutable { 77033d722a9Sopenharmony_ci write!(out, " const"); 77133d722a9Sopenharmony_ci } 77233d722a9Sopenharmony_ci } 77333d722a9Sopenharmony_ci write!(out, " = "); 77433d722a9Sopenharmony_ci match &efn.receiver { 77533d722a9Sopenharmony_ci None => write!(out, "{}", efn.name.to_fully_qualified()), 77633d722a9Sopenharmony_ci Some(receiver) => write!( 77733d722a9Sopenharmony_ci out, 77833d722a9Sopenharmony_ci "&{}::{}", 77933d722a9Sopenharmony_ci out.types.resolve(&receiver.ty).name.to_fully_qualified(), 78033d722a9Sopenharmony_ci efn.name.cxx, 78133d722a9Sopenharmony_ci ), 78233d722a9Sopenharmony_ci } 78333d722a9Sopenharmony_ci writeln!(out, ";"); 78433d722a9Sopenharmony_ci write!(out, " "); 78533d722a9Sopenharmony_ci if efn.throws { 78633d722a9Sopenharmony_ci out.builtin.ptr_len = true; 78733d722a9Sopenharmony_ci out.builtin.trycatch = true; 78833d722a9Sopenharmony_ci writeln!(out, "::rust::repr::PtrLen throw$;"); 78933d722a9Sopenharmony_ci writeln!(out, " ::rust::behavior::trycatch("); 79033d722a9Sopenharmony_ci writeln!(out, " [&] {{"); 79133d722a9Sopenharmony_ci write!(out, " "); 79233d722a9Sopenharmony_ci } 79333d722a9Sopenharmony_ci if indirect_return { 79433d722a9Sopenharmony_ci out.include.new = true; 79533d722a9Sopenharmony_ci write!(out, "new (return$) "); 79633d722a9Sopenharmony_ci write_indirect_return_type(out, efn.ret.as_ref().unwrap()); 79733d722a9Sopenharmony_ci write!(out, "("); 79833d722a9Sopenharmony_ci } else if efn.ret.is_some() { 79933d722a9Sopenharmony_ci write!(out, "return "); 80033d722a9Sopenharmony_ci } 80133d722a9Sopenharmony_ci match &efn.ret { 80233d722a9Sopenharmony_ci Some(Type::Ref(_)) => write!(out, "&"), 80333d722a9Sopenharmony_ci Some(Type::Str(_)) if !indirect_return => { 80433d722a9Sopenharmony_ci out.builtin.rust_str_repr = true; 80533d722a9Sopenharmony_ci write!(out, "::rust::impl<::rust::Str>::repr("); 80633d722a9Sopenharmony_ci } 80733d722a9Sopenharmony_ci Some(ty @ Type::SliceRef(_)) if !indirect_return => { 80833d722a9Sopenharmony_ci out.builtin.rust_slice_repr = true; 80933d722a9Sopenharmony_ci write!(out, "::rust::impl<"); 81033d722a9Sopenharmony_ci write_type(out, ty); 81133d722a9Sopenharmony_ci write!(out, ">::repr("); 81233d722a9Sopenharmony_ci } 81333d722a9Sopenharmony_ci _ => {} 81433d722a9Sopenharmony_ci } 81533d722a9Sopenharmony_ci match &efn.receiver { 81633d722a9Sopenharmony_ci None => write!(out, "{}$(", efn.name.rust), 81733d722a9Sopenharmony_ci Some(_) => write!(out, "(self.*{}$)(", efn.name.rust), 81833d722a9Sopenharmony_ci } 81933d722a9Sopenharmony_ci for (i, arg) in efn.args.iter().enumerate() { 82033d722a9Sopenharmony_ci if i > 0 { 82133d722a9Sopenharmony_ci write!(out, ", "); 82233d722a9Sopenharmony_ci } 82333d722a9Sopenharmony_ci if let Type::RustBox(_) = &arg.ty { 82433d722a9Sopenharmony_ci write_type(out, &arg.ty); 82533d722a9Sopenharmony_ci write!(out, "::from_raw({})", arg.name.cxx); 82633d722a9Sopenharmony_ci } else if let Type::UniquePtr(_) = &arg.ty { 82733d722a9Sopenharmony_ci write_type(out, &arg.ty); 82833d722a9Sopenharmony_ci write!(out, "({})", arg.name.cxx); 82933d722a9Sopenharmony_ci } else if arg.ty == RustString { 83033d722a9Sopenharmony_ci out.builtin.unsafe_bitcopy = true; 83133d722a9Sopenharmony_ci write!( 83233d722a9Sopenharmony_ci out, 83333d722a9Sopenharmony_ci "::rust::String(::rust::unsafe_bitcopy, *{})", 83433d722a9Sopenharmony_ci arg.name.cxx, 83533d722a9Sopenharmony_ci ); 83633d722a9Sopenharmony_ci } else if let Type::RustVec(_) = arg.ty { 83733d722a9Sopenharmony_ci out.builtin.unsafe_bitcopy = true; 83833d722a9Sopenharmony_ci write_type(out, &arg.ty); 83933d722a9Sopenharmony_ci write!(out, "(::rust::unsafe_bitcopy, *{})", arg.name.cxx); 84033d722a9Sopenharmony_ci } else if out.types.needs_indirect_abi(&arg.ty) { 84133d722a9Sopenharmony_ci out.include.utility = true; 84233d722a9Sopenharmony_ci write!(out, "::std::move(*{})", arg.name.cxx); 84333d722a9Sopenharmony_ci } else { 84433d722a9Sopenharmony_ci write!(out, "{}", arg.name.cxx); 84533d722a9Sopenharmony_ci } 84633d722a9Sopenharmony_ci } 84733d722a9Sopenharmony_ci write!(out, ")"); 84833d722a9Sopenharmony_ci match &efn.ret { 84933d722a9Sopenharmony_ci Some(Type::RustBox(_)) => write!(out, ".into_raw()"), 85033d722a9Sopenharmony_ci Some(Type::UniquePtr(_)) => write!(out, ".release()"), 85133d722a9Sopenharmony_ci Some(Type::Str(_)) | Some(Type::SliceRef(_)) if !indirect_return => write!(out, ")"), 85233d722a9Sopenharmony_ci _ => {} 85333d722a9Sopenharmony_ci } 85433d722a9Sopenharmony_ci if indirect_return { 85533d722a9Sopenharmony_ci write!(out, ")"); 85633d722a9Sopenharmony_ci } 85733d722a9Sopenharmony_ci writeln!(out, ";"); 85833d722a9Sopenharmony_ci if efn.throws { 85933d722a9Sopenharmony_ci writeln!(out, " throw$.ptr = nullptr;"); 86033d722a9Sopenharmony_ci writeln!(out, " }},"); 86133d722a9Sopenharmony_ci writeln!(out, " ::rust::detail::Fail(throw$));"); 86233d722a9Sopenharmony_ci writeln!(out, " return throw$;"); 86333d722a9Sopenharmony_ci } 86433d722a9Sopenharmony_ci writeln!(out, "}}"); 86533d722a9Sopenharmony_ci for arg in &efn.args { 86633d722a9Sopenharmony_ci if let Type::Fn(f) = &arg.ty { 86733d722a9Sopenharmony_ci let var = &arg.name; 86833d722a9Sopenharmony_ci write_function_pointer_trampoline(out, efn, var, f); 86933d722a9Sopenharmony_ci } 87033d722a9Sopenharmony_ci } 87133d722a9Sopenharmony_ci out.end_block(Block::ExternC); 87233d722a9Sopenharmony_ci} 87333d722a9Sopenharmony_ci 87433d722a9Sopenharmony_cifn write_function_pointer_trampoline(out: &mut OutFile, efn: &ExternFn, var: &Pair, f: &Signature) { 87533d722a9Sopenharmony_ci let r_trampoline = mangle::r_trampoline(efn, var, out.types); 87633d722a9Sopenharmony_ci let indirect_call = true; 87733d722a9Sopenharmony_ci write_rust_function_decl_impl(out, &r_trampoline, f, indirect_call); 87833d722a9Sopenharmony_ci 87933d722a9Sopenharmony_ci out.next_section(); 88033d722a9Sopenharmony_ci let c_trampoline = mangle::c_trampoline(efn, var, out.types).to_string(); 88133d722a9Sopenharmony_ci let doc = Doc::new(); 88233d722a9Sopenharmony_ci write_rust_function_shim_impl(out, &c_trampoline, f, &doc, &r_trampoline, indirect_call); 88333d722a9Sopenharmony_ci} 88433d722a9Sopenharmony_ci 88533d722a9Sopenharmony_cifn write_rust_function_decl<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { 88633d722a9Sopenharmony_ci out.set_namespace(&efn.name.namespace); 88733d722a9Sopenharmony_ci out.begin_block(Block::ExternC); 88833d722a9Sopenharmony_ci let link_name = mangle::extern_fn(efn, out.types); 88933d722a9Sopenharmony_ci let indirect_call = false; 89033d722a9Sopenharmony_ci write_rust_function_decl_impl(out, &link_name, efn, indirect_call); 89133d722a9Sopenharmony_ci out.end_block(Block::ExternC); 89233d722a9Sopenharmony_ci} 89333d722a9Sopenharmony_ci 89433d722a9Sopenharmony_cifn write_rust_function_decl_impl( 89533d722a9Sopenharmony_ci out: &mut OutFile, 89633d722a9Sopenharmony_ci link_name: &Symbol, 89733d722a9Sopenharmony_ci sig: &Signature, 89833d722a9Sopenharmony_ci indirect_call: bool, 89933d722a9Sopenharmony_ci) { 90033d722a9Sopenharmony_ci out.next_section(); 90133d722a9Sopenharmony_ci if sig.throws { 90233d722a9Sopenharmony_ci out.builtin.ptr_len = true; 90333d722a9Sopenharmony_ci write!(out, "::rust::repr::PtrLen "); 90433d722a9Sopenharmony_ci } else { 90533d722a9Sopenharmony_ci write_extern_return_type_space(out, &sig.ret); 90633d722a9Sopenharmony_ci } 90733d722a9Sopenharmony_ci write!(out, "{}(", link_name); 90833d722a9Sopenharmony_ci let mut needs_comma = false; 90933d722a9Sopenharmony_ci if let Some(receiver) = &sig.receiver { 91033d722a9Sopenharmony_ci write!( 91133d722a9Sopenharmony_ci out, 91233d722a9Sopenharmony_ci "{}", 91333d722a9Sopenharmony_ci out.types.resolve(&receiver.ty).name.to_fully_qualified(), 91433d722a9Sopenharmony_ci ); 91533d722a9Sopenharmony_ci if !receiver.mutable { 91633d722a9Sopenharmony_ci write!(out, " const"); 91733d722a9Sopenharmony_ci } 91833d722a9Sopenharmony_ci write!(out, " &self"); 91933d722a9Sopenharmony_ci needs_comma = true; 92033d722a9Sopenharmony_ci } 92133d722a9Sopenharmony_ci for arg in &sig.args { 92233d722a9Sopenharmony_ci if needs_comma { 92333d722a9Sopenharmony_ci write!(out, ", "); 92433d722a9Sopenharmony_ci } 92533d722a9Sopenharmony_ci write_extern_arg(out, arg); 92633d722a9Sopenharmony_ci needs_comma = true; 92733d722a9Sopenharmony_ci } 92833d722a9Sopenharmony_ci if indirect_return(sig, out.types) { 92933d722a9Sopenharmony_ci if needs_comma { 93033d722a9Sopenharmony_ci write!(out, ", "); 93133d722a9Sopenharmony_ci } 93233d722a9Sopenharmony_ci match sig.ret.as_ref().unwrap() { 93333d722a9Sopenharmony_ci Type::Ref(ret) => { 93433d722a9Sopenharmony_ci write_type_space(out, &ret.inner); 93533d722a9Sopenharmony_ci if !ret.mutable { 93633d722a9Sopenharmony_ci write!(out, "const "); 93733d722a9Sopenharmony_ci } 93833d722a9Sopenharmony_ci write!(out, "*"); 93933d722a9Sopenharmony_ci } 94033d722a9Sopenharmony_ci ret => write_type_space(out, ret), 94133d722a9Sopenharmony_ci } 94233d722a9Sopenharmony_ci write!(out, "*return$"); 94333d722a9Sopenharmony_ci needs_comma = true; 94433d722a9Sopenharmony_ci } 94533d722a9Sopenharmony_ci if indirect_call { 94633d722a9Sopenharmony_ci if needs_comma { 94733d722a9Sopenharmony_ci write!(out, ", "); 94833d722a9Sopenharmony_ci } 94933d722a9Sopenharmony_ci write!(out, "void *"); 95033d722a9Sopenharmony_ci } 95133d722a9Sopenharmony_ci writeln!(out, ") noexcept;"); 95233d722a9Sopenharmony_ci} 95333d722a9Sopenharmony_ci 95433d722a9Sopenharmony_cifn write_rust_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) { 95533d722a9Sopenharmony_ci out.set_namespace(&efn.name.namespace); 95633d722a9Sopenharmony_ci let local_name = match &efn.sig.receiver { 95733d722a9Sopenharmony_ci None => efn.name.cxx.to_string(), 95833d722a9Sopenharmony_ci Some(receiver) => format!( 95933d722a9Sopenharmony_ci "{}::{}", 96033d722a9Sopenharmony_ci out.types.resolve(&receiver.ty).name.cxx, 96133d722a9Sopenharmony_ci efn.name.cxx, 96233d722a9Sopenharmony_ci ), 96333d722a9Sopenharmony_ci }; 96433d722a9Sopenharmony_ci let doc = &efn.doc; 96533d722a9Sopenharmony_ci let invoke = mangle::extern_fn(efn, out.types); 96633d722a9Sopenharmony_ci let indirect_call = false; 96733d722a9Sopenharmony_ci write_rust_function_shim_impl(out, &local_name, efn, doc, &invoke, indirect_call); 96833d722a9Sopenharmony_ci} 96933d722a9Sopenharmony_ci 97033d722a9Sopenharmony_cifn write_rust_function_shim_decl( 97133d722a9Sopenharmony_ci out: &mut OutFile, 97233d722a9Sopenharmony_ci local_name: &str, 97333d722a9Sopenharmony_ci sig: &Signature, 97433d722a9Sopenharmony_ci indirect_call: bool, 97533d722a9Sopenharmony_ci) { 97633d722a9Sopenharmony_ci begin_function_definition(out); 97733d722a9Sopenharmony_ci write_return_type(out, &sig.ret); 97833d722a9Sopenharmony_ci write!(out, "{}(", local_name); 97933d722a9Sopenharmony_ci for (i, arg) in sig.args.iter().enumerate() { 98033d722a9Sopenharmony_ci if i > 0 { 98133d722a9Sopenharmony_ci write!(out, ", "); 98233d722a9Sopenharmony_ci } 98333d722a9Sopenharmony_ci write_type_space(out, &arg.ty); 98433d722a9Sopenharmony_ci write!(out, "{}", arg.name.cxx); 98533d722a9Sopenharmony_ci } 98633d722a9Sopenharmony_ci if indirect_call { 98733d722a9Sopenharmony_ci if !sig.args.is_empty() { 98833d722a9Sopenharmony_ci write!(out, ", "); 98933d722a9Sopenharmony_ci } 99033d722a9Sopenharmony_ci write!(out, "void *extern$"); 99133d722a9Sopenharmony_ci } 99233d722a9Sopenharmony_ci write!(out, ")"); 99333d722a9Sopenharmony_ci if let Some(receiver) = &sig.receiver { 99433d722a9Sopenharmony_ci if !receiver.mutable { 99533d722a9Sopenharmony_ci write!(out, " const"); 99633d722a9Sopenharmony_ci } 99733d722a9Sopenharmony_ci } 99833d722a9Sopenharmony_ci if !sig.throws { 99933d722a9Sopenharmony_ci write!(out, " noexcept"); 100033d722a9Sopenharmony_ci } 100133d722a9Sopenharmony_ci} 100233d722a9Sopenharmony_ci 100333d722a9Sopenharmony_cifn write_rust_function_shim_impl( 100433d722a9Sopenharmony_ci out: &mut OutFile, 100533d722a9Sopenharmony_ci local_name: &str, 100633d722a9Sopenharmony_ci sig: &Signature, 100733d722a9Sopenharmony_ci doc: &Doc, 100833d722a9Sopenharmony_ci invoke: &Symbol, 100933d722a9Sopenharmony_ci indirect_call: bool, 101033d722a9Sopenharmony_ci) { 101133d722a9Sopenharmony_ci if out.header && sig.receiver.is_some() { 101233d722a9Sopenharmony_ci // We've already defined this inside the struct. 101333d722a9Sopenharmony_ci return; 101433d722a9Sopenharmony_ci } 101533d722a9Sopenharmony_ci if sig.receiver.is_none() { 101633d722a9Sopenharmony_ci // Member functions already documented at their declaration. 101733d722a9Sopenharmony_ci write_doc(out, "", doc); 101833d722a9Sopenharmony_ci } 101933d722a9Sopenharmony_ci write_rust_function_shim_decl(out, local_name, sig, indirect_call); 102033d722a9Sopenharmony_ci if out.header { 102133d722a9Sopenharmony_ci writeln!(out, ";"); 102233d722a9Sopenharmony_ci return; 102333d722a9Sopenharmony_ci } 102433d722a9Sopenharmony_ci writeln!(out, " {{"); 102533d722a9Sopenharmony_ci for arg in &sig.args { 102633d722a9Sopenharmony_ci if arg.ty != RustString && out.types.needs_indirect_abi(&arg.ty) { 102733d722a9Sopenharmony_ci out.include.utility = true; 102833d722a9Sopenharmony_ci out.builtin.manually_drop = true; 102933d722a9Sopenharmony_ci write!(out, " ::rust::ManuallyDrop<"); 103033d722a9Sopenharmony_ci write_type(out, &arg.ty); 103133d722a9Sopenharmony_ci writeln!(out, "> {}$(::std::move({0}));", arg.name.cxx); 103233d722a9Sopenharmony_ci } 103333d722a9Sopenharmony_ci } 103433d722a9Sopenharmony_ci write!(out, " "); 103533d722a9Sopenharmony_ci let indirect_return = indirect_return(sig, out.types); 103633d722a9Sopenharmony_ci if indirect_return { 103733d722a9Sopenharmony_ci out.builtin.maybe_uninit = true; 103833d722a9Sopenharmony_ci write!(out, "::rust::MaybeUninit<"); 103933d722a9Sopenharmony_ci match sig.ret.as_ref().unwrap() { 104033d722a9Sopenharmony_ci Type::Ref(ret) => { 104133d722a9Sopenharmony_ci write_type_space(out, &ret.inner); 104233d722a9Sopenharmony_ci if !ret.mutable { 104333d722a9Sopenharmony_ci write!(out, "const "); 104433d722a9Sopenharmony_ci } 104533d722a9Sopenharmony_ci write!(out, "*"); 104633d722a9Sopenharmony_ci } 104733d722a9Sopenharmony_ci ret => write_type(out, ret), 104833d722a9Sopenharmony_ci } 104933d722a9Sopenharmony_ci writeln!(out, "> return$;"); 105033d722a9Sopenharmony_ci write!(out, " "); 105133d722a9Sopenharmony_ci } else if let Some(ret) = &sig.ret { 105233d722a9Sopenharmony_ci write!(out, "return "); 105333d722a9Sopenharmony_ci match ret { 105433d722a9Sopenharmony_ci Type::RustBox(_) => { 105533d722a9Sopenharmony_ci write_type(out, ret); 105633d722a9Sopenharmony_ci write!(out, "::from_raw("); 105733d722a9Sopenharmony_ci } 105833d722a9Sopenharmony_ci Type::UniquePtr(_) => { 105933d722a9Sopenharmony_ci write_type(out, ret); 106033d722a9Sopenharmony_ci write!(out, "("); 106133d722a9Sopenharmony_ci } 106233d722a9Sopenharmony_ci Type::Ref(_) => write!(out, "*"), 106333d722a9Sopenharmony_ci Type::Str(_) => { 106433d722a9Sopenharmony_ci out.builtin.rust_str_new_unchecked = true; 106533d722a9Sopenharmony_ci write!(out, "::rust::impl<::rust::Str>::new_unchecked("); 106633d722a9Sopenharmony_ci } 106733d722a9Sopenharmony_ci Type::SliceRef(_) => { 106833d722a9Sopenharmony_ci out.builtin.rust_slice_new = true; 106933d722a9Sopenharmony_ci write!(out, "::rust::impl<"); 107033d722a9Sopenharmony_ci write_type(out, ret); 107133d722a9Sopenharmony_ci write!(out, ">::slice("); 107233d722a9Sopenharmony_ci } 107333d722a9Sopenharmony_ci _ => {} 107433d722a9Sopenharmony_ci } 107533d722a9Sopenharmony_ci } 107633d722a9Sopenharmony_ci if sig.throws { 107733d722a9Sopenharmony_ci out.builtin.ptr_len = true; 107833d722a9Sopenharmony_ci write!(out, "::rust::repr::PtrLen error$ = "); 107933d722a9Sopenharmony_ci } 108033d722a9Sopenharmony_ci write!(out, "{}(", invoke); 108133d722a9Sopenharmony_ci let mut needs_comma = false; 108233d722a9Sopenharmony_ci if sig.receiver.is_some() { 108333d722a9Sopenharmony_ci write!(out, "*this"); 108433d722a9Sopenharmony_ci needs_comma = true; 108533d722a9Sopenharmony_ci } 108633d722a9Sopenharmony_ci for arg in &sig.args { 108733d722a9Sopenharmony_ci if needs_comma { 108833d722a9Sopenharmony_ci write!(out, ", "); 108933d722a9Sopenharmony_ci } 109033d722a9Sopenharmony_ci if out.types.needs_indirect_abi(&arg.ty) { 109133d722a9Sopenharmony_ci write!(out, "&"); 109233d722a9Sopenharmony_ci } 109333d722a9Sopenharmony_ci write!(out, "{}", arg.name.cxx); 109433d722a9Sopenharmony_ci match &arg.ty { 109533d722a9Sopenharmony_ci Type::RustBox(_) => write!(out, ".into_raw()"), 109633d722a9Sopenharmony_ci Type::UniquePtr(_) => write!(out, ".release()"), 109733d722a9Sopenharmony_ci ty if ty != RustString && out.types.needs_indirect_abi(ty) => write!(out, "$.value"), 109833d722a9Sopenharmony_ci _ => {} 109933d722a9Sopenharmony_ci } 110033d722a9Sopenharmony_ci needs_comma = true; 110133d722a9Sopenharmony_ci } 110233d722a9Sopenharmony_ci if indirect_return { 110333d722a9Sopenharmony_ci if needs_comma { 110433d722a9Sopenharmony_ci write!(out, ", "); 110533d722a9Sopenharmony_ci } 110633d722a9Sopenharmony_ci write!(out, "&return$.value"); 110733d722a9Sopenharmony_ci needs_comma = true; 110833d722a9Sopenharmony_ci } 110933d722a9Sopenharmony_ci if indirect_call { 111033d722a9Sopenharmony_ci if needs_comma { 111133d722a9Sopenharmony_ci write!(out, ", "); 111233d722a9Sopenharmony_ci } 111333d722a9Sopenharmony_ci write!(out, "extern$"); 111433d722a9Sopenharmony_ci } 111533d722a9Sopenharmony_ci write!(out, ")"); 111633d722a9Sopenharmony_ci if !indirect_return { 111733d722a9Sopenharmony_ci if let Some(ret) = &sig.ret { 111833d722a9Sopenharmony_ci if let Type::RustBox(_) | Type::UniquePtr(_) | Type::Str(_) | Type::SliceRef(_) = ret { 111933d722a9Sopenharmony_ci write!(out, ")"); 112033d722a9Sopenharmony_ci } 112133d722a9Sopenharmony_ci } 112233d722a9Sopenharmony_ci } 112333d722a9Sopenharmony_ci writeln!(out, ";"); 112433d722a9Sopenharmony_ci if sig.throws { 112533d722a9Sopenharmony_ci out.builtin.rust_error = true; 112633d722a9Sopenharmony_ci writeln!(out, " if (error$.ptr) {{"); 112733d722a9Sopenharmony_ci writeln!(out, " throw ::rust::impl<::rust::Error>::error(error$);"); 112833d722a9Sopenharmony_ci writeln!(out, " }}"); 112933d722a9Sopenharmony_ci } 113033d722a9Sopenharmony_ci if indirect_return { 113133d722a9Sopenharmony_ci write!(out, " return "); 113233d722a9Sopenharmony_ci match sig.ret.as_ref().unwrap() { 113333d722a9Sopenharmony_ci Type::Ref(_) => write!(out, "*return$.value"), 113433d722a9Sopenharmony_ci _ => { 113533d722a9Sopenharmony_ci out.include.utility = true; 113633d722a9Sopenharmony_ci write!(out, "::std::move(return$.value)"); 113733d722a9Sopenharmony_ci } 113833d722a9Sopenharmony_ci } 113933d722a9Sopenharmony_ci writeln!(out, ";"); 114033d722a9Sopenharmony_ci } 114133d722a9Sopenharmony_ci writeln!(out, "}}"); 114233d722a9Sopenharmony_ci} 114333d722a9Sopenharmony_ci 114433d722a9Sopenharmony_cifn write_return_type(out: &mut OutFile, ty: &Option<Type>) { 114533d722a9Sopenharmony_ci match ty { 114633d722a9Sopenharmony_ci None => write!(out, "void "), 114733d722a9Sopenharmony_ci Some(ty) => write_type_space(out, ty), 114833d722a9Sopenharmony_ci } 114933d722a9Sopenharmony_ci} 115033d722a9Sopenharmony_ci 115133d722a9Sopenharmony_cifn indirect_return(sig: &Signature, types: &Types) -> bool { 115233d722a9Sopenharmony_ci sig.ret 115333d722a9Sopenharmony_ci .as_ref() 115433d722a9Sopenharmony_ci .map_or(false, |ret| sig.throws || types.needs_indirect_abi(ret)) 115533d722a9Sopenharmony_ci} 115633d722a9Sopenharmony_ci 115733d722a9Sopenharmony_cifn write_indirect_return_type(out: &mut OutFile, ty: &Type) { 115833d722a9Sopenharmony_ci match ty { 115933d722a9Sopenharmony_ci Type::RustBox(ty) | Type::UniquePtr(ty) => { 116033d722a9Sopenharmony_ci write_type_space(out, &ty.inner); 116133d722a9Sopenharmony_ci write!(out, "*"); 116233d722a9Sopenharmony_ci } 116333d722a9Sopenharmony_ci Type::Ref(ty) => { 116433d722a9Sopenharmony_ci write_type_space(out, &ty.inner); 116533d722a9Sopenharmony_ci if !ty.mutable { 116633d722a9Sopenharmony_ci write!(out, "const "); 116733d722a9Sopenharmony_ci } 116833d722a9Sopenharmony_ci write!(out, "*"); 116933d722a9Sopenharmony_ci } 117033d722a9Sopenharmony_ci _ => write_type(out, ty), 117133d722a9Sopenharmony_ci } 117233d722a9Sopenharmony_ci} 117333d722a9Sopenharmony_ci 117433d722a9Sopenharmony_cifn write_indirect_return_type_space(out: &mut OutFile, ty: &Type) { 117533d722a9Sopenharmony_ci write_indirect_return_type(out, ty); 117633d722a9Sopenharmony_ci match ty { 117733d722a9Sopenharmony_ci Type::RustBox(_) | Type::UniquePtr(_) | Type::Ref(_) => {} 117833d722a9Sopenharmony_ci Type::Str(_) | Type::SliceRef(_) => write!(out, " "), 117933d722a9Sopenharmony_ci _ => write_space_after_type(out, ty), 118033d722a9Sopenharmony_ci } 118133d722a9Sopenharmony_ci} 118233d722a9Sopenharmony_ci 118333d722a9Sopenharmony_cifn write_extern_return_type_space(out: &mut OutFile, ty: &Option<Type>) { 118433d722a9Sopenharmony_ci match ty { 118533d722a9Sopenharmony_ci Some(Type::RustBox(ty)) | Some(Type::UniquePtr(ty)) => { 118633d722a9Sopenharmony_ci write_type_space(out, &ty.inner); 118733d722a9Sopenharmony_ci write!(out, "*"); 118833d722a9Sopenharmony_ci } 118933d722a9Sopenharmony_ci Some(Type::Ref(ty)) => { 119033d722a9Sopenharmony_ci write_type_space(out, &ty.inner); 119133d722a9Sopenharmony_ci if !ty.mutable { 119233d722a9Sopenharmony_ci write!(out, "const "); 119333d722a9Sopenharmony_ci } 119433d722a9Sopenharmony_ci write!(out, "*"); 119533d722a9Sopenharmony_ci } 119633d722a9Sopenharmony_ci Some(Type::Str(_)) | Some(Type::SliceRef(_)) => { 119733d722a9Sopenharmony_ci out.builtin.repr_fat = true; 119833d722a9Sopenharmony_ci write!(out, "::rust::repr::Fat "); 119933d722a9Sopenharmony_ci } 120033d722a9Sopenharmony_ci Some(ty) if out.types.needs_indirect_abi(ty) => write!(out, "void "), 120133d722a9Sopenharmony_ci _ => write_return_type(out, ty), 120233d722a9Sopenharmony_ci } 120333d722a9Sopenharmony_ci} 120433d722a9Sopenharmony_ci 120533d722a9Sopenharmony_cifn write_extern_arg(out: &mut OutFile, arg: &Var) { 120633d722a9Sopenharmony_ci match &arg.ty { 120733d722a9Sopenharmony_ci Type::RustBox(ty) | Type::UniquePtr(ty) | Type::CxxVector(ty) => { 120833d722a9Sopenharmony_ci write_type_space(out, &ty.inner); 120933d722a9Sopenharmony_ci write!(out, "*"); 121033d722a9Sopenharmony_ci } 121133d722a9Sopenharmony_ci _ => write_type_space(out, &arg.ty), 121233d722a9Sopenharmony_ci } 121333d722a9Sopenharmony_ci if out.types.needs_indirect_abi(&arg.ty) { 121433d722a9Sopenharmony_ci write!(out, "*"); 121533d722a9Sopenharmony_ci } 121633d722a9Sopenharmony_ci write!(out, "{}", arg.name.cxx); 121733d722a9Sopenharmony_ci} 121833d722a9Sopenharmony_ci 121933d722a9Sopenharmony_cifn write_type(out: &mut OutFile, ty: &Type) { 122033d722a9Sopenharmony_ci match ty { 122133d722a9Sopenharmony_ci Type::Ident(ident) => match Atom::from(&ident.rust) { 122233d722a9Sopenharmony_ci Some(atom) => write_atom(out, atom), 122333d722a9Sopenharmony_ci None => write!( 122433d722a9Sopenharmony_ci out, 122533d722a9Sopenharmony_ci "{}", 122633d722a9Sopenharmony_ci out.types.resolve(ident).name.to_fully_qualified(), 122733d722a9Sopenharmony_ci ), 122833d722a9Sopenharmony_ci }, 122933d722a9Sopenharmony_ci Type::RustBox(ty) => { 123033d722a9Sopenharmony_ci write!(out, "::rust::Box<"); 123133d722a9Sopenharmony_ci write_type(out, &ty.inner); 123233d722a9Sopenharmony_ci write!(out, ">"); 123333d722a9Sopenharmony_ci } 123433d722a9Sopenharmony_ci Type::RustVec(ty) => { 123533d722a9Sopenharmony_ci write!(out, "::rust::Vec<"); 123633d722a9Sopenharmony_ci write_type(out, &ty.inner); 123733d722a9Sopenharmony_ci write!(out, ">"); 123833d722a9Sopenharmony_ci } 123933d722a9Sopenharmony_ci Type::UniquePtr(ptr) => { 124033d722a9Sopenharmony_ci write!(out, "::std::unique_ptr<"); 124133d722a9Sopenharmony_ci write_type(out, &ptr.inner); 124233d722a9Sopenharmony_ci write!(out, ">"); 124333d722a9Sopenharmony_ci } 124433d722a9Sopenharmony_ci Type::SharedPtr(ptr) => { 124533d722a9Sopenharmony_ci write!(out, "::std::shared_ptr<"); 124633d722a9Sopenharmony_ci write_type(out, &ptr.inner); 124733d722a9Sopenharmony_ci write!(out, ">"); 124833d722a9Sopenharmony_ci } 124933d722a9Sopenharmony_ci Type::WeakPtr(ptr) => { 125033d722a9Sopenharmony_ci write!(out, "::std::weak_ptr<"); 125133d722a9Sopenharmony_ci write_type(out, &ptr.inner); 125233d722a9Sopenharmony_ci write!(out, ">"); 125333d722a9Sopenharmony_ci } 125433d722a9Sopenharmony_ci Type::CxxVector(ty) => { 125533d722a9Sopenharmony_ci write!(out, "::std::vector<"); 125633d722a9Sopenharmony_ci write_type(out, &ty.inner); 125733d722a9Sopenharmony_ci write!(out, ">"); 125833d722a9Sopenharmony_ci } 125933d722a9Sopenharmony_ci Type::Ref(r) => { 126033d722a9Sopenharmony_ci write_type_space(out, &r.inner); 126133d722a9Sopenharmony_ci if !r.mutable { 126233d722a9Sopenharmony_ci write!(out, "const "); 126333d722a9Sopenharmony_ci } 126433d722a9Sopenharmony_ci write!(out, "&"); 126533d722a9Sopenharmony_ci } 126633d722a9Sopenharmony_ci Type::Ptr(p) => { 126733d722a9Sopenharmony_ci write_type_space(out, &p.inner); 126833d722a9Sopenharmony_ci if !p.mutable { 126933d722a9Sopenharmony_ci write!(out, "const "); 127033d722a9Sopenharmony_ci } 127133d722a9Sopenharmony_ci write!(out, "*"); 127233d722a9Sopenharmony_ci } 127333d722a9Sopenharmony_ci Type::Str(_) => { 127433d722a9Sopenharmony_ci write!(out, "::rust::Str"); 127533d722a9Sopenharmony_ci } 127633d722a9Sopenharmony_ci Type::SliceRef(slice) => { 127733d722a9Sopenharmony_ci write!(out, "::rust::Slice<"); 127833d722a9Sopenharmony_ci write_type_space(out, &slice.inner); 127933d722a9Sopenharmony_ci if slice.mutability.is_none() { 128033d722a9Sopenharmony_ci write!(out, "const"); 128133d722a9Sopenharmony_ci } 128233d722a9Sopenharmony_ci write!(out, ">"); 128333d722a9Sopenharmony_ci } 128433d722a9Sopenharmony_ci Type::Fn(f) => { 128533d722a9Sopenharmony_ci write!(out, "::rust::Fn<"); 128633d722a9Sopenharmony_ci match &f.ret { 128733d722a9Sopenharmony_ci Some(ret) => write_type(out, ret), 128833d722a9Sopenharmony_ci None => write!(out, "void"), 128933d722a9Sopenharmony_ci } 129033d722a9Sopenharmony_ci write!(out, "("); 129133d722a9Sopenharmony_ci for (i, arg) in f.args.iter().enumerate() { 129233d722a9Sopenharmony_ci if i > 0 { 129333d722a9Sopenharmony_ci write!(out, ", "); 129433d722a9Sopenharmony_ci } 129533d722a9Sopenharmony_ci write_type(out, &arg.ty); 129633d722a9Sopenharmony_ci } 129733d722a9Sopenharmony_ci write!(out, ")>"); 129833d722a9Sopenharmony_ci } 129933d722a9Sopenharmony_ci Type::Array(a) => { 130033d722a9Sopenharmony_ci write!(out, "::std::array<"); 130133d722a9Sopenharmony_ci write_type(out, &a.inner); 130233d722a9Sopenharmony_ci write!(out, ", {}>", &a.len); 130333d722a9Sopenharmony_ci } 130433d722a9Sopenharmony_ci Type::Void(_) => unreachable!(), 130533d722a9Sopenharmony_ci } 130633d722a9Sopenharmony_ci} 130733d722a9Sopenharmony_ci 130833d722a9Sopenharmony_cifn write_atom(out: &mut OutFile, atom: Atom) { 130933d722a9Sopenharmony_ci match atom { 131033d722a9Sopenharmony_ci Bool => write!(out, "bool"), 131133d722a9Sopenharmony_ci Char => write!(out, "char"), 131233d722a9Sopenharmony_ci U8 => write!(out, "::std::uint8_t"), 131333d722a9Sopenharmony_ci U16 => write!(out, "::std::uint16_t"), 131433d722a9Sopenharmony_ci U32 => write!(out, "::std::uint32_t"), 131533d722a9Sopenharmony_ci U64 => write!(out, "::std::uint64_t"), 131633d722a9Sopenharmony_ci Usize => write!(out, "::std::size_t"), 131733d722a9Sopenharmony_ci I8 => write!(out, "::std::int8_t"), 131833d722a9Sopenharmony_ci I16 => write!(out, "::std::int16_t"), 131933d722a9Sopenharmony_ci I32 => write!(out, "::std::int32_t"), 132033d722a9Sopenharmony_ci I64 => write!(out, "::std::int64_t"), 132133d722a9Sopenharmony_ci Isize => write!(out, "::rust::isize"), 132233d722a9Sopenharmony_ci F32 => write!(out, "float"), 132333d722a9Sopenharmony_ci F64 => write!(out, "double"), 132433d722a9Sopenharmony_ci CxxString => write!(out, "::std::string"), 132533d722a9Sopenharmony_ci RustString => write!(out, "::rust::String"), 132633d722a9Sopenharmony_ci } 132733d722a9Sopenharmony_ci} 132833d722a9Sopenharmony_ci 132933d722a9Sopenharmony_cifn write_type_space(out: &mut OutFile, ty: &Type) { 133033d722a9Sopenharmony_ci write_type(out, ty); 133133d722a9Sopenharmony_ci write_space_after_type(out, ty); 133233d722a9Sopenharmony_ci} 133333d722a9Sopenharmony_ci 133433d722a9Sopenharmony_cifn write_space_after_type(out: &mut OutFile, ty: &Type) { 133533d722a9Sopenharmony_ci match ty { 133633d722a9Sopenharmony_ci Type::Ident(_) 133733d722a9Sopenharmony_ci | Type::RustBox(_) 133833d722a9Sopenharmony_ci | Type::UniquePtr(_) 133933d722a9Sopenharmony_ci | Type::SharedPtr(_) 134033d722a9Sopenharmony_ci | Type::WeakPtr(_) 134133d722a9Sopenharmony_ci | Type::Str(_) 134233d722a9Sopenharmony_ci | Type::CxxVector(_) 134333d722a9Sopenharmony_ci | Type::RustVec(_) 134433d722a9Sopenharmony_ci | Type::SliceRef(_) 134533d722a9Sopenharmony_ci | Type::Fn(_) 134633d722a9Sopenharmony_ci | Type::Array(_) => write!(out, " "), 134733d722a9Sopenharmony_ci Type::Ref(_) | Type::Ptr(_) => {} 134833d722a9Sopenharmony_ci Type::Void(_) => unreachable!(), 134933d722a9Sopenharmony_ci } 135033d722a9Sopenharmony_ci} 135133d722a9Sopenharmony_ci 135233d722a9Sopenharmony_ci#[derive(Copy, Clone)] 135333d722a9Sopenharmony_cienum UniquePtr<'a> { 135433d722a9Sopenharmony_ci Ident(&'a Ident), 135533d722a9Sopenharmony_ci CxxVector(&'a Ident), 135633d722a9Sopenharmony_ci} 135733d722a9Sopenharmony_ci 135833d722a9Sopenharmony_citrait ToTypename { 135933d722a9Sopenharmony_ci fn to_typename(&self, types: &Types) -> String; 136033d722a9Sopenharmony_ci} 136133d722a9Sopenharmony_ci 136233d722a9Sopenharmony_ciimpl ToTypename for Ident { 136333d722a9Sopenharmony_ci fn to_typename(&self, types: &Types) -> String { 136433d722a9Sopenharmony_ci types.resolve(self).name.to_fully_qualified() 136533d722a9Sopenharmony_ci } 136633d722a9Sopenharmony_ci} 136733d722a9Sopenharmony_ci 136833d722a9Sopenharmony_ciimpl<'a> ToTypename for UniquePtr<'a> { 136933d722a9Sopenharmony_ci fn to_typename(&self, types: &Types) -> String { 137033d722a9Sopenharmony_ci match self { 137133d722a9Sopenharmony_ci UniquePtr::Ident(ident) => ident.to_typename(types), 137233d722a9Sopenharmony_ci UniquePtr::CxxVector(element) => { 137333d722a9Sopenharmony_ci format!("::std::vector<{}>", element.to_typename(types)) 137433d722a9Sopenharmony_ci } 137533d722a9Sopenharmony_ci } 137633d722a9Sopenharmony_ci } 137733d722a9Sopenharmony_ci} 137833d722a9Sopenharmony_ci 137933d722a9Sopenharmony_citrait ToMangled { 138033d722a9Sopenharmony_ci fn to_mangled(&self, types: &Types) -> Symbol; 138133d722a9Sopenharmony_ci} 138233d722a9Sopenharmony_ci 138333d722a9Sopenharmony_ciimpl ToMangled for Ident { 138433d722a9Sopenharmony_ci fn to_mangled(&self, types: &Types) -> Symbol { 138533d722a9Sopenharmony_ci types.resolve(self).name.to_symbol() 138633d722a9Sopenharmony_ci } 138733d722a9Sopenharmony_ci} 138833d722a9Sopenharmony_ci 138933d722a9Sopenharmony_ciimpl<'a> ToMangled for UniquePtr<'a> { 139033d722a9Sopenharmony_ci fn to_mangled(&self, types: &Types) -> Symbol { 139133d722a9Sopenharmony_ci match self { 139233d722a9Sopenharmony_ci UniquePtr::Ident(ident) => ident.to_mangled(types), 139333d722a9Sopenharmony_ci UniquePtr::CxxVector(element) => { 139433d722a9Sopenharmony_ci symbol::join(&[&"std", &"vector", &element.to_mangled(types)]) 139533d722a9Sopenharmony_ci } 139633d722a9Sopenharmony_ci } 139733d722a9Sopenharmony_ci } 139833d722a9Sopenharmony_ci} 139933d722a9Sopenharmony_ci 140033d722a9Sopenharmony_cifn write_generic_instantiations(out: &mut OutFile) { 140133d722a9Sopenharmony_ci if out.header { 140233d722a9Sopenharmony_ci return; 140333d722a9Sopenharmony_ci } 140433d722a9Sopenharmony_ci 140533d722a9Sopenharmony_ci out.next_section(); 140633d722a9Sopenharmony_ci out.set_namespace(Default::default()); 140733d722a9Sopenharmony_ci out.begin_block(Block::ExternC); 140833d722a9Sopenharmony_ci for impl_key in out.types.impls.keys() { 140933d722a9Sopenharmony_ci out.next_section(); 141033d722a9Sopenharmony_ci match *impl_key { 141133d722a9Sopenharmony_ci ImplKey::RustBox(ident) => write_rust_box_extern(out, ident), 141233d722a9Sopenharmony_ci ImplKey::RustVec(ident) => write_rust_vec_extern(out, ident), 141333d722a9Sopenharmony_ci ImplKey::UniquePtr(ident) => write_unique_ptr(out, ident), 141433d722a9Sopenharmony_ci ImplKey::SharedPtr(ident) => write_shared_ptr(out, ident), 141533d722a9Sopenharmony_ci ImplKey::WeakPtr(ident) => write_weak_ptr(out, ident), 141633d722a9Sopenharmony_ci ImplKey::CxxVector(ident) => write_cxx_vector(out, ident), 141733d722a9Sopenharmony_ci } 141833d722a9Sopenharmony_ci } 141933d722a9Sopenharmony_ci out.end_block(Block::ExternC); 142033d722a9Sopenharmony_ci 142133d722a9Sopenharmony_ci out.begin_block(Block::Namespace("rust")); 142233d722a9Sopenharmony_ci out.begin_block(Block::InlineNamespace("cxxbridge1")); 142333d722a9Sopenharmony_ci for impl_key in out.types.impls.keys() { 142433d722a9Sopenharmony_ci match *impl_key { 142533d722a9Sopenharmony_ci ImplKey::RustBox(ident) => write_rust_box_impl(out, ident), 142633d722a9Sopenharmony_ci ImplKey::RustVec(ident) => write_rust_vec_impl(out, ident), 142733d722a9Sopenharmony_ci _ => {} 142833d722a9Sopenharmony_ci } 142933d722a9Sopenharmony_ci } 143033d722a9Sopenharmony_ci out.end_block(Block::InlineNamespace("cxxbridge1")); 143133d722a9Sopenharmony_ci out.end_block(Block::Namespace("rust")); 143233d722a9Sopenharmony_ci} 143333d722a9Sopenharmony_ci 143433d722a9Sopenharmony_cifn write_rust_box_extern(out: &mut OutFile, key: NamedImplKey) { 143533d722a9Sopenharmony_ci let resolve = out.types.resolve(&key); 143633d722a9Sopenharmony_ci let inner = resolve.name.to_fully_qualified(); 143733d722a9Sopenharmony_ci let instance = resolve.name.to_symbol(); 143833d722a9Sopenharmony_ci 143933d722a9Sopenharmony_ci writeln!( 144033d722a9Sopenharmony_ci out, 144133d722a9Sopenharmony_ci "{} *cxxbridge1$box${}$alloc() noexcept;", 144233d722a9Sopenharmony_ci inner, instance, 144333d722a9Sopenharmony_ci ); 144433d722a9Sopenharmony_ci writeln!( 144533d722a9Sopenharmony_ci out, 144633d722a9Sopenharmony_ci "void cxxbridge1$box${}$dealloc({} *) noexcept;", 144733d722a9Sopenharmony_ci instance, inner, 144833d722a9Sopenharmony_ci ); 144933d722a9Sopenharmony_ci writeln!( 145033d722a9Sopenharmony_ci out, 145133d722a9Sopenharmony_ci "void cxxbridge1$box${}$drop(::rust::Box<{}> *ptr) noexcept;", 145233d722a9Sopenharmony_ci instance, inner, 145333d722a9Sopenharmony_ci ); 145433d722a9Sopenharmony_ci} 145533d722a9Sopenharmony_ci 145633d722a9Sopenharmony_cifn write_rust_vec_extern(out: &mut OutFile, key: NamedImplKey) { 145733d722a9Sopenharmony_ci let element = key.rust; 145833d722a9Sopenharmony_ci let inner = element.to_typename(out.types); 145933d722a9Sopenharmony_ci let instance = element.to_mangled(out.types); 146033d722a9Sopenharmony_ci 146133d722a9Sopenharmony_ci out.include.cstddef = true; 146233d722a9Sopenharmony_ci 146333d722a9Sopenharmony_ci writeln!( 146433d722a9Sopenharmony_ci out, 146533d722a9Sopenharmony_ci "void cxxbridge1$rust_vec${}$new(::rust::Vec<{}> const *ptr) noexcept;", 146633d722a9Sopenharmony_ci instance, inner, 146733d722a9Sopenharmony_ci ); 146833d722a9Sopenharmony_ci writeln!( 146933d722a9Sopenharmony_ci out, 147033d722a9Sopenharmony_ci "void cxxbridge1$rust_vec${}$drop(::rust::Vec<{}> *ptr) noexcept;", 147133d722a9Sopenharmony_ci instance, inner, 147233d722a9Sopenharmony_ci ); 147333d722a9Sopenharmony_ci writeln!( 147433d722a9Sopenharmony_ci out, 147533d722a9Sopenharmony_ci "::std::size_t cxxbridge1$rust_vec${}$len(::rust::Vec<{}> const *ptr) noexcept;", 147633d722a9Sopenharmony_ci instance, inner, 147733d722a9Sopenharmony_ci ); 147833d722a9Sopenharmony_ci writeln!( 147933d722a9Sopenharmony_ci out, 148033d722a9Sopenharmony_ci "::std::size_t cxxbridge1$rust_vec${}$capacity(::rust::Vec<{}> const *ptr) noexcept;", 148133d722a9Sopenharmony_ci instance, inner, 148233d722a9Sopenharmony_ci ); 148333d722a9Sopenharmony_ci writeln!( 148433d722a9Sopenharmony_ci out, 148533d722a9Sopenharmony_ci "{} const *cxxbridge1$rust_vec${}$data(::rust::Vec<{0}> const *ptr) noexcept;", 148633d722a9Sopenharmony_ci inner, instance, 148733d722a9Sopenharmony_ci ); 148833d722a9Sopenharmony_ci writeln!( 148933d722a9Sopenharmony_ci out, 149033d722a9Sopenharmony_ci "void cxxbridge1$rust_vec${}$reserve_total(::rust::Vec<{}> *ptr, ::std::size_t new_cap) noexcept;", 149133d722a9Sopenharmony_ci instance, inner, 149233d722a9Sopenharmony_ci ); 149333d722a9Sopenharmony_ci writeln!( 149433d722a9Sopenharmony_ci out, 149533d722a9Sopenharmony_ci "void cxxbridge1$rust_vec${}$set_len(::rust::Vec<{}> *ptr, ::std::size_t len) noexcept;", 149633d722a9Sopenharmony_ci instance, inner, 149733d722a9Sopenharmony_ci ); 149833d722a9Sopenharmony_ci writeln!( 149933d722a9Sopenharmony_ci out, 150033d722a9Sopenharmony_ci "void cxxbridge1$rust_vec${}$truncate(::rust::Vec<{}> *ptr, ::std::size_t len) noexcept;", 150133d722a9Sopenharmony_ci instance, inner, 150233d722a9Sopenharmony_ci ); 150333d722a9Sopenharmony_ci} 150433d722a9Sopenharmony_ci 150533d722a9Sopenharmony_cifn write_rust_box_impl(out: &mut OutFile, key: NamedImplKey) { 150633d722a9Sopenharmony_ci let resolve = out.types.resolve(&key); 150733d722a9Sopenharmony_ci let inner = resolve.name.to_fully_qualified(); 150833d722a9Sopenharmony_ci let instance = resolve.name.to_symbol(); 150933d722a9Sopenharmony_ci 151033d722a9Sopenharmony_ci writeln!(out, "template <>"); 151133d722a9Sopenharmony_ci begin_function_definition(out); 151233d722a9Sopenharmony_ci writeln!( 151333d722a9Sopenharmony_ci out, 151433d722a9Sopenharmony_ci "{} *Box<{}>::allocation::alloc() noexcept {{", 151533d722a9Sopenharmony_ci inner, inner, 151633d722a9Sopenharmony_ci ); 151733d722a9Sopenharmony_ci writeln!(out, " return cxxbridge1$box${}$alloc();", instance); 151833d722a9Sopenharmony_ci writeln!(out, "}}"); 151933d722a9Sopenharmony_ci 152033d722a9Sopenharmony_ci writeln!(out, "template <>"); 152133d722a9Sopenharmony_ci begin_function_definition(out); 152233d722a9Sopenharmony_ci writeln!( 152333d722a9Sopenharmony_ci out, 152433d722a9Sopenharmony_ci "void Box<{}>::allocation::dealloc({} *ptr) noexcept {{", 152533d722a9Sopenharmony_ci inner, inner, 152633d722a9Sopenharmony_ci ); 152733d722a9Sopenharmony_ci writeln!(out, " cxxbridge1$box${}$dealloc(ptr);", instance); 152833d722a9Sopenharmony_ci writeln!(out, "}}"); 152933d722a9Sopenharmony_ci 153033d722a9Sopenharmony_ci writeln!(out, "template <>"); 153133d722a9Sopenharmony_ci begin_function_definition(out); 153233d722a9Sopenharmony_ci writeln!(out, "void Box<{}>::drop() noexcept {{", inner); 153333d722a9Sopenharmony_ci writeln!(out, " cxxbridge1$box${}$drop(this);", instance); 153433d722a9Sopenharmony_ci writeln!(out, "}}"); 153533d722a9Sopenharmony_ci} 153633d722a9Sopenharmony_ci 153733d722a9Sopenharmony_cifn write_rust_vec_impl(out: &mut OutFile, key: NamedImplKey) { 153833d722a9Sopenharmony_ci let element = key.rust; 153933d722a9Sopenharmony_ci let inner = element.to_typename(out.types); 154033d722a9Sopenharmony_ci let instance = element.to_mangled(out.types); 154133d722a9Sopenharmony_ci 154233d722a9Sopenharmony_ci out.include.cstddef = true; 154333d722a9Sopenharmony_ci 154433d722a9Sopenharmony_ci writeln!(out, "template <>"); 154533d722a9Sopenharmony_ci begin_function_definition(out); 154633d722a9Sopenharmony_ci writeln!(out, "Vec<{}>::Vec() noexcept {{", inner); 154733d722a9Sopenharmony_ci writeln!(out, " cxxbridge1$rust_vec${}$new(this);", instance); 154833d722a9Sopenharmony_ci writeln!(out, "}}"); 154933d722a9Sopenharmony_ci 155033d722a9Sopenharmony_ci writeln!(out, "template <>"); 155133d722a9Sopenharmony_ci begin_function_definition(out); 155233d722a9Sopenharmony_ci writeln!(out, "void Vec<{}>::drop() noexcept {{", inner); 155333d722a9Sopenharmony_ci writeln!(out, " return cxxbridge1$rust_vec${}$drop(this);", instance); 155433d722a9Sopenharmony_ci writeln!(out, "}}"); 155533d722a9Sopenharmony_ci 155633d722a9Sopenharmony_ci writeln!(out, "template <>"); 155733d722a9Sopenharmony_ci begin_function_definition(out); 155833d722a9Sopenharmony_ci writeln!( 155933d722a9Sopenharmony_ci out, 156033d722a9Sopenharmony_ci "::std::size_t Vec<{}>::size() const noexcept {{", 156133d722a9Sopenharmony_ci inner, 156233d722a9Sopenharmony_ci ); 156333d722a9Sopenharmony_ci writeln!(out, " return cxxbridge1$rust_vec${}$len(this);", instance); 156433d722a9Sopenharmony_ci writeln!(out, "}}"); 156533d722a9Sopenharmony_ci 156633d722a9Sopenharmony_ci writeln!(out, "template <>"); 156733d722a9Sopenharmony_ci begin_function_definition(out); 156833d722a9Sopenharmony_ci writeln!( 156933d722a9Sopenharmony_ci out, 157033d722a9Sopenharmony_ci "::std::size_t Vec<{}>::capacity() const noexcept {{", 157133d722a9Sopenharmony_ci inner, 157233d722a9Sopenharmony_ci ); 157333d722a9Sopenharmony_ci writeln!( 157433d722a9Sopenharmony_ci out, 157533d722a9Sopenharmony_ci " return cxxbridge1$rust_vec${}$capacity(this);", 157633d722a9Sopenharmony_ci instance, 157733d722a9Sopenharmony_ci ); 157833d722a9Sopenharmony_ci writeln!(out, "}}"); 157933d722a9Sopenharmony_ci 158033d722a9Sopenharmony_ci writeln!(out, "template <>"); 158133d722a9Sopenharmony_ci begin_function_definition(out); 158233d722a9Sopenharmony_ci writeln!(out, "{} const *Vec<{0}>::data() const noexcept {{", inner); 158333d722a9Sopenharmony_ci writeln!(out, " return cxxbridge1$rust_vec${}$data(this);", instance); 158433d722a9Sopenharmony_ci writeln!(out, "}}"); 158533d722a9Sopenharmony_ci 158633d722a9Sopenharmony_ci writeln!(out, "template <>"); 158733d722a9Sopenharmony_ci begin_function_definition(out); 158833d722a9Sopenharmony_ci writeln!( 158933d722a9Sopenharmony_ci out, 159033d722a9Sopenharmony_ci "void Vec<{}>::reserve_total(::std::size_t new_cap) noexcept {{", 159133d722a9Sopenharmony_ci inner, 159233d722a9Sopenharmony_ci ); 159333d722a9Sopenharmony_ci writeln!( 159433d722a9Sopenharmony_ci out, 159533d722a9Sopenharmony_ci " return cxxbridge1$rust_vec${}$reserve_total(this, new_cap);", 159633d722a9Sopenharmony_ci instance, 159733d722a9Sopenharmony_ci ); 159833d722a9Sopenharmony_ci writeln!(out, "}}"); 159933d722a9Sopenharmony_ci 160033d722a9Sopenharmony_ci writeln!(out, "template <>"); 160133d722a9Sopenharmony_ci begin_function_definition(out); 160233d722a9Sopenharmony_ci writeln!( 160333d722a9Sopenharmony_ci out, 160433d722a9Sopenharmony_ci "void Vec<{}>::set_len(::std::size_t len) noexcept {{", 160533d722a9Sopenharmony_ci inner, 160633d722a9Sopenharmony_ci ); 160733d722a9Sopenharmony_ci writeln!( 160833d722a9Sopenharmony_ci out, 160933d722a9Sopenharmony_ci " return cxxbridge1$rust_vec${}$set_len(this, len);", 161033d722a9Sopenharmony_ci instance, 161133d722a9Sopenharmony_ci ); 161233d722a9Sopenharmony_ci writeln!(out, "}}"); 161333d722a9Sopenharmony_ci 161433d722a9Sopenharmony_ci writeln!(out, "template <>"); 161533d722a9Sopenharmony_ci begin_function_definition(out); 161633d722a9Sopenharmony_ci writeln!(out, "void Vec<{}>::truncate(::std::size_t len) {{", inner,); 161733d722a9Sopenharmony_ci writeln!( 161833d722a9Sopenharmony_ci out, 161933d722a9Sopenharmony_ci " return cxxbridge1$rust_vec${}$truncate(this, len);", 162033d722a9Sopenharmony_ci instance, 162133d722a9Sopenharmony_ci ); 162233d722a9Sopenharmony_ci writeln!(out, "}}"); 162333d722a9Sopenharmony_ci} 162433d722a9Sopenharmony_ci 162533d722a9Sopenharmony_cifn write_unique_ptr(out: &mut OutFile, key: NamedImplKey) { 162633d722a9Sopenharmony_ci let ty = UniquePtr::Ident(key.rust); 162733d722a9Sopenharmony_ci write_unique_ptr_common(out, ty); 162833d722a9Sopenharmony_ci} 162933d722a9Sopenharmony_ci 163033d722a9Sopenharmony_ci// Shared by UniquePtr<T> and UniquePtr<CxxVector<T>>. 163133d722a9Sopenharmony_cifn write_unique_ptr_common(out: &mut OutFile, ty: UniquePtr) { 163233d722a9Sopenharmony_ci out.include.new = true; 163333d722a9Sopenharmony_ci out.include.utility = true; 163433d722a9Sopenharmony_ci let inner = ty.to_typename(out.types); 163533d722a9Sopenharmony_ci let instance = ty.to_mangled(out.types); 163633d722a9Sopenharmony_ci 163733d722a9Sopenharmony_ci let can_construct_from_value = match ty { 163833d722a9Sopenharmony_ci // Some aliases are to opaque types; some are to trivial types. We can't 163933d722a9Sopenharmony_ci // know at code generation time, so we generate both C++ and Rust side 164033d722a9Sopenharmony_ci // bindings for a "new" method anyway. But the Rust code can't be called 164133d722a9Sopenharmony_ci // for Opaque types because the 'new' method is not implemented. 164233d722a9Sopenharmony_ci UniquePtr::Ident(ident) => out.types.is_maybe_trivial(ident), 164333d722a9Sopenharmony_ci UniquePtr::CxxVector(_) => false, 164433d722a9Sopenharmony_ci }; 164533d722a9Sopenharmony_ci 164633d722a9Sopenharmony_ci let conditional_delete = match ty { 164733d722a9Sopenharmony_ci UniquePtr::Ident(ident) => { 164833d722a9Sopenharmony_ci !out.types.structs.contains_key(ident) && !out.types.enums.contains_key(ident) 164933d722a9Sopenharmony_ci } 165033d722a9Sopenharmony_ci UniquePtr::CxxVector(_) => false, 165133d722a9Sopenharmony_ci }; 165233d722a9Sopenharmony_ci 165333d722a9Sopenharmony_ci if conditional_delete { 165433d722a9Sopenharmony_ci out.builtin.is_complete = true; 165533d722a9Sopenharmony_ci let definition = match ty { 165633d722a9Sopenharmony_ci UniquePtr::Ident(ty) => &out.types.resolve(ty).name.cxx, 165733d722a9Sopenharmony_ci UniquePtr::CxxVector(_) => unreachable!(), 165833d722a9Sopenharmony_ci }; 165933d722a9Sopenharmony_ci writeln!( 166033d722a9Sopenharmony_ci out, 166133d722a9Sopenharmony_ci "static_assert(::rust::detail::is_complete<{}>::value, \"definition of {} is required\");", 166233d722a9Sopenharmony_ci inner, definition, 166333d722a9Sopenharmony_ci ); 166433d722a9Sopenharmony_ci } 166533d722a9Sopenharmony_ci writeln!( 166633d722a9Sopenharmony_ci out, 166733d722a9Sopenharmony_ci "static_assert(sizeof(::std::unique_ptr<{}>) == sizeof(void *), \"\");", 166833d722a9Sopenharmony_ci inner, 166933d722a9Sopenharmony_ci ); 167033d722a9Sopenharmony_ci writeln!( 167133d722a9Sopenharmony_ci out, 167233d722a9Sopenharmony_ci "static_assert(alignof(::std::unique_ptr<{}>) == alignof(void *), \"\");", 167333d722a9Sopenharmony_ci inner, 167433d722a9Sopenharmony_ci ); 167533d722a9Sopenharmony_ci begin_function_definition(out); 167633d722a9Sopenharmony_ci writeln!( 167733d722a9Sopenharmony_ci out, 167833d722a9Sopenharmony_ci "void cxxbridge1$unique_ptr${}$null(::std::unique_ptr<{}> *ptr) noexcept {{", 167933d722a9Sopenharmony_ci instance, inner, 168033d722a9Sopenharmony_ci ); 168133d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::unique_ptr<{}>();", inner); 168233d722a9Sopenharmony_ci writeln!(out, "}}"); 168333d722a9Sopenharmony_ci if can_construct_from_value { 168433d722a9Sopenharmony_ci out.builtin.maybe_uninit = true; 168533d722a9Sopenharmony_ci begin_function_definition(out); 168633d722a9Sopenharmony_ci writeln!( 168733d722a9Sopenharmony_ci out, 168833d722a9Sopenharmony_ci "{} *cxxbridge1$unique_ptr${}$uninit(::std::unique_ptr<{}> *ptr) noexcept {{", 168933d722a9Sopenharmony_ci inner, instance, inner, 169033d722a9Sopenharmony_ci ); 169133d722a9Sopenharmony_ci writeln!( 169233d722a9Sopenharmony_ci out, 169333d722a9Sopenharmony_ci " {} *uninit = reinterpret_cast<{} *>(new ::rust::MaybeUninit<{}>);", 169433d722a9Sopenharmony_ci inner, inner, inner, 169533d722a9Sopenharmony_ci ); 169633d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::unique_ptr<{}>(uninit);", inner); 169733d722a9Sopenharmony_ci writeln!(out, " return uninit;"); 169833d722a9Sopenharmony_ci writeln!(out, "}}"); 169933d722a9Sopenharmony_ci } 170033d722a9Sopenharmony_ci begin_function_definition(out); 170133d722a9Sopenharmony_ci writeln!( 170233d722a9Sopenharmony_ci out, 170333d722a9Sopenharmony_ci "void cxxbridge1$unique_ptr${}$raw(::std::unique_ptr<{}> *ptr, {} *raw) noexcept {{", 170433d722a9Sopenharmony_ci instance, inner, inner, 170533d722a9Sopenharmony_ci ); 170633d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::unique_ptr<{}>(raw);", inner); 170733d722a9Sopenharmony_ci writeln!(out, "}}"); 170833d722a9Sopenharmony_ci begin_function_definition(out); 170933d722a9Sopenharmony_ci writeln!( 171033d722a9Sopenharmony_ci out, 171133d722a9Sopenharmony_ci "{} const *cxxbridge1$unique_ptr${}$get(::std::unique_ptr<{}> const &ptr) noexcept {{", 171233d722a9Sopenharmony_ci inner, instance, inner, 171333d722a9Sopenharmony_ci ); 171433d722a9Sopenharmony_ci writeln!(out, " return ptr.get();"); 171533d722a9Sopenharmony_ci writeln!(out, "}}"); 171633d722a9Sopenharmony_ci begin_function_definition(out); 171733d722a9Sopenharmony_ci writeln!( 171833d722a9Sopenharmony_ci out, 171933d722a9Sopenharmony_ci "{} *cxxbridge1$unique_ptr${}$release(::std::unique_ptr<{}> &ptr) noexcept {{", 172033d722a9Sopenharmony_ci inner, instance, inner, 172133d722a9Sopenharmony_ci ); 172233d722a9Sopenharmony_ci writeln!(out, " return ptr.release();"); 172333d722a9Sopenharmony_ci writeln!(out, "}}"); 172433d722a9Sopenharmony_ci begin_function_definition(out); 172533d722a9Sopenharmony_ci writeln!( 172633d722a9Sopenharmony_ci out, 172733d722a9Sopenharmony_ci "void cxxbridge1$unique_ptr${}$drop(::std::unique_ptr<{}> *ptr) noexcept {{", 172833d722a9Sopenharmony_ci instance, inner, 172933d722a9Sopenharmony_ci ); 173033d722a9Sopenharmony_ci if conditional_delete { 173133d722a9Sopenharmony_ci out.builtin.deleter_if = true; 173233d722a9Sopenharmony_ci writeln!( 173333d722a9Sopenharmony_ci out, 173433d722a9Sopenharmony_ci " ::rust::deleter_if<::rust::detail::is_complete<{}>::value>{{}}(ptr);", 173533d722a9Sopenharmony_ci inner, 173633d722a9Sopenharmony_ci ); 173733d722a9Sopenharmony_ci } else { 173833d722a9Sopenharmony_ci writeln!(out, " ptr->~unique_ptr();"); 173933d722a9Sopenharmony_ci } 174033d722a9Sopenharmony_ci writeln!(out, "}}"); 174133d722a9Sopenharmony_ci} 174233d722a9Sopenharmony_ci 174333d722a9Sopenharmony_cifn write_shared_ptr(out: &mut OutFile, key: NamedImplKey) { 174433d722a9Sopenharmony_ci let ident = key.rust; 174533d722a9Sopenharmony_ci let resolve = out.types.resolve(ident); 174633d722a9Sopenharmony_ci let inner = resolve.name.to_fully_qualified(); 174733d722a9Sopenharmony_ci let instance = resolve.name.to_symbol(); 174833d722a9Sopenharmony_ci 174933d722a9Sopenharmony_ci out.include.new = true; 175033d722a9Sopenharmony_ci out.include.utility = true; 175133d722a9Sopenharmony_ci 175233d722a9Sopenharmony_ci // Some aliases are to opaque types; some are to trivial types. We can't 175333d722a9Sopenharmony_ci // know at code generation time, so we generate both C++ and Rust side 175433d722a9Sopenharmony_ci // bindings for a "new" method anyway. But the Rust code can't be called for 175533d722a9Sopenharmony_ci // Opaque types because the 'new' method is not implemented. 175633d722a9Sopenharmony_ci let can_construct_from_value = out.types.is_maybe_trivial(ident); 175733d722a9Sopenharmony_ci 175833d722a9Sopenharmony_ci writeln!( 175933d722a9Sopenharmony_ci out, 176033d722a9Sopenharmony_ci "static_assert(sizeof(::std::shared_ptr<{}>) == 2 * sizeof(void *), \"\");", 176133d722a9Sopenharmony_ci inner, 176233d722a9Sopenharmony_ci ); 176333d722a9Sopenharmony_ci writeln!( 176433d722a9Sopenharmony_ci out, 176533d722a9Sopenharmony_ci "static_assert(alignof(::std::shared_ptr<{}>) == alignof(void *), \"\");", 176633d722a9Sopenharmony_ci inner, 176733d722a9Sopenharmony_ci ); 176833d722a9Sopenharmony_ci begin_function_definition(out); 176933d722a9Sopenharmony_ci writeln!( 177033d722a9Sopenharmony_ci out, 177133d722a9Sopenharmony_ci "void cxxbridge1$shared_ptr${}$null(::std::shared_ptr<{}> *ptr) noexcept {{", 177233d722a9Sopenharmony_ci instance, inner, 177333d722a9Sopenharmony_ci ); 177433d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::shared_ptr<{}>();", inner); 177533d722a9Sopenharmony_ci writeln!(out, "}}"); 177633d722a9Sopenharmony_ci if can_construct_from_value { 177733d722a9Sopenharmony_ci out.builtin.maybe_uninit = true; 177833d722a9Sopenharmony_ci begin_function_definition(out); 177933d722a9Sopenharmony_ci writeln!( 178033d722a9Sopenharmony_ci out, 178133d722a9Sopenharmony_ci "{} *cxxbridge1$shared_ptr${}$uninit(::std::shared_ptr<{}> *ptr) noexcept {{", 178233d722a9Sopenharmony_ci inner, instance, inner, 178333d722a9Sopenharmony_ci ); 178433d722a9Sopenharmony_ci writeln!( 178533d722a9Sopenharmony_ci out, 178633d722a9Sopenharmony_ci " {} *uninit = reinterpret_cast<{} *>(new ::rust::MaybeUninit<{}>);", 178733d722a9Sopenharmony_ci inner, inner, inner, 178833d722a9Sopenharmony_ci ); 178933d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::shared_ptr<{}>(uninit);", inner); 179033d722a9Sopenharmony_ci writeln!(out, " return uninit;"); 179133d722a9Sopenharmony_ci writeln!(out, "}}"); 179233d722a9Sopenharmony_ci } 179333d722a9Sopenharmony_ci begin_function_definition(out); 179433d722a9Sopenharmony_ci writeln!( 179533d722a9Sopenharmony_ci out, 179633d722a9Sopenharmony_ci "void cxxbridge1$shared_ptr${}$clone(::std::shared_ptr<{}> const &self, ::std::shared_ptr<{}> *ptr) noexcept {{", 179733d722a9Sopenharmony_ci instance, inner, inner, 179833d722a9Sopenharmony_ci ); 179933d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::shared_ptr<{}>(self);", inner); 180033d722a9Sopenharmony_ci writeln!(out, "}}"); 180133d722a9Sopenharmony_ci begin_function_definition(out); 180233d722a9Sopenharmony_ci writeln!( 180333d722a9Sopenharmony_ci out, 180433d722a9Sopenharmony_ci "{} const *cxxbridge1$shared_ptr${}$get(::std::shared_ptr<{}> const &self) noexcept {{", 180533d722a9Sopenharmony_ci inner, instance, inner, 180633d722a9Sopenharmony_ci ); 180733d722a9Sopenharmony_ci writeln!(out, " return self.get();"); 180833d722a9Sopenharmony_ci writeln!(out, "}}"); 180933d722a9Sopenharmony_ci begin_function_definition(out); 181033d722a9Sopenharmony_ci writeln!( 181133d722a9Sopenharmony_ci out, 181233d722a9Sopenharmony_ci "void cxxbridge1$shared_ptr${}$drop(::std::shared_ptr<{}> *self) noexcept {{", 181333d722a9Sopenharmony_ci instance, inner, 181433d722a9Sopenharmony_ci ); 181533d722a9Sopenharmony_ci writeln!(out, " self->~shared_ptr();"); 181633d722a9Sopenharmony_ci writeln!(out, "}}"); 181733d722a9Sopenharmony_ci} 181833d722a9Sopenharmony_ci 181933d722a9Sopenharmony_cifn write_weak_ptr(out: &mut OutFile, key: NamedImplKey) { 182033d722a9Sopenharmony_ci let resolve = out.types.resolve(&key); 182133d722a9Sopenharmony_ci let inner = resolve.name.to_fully_qualified(); 182233d722a9Sopenharmony_ci let instance = resolve.name.to_symbol(); 182333d722a9Sopenharmony_ci 182433d722a9Sopenharmony_ci out.include.new = true; 182533d722a9Sopenharmony_ci out.include.utility = true; 182633d722a9Sopenharmony_ci 182733d722a9Sopenharmony_ci writeln!( 182833d722a9Sopenharmony_ci out, 182933d722a9Sopenharmony_ci "static_assert(sizeof(::std::weak_ptr<{}>) == 2 * sizeof(void *), \"\");", 183033d722a9Sopenharmony_ci inner, 183133d722a9Sopenharmony_ci ); 183233d722a9Sopenharmony_ci writeln!( 183333d722a9Sopenharmony_ci out, 183433d722a9Sopenharmony_ci "static_assert(alignof(::std::weak_ptr<{}>) == alignof(void *), \"\");", 183533d722a9Sopenharmony_ci inner, 183633d722a9Sopenharmony_ci ); 183733d722a9Sopenharmony_ci writeln!( 183833d722a9Sopenharmony_ci out, 183933d722a9Sopenharmony_ci "void cxxbridge1$weak_ptr${}$null(::std::weak_ptr<{}> *ptr) noexcept {{", 184033d722a9Sopenharmony_ci instance, inner, 184133d722a9Sopenharmony_ci ); 184233d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::weak_ptr<{}>();", inner); 184333d722a9Sopenharmony_ci writeln!(out, "}}"); 184433d722a9Sopenharmony_ci begin_function_definition(out); 184533d722a9Sopenharmony_ci writeln!( 184633d722a9Sopenharmony_ci out, 184733d722a9Sopenharmony_ci "void cxxbridge1$weak_ptr${}$clone(::std::weak_ptr<{}> const &self, ::std::weak_ptr<{}> *ptr) noexcept {{", 184833d722a9Sopenharmony_ci instance, inner, inner, 184933d722a9Sopenharmony_ci ); 185033d722a9Sopenharmony_ci writeln!(out, " ::new (ptr) ::std::weak_ptr<{}>(self);", inner); 185133d722a9Sopenharmony_ci writeln!(out, "}}"); 185233d722a9Sopenharmony_ci begin_function_definition(out); 185333d722a9Sopenharmony_ci writeln!( 185433d722a9Sopenharmony_ci out, 185533d722a9Sopenharmony_ci "void cxxbridge1$weak_ptr${}$downgrade(::std::shared_ptr<{}> const &shared, ::std::weak_ptr<{}> *weak) noexcept {{", 185633d722a9Sopenharmony_ci instance, inner, inner, 185733d722a9Sopenharmony_ci ); 185833d722a9Sopenharmony_ci writeln!(out, " ::new (weak) ::std::weak_ptr<{}>(shared);", inner); 185933d722a9Sopenharmony_ci writeln!(out, "}}"); 186033d722a9Sopenharmony_ci begin_function_definition(out); 186133d722a9Sopenharmony_ci writeln!( 186233d722a9Sopenharmony_ci out, 186333d722a9Sopenharmony_ci "void cxxbridge1$weak_ptr${}$upgrade(::std::weak_ptr<{}> const &weak, ::std::shared_ptr<{}> *shared) noexcept {{", 186433d722a9Sopenharmony_ci instance, inner, inner, 186533d722a9Sopenharmony_ci ); 186633d722a9Sopenharmony_ci writeln!( 186733d722a9Sopenharmony_ci out, 186833d722a9Sopenharmony_ci " ::new (shared) ::std::shared_ptr<{}>(weak.lock());", 186933d722a9Sopenharmony_ci inner, 187033d722a9Sopenharmony_ci ); 187133d722a9Sopenharmony_ci writeln!(out, "}}"); 187233d722a9Sopenharmony_ci begin_function_definition(out); 187333d722a9Sopenharmony_ci writeln!( 187433d722a9Sopenharmony_ci out, 187533d722a9Sopenharmony_ci "void cxxbridge1$weak_ptr${}$drop(::std::weak_ptr<{}> *self) noexcept {{", 187633d722a9Sopenharmony_ci instance, inner, 187733d722a9Sopenharmony_ci ); 187833d722a9Sopenharmony_ci writeln!(out, " self->~weak_ptr();"); 187933d722a9Sopenharmony_ci writeln!(out, "}}"); 188033d722a9Sopenharmony_ci} 188133d722a9Sopenharmony_ci 188233d722a9Sopenharmony_cifn write_cxx_vector(out: &mut OutFile, key: NamedImplKey) { 188333d722a9Sopenharmony_ci let element = key.rust; 188433d722a9Sopenharmony_ci let inner = element.to_typename(out.types); 188533d722a9Sopenharmony_ci let instance = element.to_mangled(out.types); 188633d722a9Sopenharmony_ci 188733d722a9Sopenharmony_ci out.include.cstddef = true; 188833d722a9Sopenharmony_ci out.include.utility = true; 188933d722a9Sopenharmony_ci out.builtin.destroy = true; 189033d722a9Sopenharmony_ci 189133d722a9Sopenharmony_ci writeln!( 189233d722a9Sopenharmony_ci out, 189333d722a9Sopenharmony_ci "::std::size_t cxxbridge1$std$vector${}$size(::std::vector<{}> const &s) noexcept {{", 189433d722a9Sopenharmony_ci instance, inner, 189533d722a9Sopenharmony_ci ); 189633d722a9Sopenharmony_ci writeln!(out, " return s.size();"); 189733d722a9Sopenharmony_ci writeln!(out, "}}"); 189833d722a9Sopenharmony_ci 189933d722a9Sopenharmony_ci begin_function_definition(out); 190033d722a9Sopenharmony_ci writeln!( 190133d722a9Sopenharmony_ci out, 190233d722a9Sopenharmony_ci "{} *cxxbridge1$std$vector${}$get_unchecked(::std::vector<{}> *s, ::std::size_t pos) noexcept {{", 190333d722a9Sopenharmony_ci inner, instance, inner, 190433d722a9Sopenharmony_ci ); 190533d722a9Sopenharmony_ci writeln!(out, " return &(*s)[pos];"); 190633d722a9Sopenharmony_ci writeln!(out, "}}"); 190733d722a9Sopenharmony_ci 190833d722a9Sopenharmony_ci if out.types.is_maybe_trivial(element) { 190933d722a9Sopenharmony_ci begin_function_definition(out); 191033d722a9Sopenharmony_ci writeln!( 191133d722a9Sopenharmony_ci out, 191233d722a9Sopenharmony_ci "void cxxbridge1$std$vector${}$push_back(::std::vector<{}> *v, {} *value) noexcept {{", 191333d722a9Sopenharmony_ci instance, inner, inner, 191433d722a9Sopenharmony_ci ); 191533d722a9Sopenharmony_ci writeln!(out, " v->push_back(::std::move(*value));"); 191633d722a9Sopenharmony_ci writeln!(out, " ::rust::destroy(value);"); 191733d722a9Sopenharmony_ci writeln!(out, "}}"); 191833d722a9Sopenharmony_ci 191933d722a9Sopenharmony_ci begin_function_definition(out); 192033d722a9Sopenharmony_ci writeln!( 192133d722a9Sopenharmony_ci out, 192233d722a9Sopenharmony_ci "void cxxbridge1$std$vector${}$pop_back(::std::vector<{}> *v, {} *out) noexcept {{", 192333d722a9Sopenharmony_ci instance, inner, inner, 192433d722a9Sopenharmony_ci ); 192533d722a9Sopenharmony_ci writeln!(out, " ::new (out) {}(::std::move(v->back()));", inner); 192633d722a9Sopenharmony_ci writeln!(out, " v->pop_back();"); 192733d722a9Sopenharmony_ci writeln!(out, "}}"); 192833d722a9Sopenharmony_ci } 192933d722a9Sopenharmony_ci 193033d722a9Sopenharmony_ci out.include.memory = true; 193133d722a9Sopenharmony_ci write_unique_ptr_common(out, UniquePtr::CxxVector(element)); 193233d722a9Sopenharmony_ci} 1933