blob: da25a776c43333e133a4325b554becaaf82c3097 [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::{
Austin Schuh6ea9bfa2023-08-06 19:05:10 -070015 api::{
16 Api, ApiName, CppVisibility, DeletedOrDefaulted, FuncToConvert, Provenance, References,
17 TraitSynthesis,
18 },
Brian Silverman4e662aa2022-05-11 23:10:19 -070019 apivec::ApiVec,
20 },
Austin Schuh6ea9bfa2023-08-06 19:05:10 -070021 minisyn::minisynize_punctuated,
Brian Silverman4e662aa2022-05-11 23:10:19 -070022 types::{make_ident, QualifiedName},
23};
24
25use super::{
26 fun::function_wrapper::{CppFunctionBody, CppFunctionKind},
27 pod::PodPhase,
28};
29
30pub(crate) fn create_alloc_and_frees(apis: ApiVec<PodPhase>) -> ApiVec<PodPhase> {
31 apis.into_iter()
32 .flat_map(|api| -> Box<dyn Iterator<Item = Api<PodPhase>>> {
33 match &api {
34 Api::Struct { name, .. } => {
35 Box::new(create_alloc_and_free(name.name.clone()).chain(std::iter::once(api)))
36 }
37 Api::Subclass { name, .. } => {
38 Box::new(create_alloc_and_free(name.cpp()).chain(std::iter::once(api)))
39 }
40 _ => Box::new(std::iter::once(api)),
41 }
42 })
43 .collect()
44}
45
46fn create_alloc_and_free(ty_name: QualifiedName) -> impl Iterator<Item = Api<PodPhase>> {
47 let typ = ty_name.to_type_path();
48 let free_inputs: Punctuated<FnArg, Comma> = parse_quote! {
49 arg0: *mut #typ
50 };
51 let alloc_return: ReturnType = parse_quote! {
52 -> *mut #typ
53 };
54 [
55 (
56 TraitSynthesis::AllocUninitialized(ty_name.clone()),
57 get_alloc_name(&ty_name),
58 Punctuated::new(),
59 alloc_return,
60 CppFunctionBody::AllocUninitialized(ty_name.clone()),
61 ),
62 (
63 TraitSynthesis::FreeUninitialized(ty_name.clone()),
64 get_free_name(&ty_name),
65 free_inputs,
66 ReturnType::Default,
67 CppFunctionBody::FreeUninitialized(ty_name.clone()),
68 ),
69 ]
70 .into_iter()
71 .map(
72 move |(synthesis, name, inputs, output, cpp_function_body)| {
73 let ident = name.get_final_ident();
74 let api_name = ApiName::new_from_qualified_name(name);
75 Api::Function {
76 name: api_name,
77 fun: Box::new(FuncToConvert {
78 ident,
79 doc_attrs: Vec::new(),
Austin Schuh6ea9bfa2023-08-06 19:05:10 -070080 inputs: minisynize_punctuated(inputs),
81 output: output.into(),
Brian Silverman4e662aa2022-05-11 23:10:19 -070082 vis: parse_quote! { pub },
83 virtualness: crate::conversion::api::Virtualness::None,
84 cpp_vis: CppVisibility::Public,
85 special_member: None,
86 unused_template_param: false,
87 references: References::default(),
88 original_name: None,
89 self_ty: None,
90 synthesized_this_type: None,
91 synthetic_cpp: Some((cpp_function_body, CppFunctionKind::Function)),
92 add_to_trait: Some(synthesis),
Austin Schuh6ea9bfa2023-08-06 19:05:10 -070093 is_deleted: DeletedOrDefaulted::Neither,
Brian Silverman4e662aa2022-05-11 23:10:19 -070094 provenance: Provenance::SynthesizedOther,
95 variadic: false,
96 }),
97 analysis: (),
98 }
99 },
100 )
101}
102
103pub(crate) fn get_alloc_name(ty_name: &QualifiedName) -> QualifiedName {
104 get_name(ty_name, "alloc")
105}
106
107pub(crate) fn get_free_name(ty_name: &QualifiedName) -> QualifiedName {
108 get_name(ty_name, "free")
109}
110
111fn get_name(ty_name: &QualifiedName, label: &str) -> QualifiedName {
112 let name = format!("{}_{}", ty_name.get_final_item(), label);
113 let name_id = make_ident(name);
114 QualifiedName::new(ty_name.get_namespace(), name_id)
115}