blob: 3695de0997e43aa5639f4836fa65e2be04d87ecb [file] [log] [blame]
Brian Silverman4e662aa2022-05-11 23:10:19 -07001// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9//! Code to create functions to alloc and free while unitialized.
10
11use syn::{parse_quote, punctuated::Punctuated, token::Comma, FnArg, ReturnType};
12
13use crate::{
14 conversion::{
15 api::{Api, ApiName, CppVisibility, FuncToConvert, Provenance, References, TraitSynthesis},
16 apivec::ApiVec,
17 },
18 types::{make_ident, QualifiedName},
19};
20
21use super::{
22 fun::function_wrapper::{CppFunctionBody, CppFunctionKind},
23 pod::PodPhase,
24};
25
26pub(crate) fn create_alloc_and_frees(apis: ApiVec<PodPhase>) -> ApiVec<PodPhase> {
27 apis.into_iter()
28 .flat_map(|api| -> Box<dyn Iterator<Item = Api<PodPhase>>> {
29 match &api {
30 Api::Struct { name, .. } => {
31 Box::new(create_alloc_and_free(name.name.clone()).chain(std::iter::once(api)))
32 }
33 Api::Subclass { name, .. } => {
34 Box::new(create_alloc_and_free(name.cpp()).chain(std::iter::once(api)))
35 }
36 _ => Box::new(std::iter::once(api)),
37 }
38 })
39 .collect()
40}
41
42fn create_alloc_and_free(ty_name: QualifiedName) -> impl Iterator<Item = Api<PodPhase>> {
43 let typ = ty_name.to_type_path();
44 let free_inputs: Punctuated<FnArg, Comma> = parse_quote! {
45 arg0: *mut #typ
46 };
47 let alloc_return: ReturnType = parse_quote! {
48 -> *mut #typ
49 };
50 [
51 (
52 TraitSynthesis::AllocUninitialized(ty_name.clone()),
53 get_alloc_name(&ty_name),
54 Punctuated::new(),
55 alloc_return,
56 CppFunctionBody::AllocUninitialized(ty_name.clone()),
57 ),
58 (
59 TraitSynthesis::FreeUninitialized(ty_name.clone()),
60 get_free_name(&ty_name),
61 free_inputs,
62 ReturnType::Default,
63 CppFunctionBody::FreeUninitialized(ty_name.clone()),
64 ),
65 ]
66 .into_iter()
67 .map(
68 move |(synthesis, name, inputs, output, cpp_function_body)| {
69 let ident = name.get_final_ident();
70 let api_name = ApiName::new_from_qualified_name(name);
71 Api::Function {
72 name: api_name,
73 fun: Box::new(FuncToConvert {
74 ident,
75 doc_attrs: Vec::new(),
76 inputs,
77 output,
78 vis: parse_quote! { pub },
79 virtualness: crate::conversion::api::Virtualness::None,
80 cpp_vis: CppVisibility::Public,
81 special_member: None,
82 unused_template_param: false,
83 references: References::default(),
84 original_name: None,
85 self_ty: None,
86 synthesized_this_type: None,
87 synthetic_cpp: Some((cpp_function_body, CppFunctionKind::Function)),
88 add_to_trait: Some(synthesis),
89 is_deleted: false,
90 provenance: Provenance::SynthesizedOther,
91 variadic: false,
92 }),
93 analysis: (),
94 }
95 },
96 )
97}
98
99pub(crate) fn get_alloc_name(ty_name: &QualifiedName) -> QualifiedName {
100 get_name(ty_name, "alloc")
101}
102
103pub(crate) fn get_free_name(ty_name: &QualifiedName) -> QualifiedName {
104 get_name(ty_name, "free")
105}
106
107fn get_name(ty_name: &QualifiedName, label: &str) -> QualifiedName {
108 let name = format!("{}_{}", ty_name.get_final_item(), label);
109 let name_id = make_ident(name);
110 QualifiedName::new(ty_name.get_namespace(), name_id)
111}