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