1 use std::io::Write;
2
3 use crate::callbacks::IntKind;
4
5 use crate::ir::comp::CompKind;
6 use crate::ir::context::{BindgenContext, TypeId};
7 use crate::ir::function::{Function, FunctionKind};
8 use crate::ir::item::Item;
9 use crate::ir::item::ItemCanonicalName;
10 use crate::ir::item_kind::ItemKind;
11 use crate::ir::ty::{FloatKind, Type, TypeKind};
12
13 use super::CodegenError;
14
get_loc(item: &Item) -> String15 fn get_loc(item: &Item) -> String {
16 item.location()
17 .map(|x| x.to_string())
18 .unwrap_or_else(|| "unknown".to_owned())
19 }
20
21 pub(crate) trait CSerialize<'a> {
22 type Extra;
23
serialize<W: Write>( &self, ctx: &BindgenContext, extra: Self::Extra, stack: &mut Vec<String>, writer: &mut W, ) -> Result<(), CodegenError>24 fn serialize<W: Write>(
25 &self,
26 ctx: &BindgenContext,
27 extra: Self::Extra,
28 stack: &mut Vec<String>,
29 writer: &mut W,
30 ) -> Result<(), CodegenError>;
31 }
32
33 impl<'a> CSerialize<'a> for Item {
34 type Extra = ();
35
serialize<W: Write>( &self, ctx: &BindgenContext, (): Self::Extra, stack: &mut Vec<String>, writer: &mut W, ) -> Result<(), CodegenError>36 fn serialize<W: Write>(
37 &self,
38 ctx: &BindgenContext,
39 (): Self::Extra,
40 stack: &mut Vec<String>,
41 writer: &mut W,
42 ) -> Result<(), CodegenError> {
43 match self.kind() {
44 ItemKind::Function(func) => {
45 func.serialize(ctx, self, stack, writer)
46 }
47 kind => {
48 return Err(CodegenError::Serialize {
49 msg: format!("Cannot serialize item kind {:?}", kind),
50 loc: get_loc(self),
51 });
52 }
53 }
54 }
55 }
56
57 impl<'a> CSerialize<'a> for Function {
58 type Extra = &'a Item;
59
serialize<W: Write>( &self, ctx: &BindgenContext, item: Self::Extra, stack: &mut Vec<String>, writer: &mut W, ) -> Result<(), CodegenError>60 fn serialize<W: Write>(
61 &self,
62 ctx: &BindgenContext,
63 item: Self::Extra,
64 stack: &mut Vec<String>,
65 writer: &mut W,
66 ) -> Result<(), CodegenError> {
67 if self.kind() != FunctionKind::Function {
68 return Err(CodegenError::Serialize {
69 msg: format!(
70 "Cannot serialize function kind {:?}",
71 self.kind(),
72 ),
73 loc: get_loc(item),
74 });
75 }
76
77 let signature = match ctx.resolve_type(self.signature()).kind() {
78 TypeKind::Function(signature) => signature,
79 _ => unreachable!(),
80 };
81
82 let name = self.name();
83
84 // Function argoments stored as `(name, type_id)` tuples.
85 let args = {
86 let mut count = 0;
87
88 signature
89 .argument_types()
90 .iter()
91 .cloned()
92 .map(|(opt_name, type_id)| {
93 (
94 opt_name.unwrap_or_else(|| {
95 let name = format!("arg_{}", count);
96 count += 1;
97 name
98 }),
99 type_id,
100 )
101 })
102 .collect::<Vec<_>>()
103 };
104
105 // The name used for the wrapper self.
106 let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix());
107 // The function's return type
108 let ret_ty = signature.return_type();
109
110 // Write `ret_ty wrap_name(args) asm("wrap_name");`
111 ret_ty.serialize(ctx, (), stack, writer)?;
112 write!(writer, " {}(", wrap_name)?;
113 if args.is_empty() {
114 write!(writer, "void")?;
115 } else {
116 serialize_sep(
117 ", ",
118 args.iter(),
119 ctx,
120 writer,
121 |(name, type_id), ctx, buf| {
122 type_id.serialize(ctx, (), &mut vec![name.clone()], buf)
123 },
124 )?;
125 }
126 writeln!(writer, ") asm(\"{}\");", wrap_name)?;
127
128 // Write `ret_ty wrap_name(args) { return name(arg_names)' }`
129 ret_ty.serialize(ctx, (), stack, writer)?;
130 write!(writer, " {}(", wrap_name)?;
131 serialize_sep(
132 ", ",
133 args.iter(),
134 ctx,
135 writer,
136 |(name, type_id), _, buf| {
137 type_id.serialize(ctx, (), &mut vec![name.clone()], buf)
138 },
139 )?;
140 write!(writer, ") {{ return {}(", name)?;
141 serialize_sep(", ", args.iter(), ctx, writer, |(name, _), _, buf| {
142 write!(buf, "{}", name).map_err(From::from)
143 })?;
144 writeln!(writer, "); }}")?;
145
146 Ok(())
147 }
148 }
149
150 impl<'a> CSerialize<'a> for TypeId {
151 type Extra = ();
152
serialize<W: Write>( &self, ctx: &BindgenContext, (): Self::Extra, stack: &mut Vec<String>, writer: &mut W, ) -> Result<(), CodegenError>153 fn serialize<W: Write>(
154 &self,
155 ctx: &BindgenContext,
156 (): Self::Extra,
157 stack: &mut Vec<String>,
158 writer: &mut W,
159 ) -> Result<(), CodegenError> {
160 let item = ctx.resolve_item(*self);
161 item.expect_type().serialize(ctx, item, stack, writer)
162 }
163 }
164
165 impl<'a> CSerialize<'a> for Type {
166 type Extra = &'a Item;
167
serialize<W: Write>( &self, ctx: &BindgenContext, item: Self::Extra, stack: &mut Vec<String>, writer: &mut W, ) -> Result<(), CodegenError>168 fn serialize<W: Write>(
169 &self,
170 ctx: &BindgenContext,
171 item: Self::Extra,
172 stack: &mut Vec<String>,
173 writer: &mut W,
174 ) -> Result<(), CodegenError> {
175 match self.kind() {
176 TypeKind::Void => {
177 if self.is_const() {
178 write!(writer, "const ")?;
179 }
180 write!(writer, "void")?
181 }
182 TypeKind::NullPtr => {
183 if self.is_const() {
184 write!(writer, "const ")?;
185 }
186 write!(writer, "nullptr_t")?
187 }
188 TypeKind::Int(int_kind) => {
189 if self.is_const() {
190 write!(writer, "const ")?;
191 }
192 match int_kind {
193 IntKind::Bool => write!(writer, "bool")?,
194 IntKind::SChar => write!(writer, "signed char")?,
195 IntKind::UChar => write!(writer, "unsigned char")?,
196 IntKind::WChar => write!(writer, "wchar_t")?,
197 IntKind::Short => write!(writer, "short")?,
198 IntKind::UShort => write!(writer, "unsigned short")?,
199 IntKind::Int => write!(writer, "int")?,
200 IntKind::UInt => write!(writer, "unsigned int")?,
201 IntKind::Long => write!(writer, "long")?,
202 IntKind::ULong => write!(writer, "unsigned long")?,
203 IntKind::LongLong => write!(writer, "long long")?,
204 IntKind::ULongLong => write!(writer, "unsigned long long")?,
205 IntKind::Char { .. } => write!(writer, "char")?,
206 int_kind => {
207 return Err(CodegenError::Serialize {
208 msg: format!(
209 "Cannot serialize integer kind {:?}",
210 int_kind
211 ),
212 loc: get_loc(item),
213 })
214 }
215 }
216 }
217 TypeKind::Float(float_kind) => {
218 if self.is_const() {
219 write!(writer, "const ")?;
220 }
221 match float_kind {
222 FloatKind::Float => write!(writer, "float")?,
223 FloatKind::Double => write!(writer, "double")?,
224 FloatKind::LongDouble => write!(writer, "long double")?,
225 FloatKind::Float128 => write!(writer, "__float128")?,
226 }
227 }
228 TypeKind::Complex(float_kind) => {
229 if self.is_const() {
230 write!(writer, "const ")?;
231 }
232 match float_kind {
233 FloatKind::Float => write!(writer, "float complex")?,
234 FloatKind::Double => write!(writer, "double complex")?,
235 FloatKind::LongDouble => {
236 write!(writer, "long double complex")?
237 }
238 FloatKind::Float128 => write!(writer, "__complex128")?,
239 }
240 }
241 TypeKind::Alias(type_id) => {
242 if let Some(name) = self.name() {
243 if self.is_const() {
244 write!(writer, "const {}", name)?;
245 } else {
246 write!(writer, "{}", name)?;
247 }
248 } else {
249 type_id.serialize(ctx, (), stack, writer)?;
250 }
251 }
252 TypeKind::Array(type_id, length) => {
253 type_id.serialize(ctx, (), stack, writer)?;
254 write!(writer, " [{}]", length)?
255 }
256 TypeKind::Function(signature) => {
257 if self.is_const() {
258 stack.push("const ".to_string());
259 }
260
261 signature.return_type().serialize(
262 ctx,
263 (),
264 &mut vec![],
265 writer,
266 )?;
267
268 write!(writer, " (")?;
269 while let Some(item) = stack.pop() {
270 write!(writer, "{}", item)?;
271 }
272 write!(writer, ")")?;
273
274 write!(writer, " (")?;
275 serialize_sep(
276 ", ",
277 signature.argument_types().iter(),
278 ctx,
279 writer,
280 |(name, type_id), ctx, buf| {
281 let mut stack = vec![];
282 if let Some(name) = name {
283 stack.push(name.clone());
284 }
285 type_id.serialize(ctx, (), &mut stack, buf)
286 },
287 )?;
288 write!(writer, ")")?
289 }
290 TypeKind::ResolvedTypeRef(type_id) => {
291 if self.is_const() {
292 write!(writer, "const ")?;
293 }
294 type_id.serialize(ctx, (), stack, writer)?
295 }
296 TypeKind::Pointer(type_id) => {
297 if self.is_const() {
298 stack.push("*const ".to_owned());
299 } else {
300 stack.push("*".to_owned());
301 }
302 type_id.serialize(ctx, (), stack, writer)?
303 }
304 TypeKind::Comp(comp_info) => {
305 if self.is_const() {
306 write!(writer, "const ")?;
307 }
308
309 let name = item.canonical_name(ctx);
310
311 match comp_info.kind() {
312 CompKind::Struct => write!(writer, "struct {}", name)?,
313 CompKind::Union => write!(writer, "union {}", name)?,
314 };
315 }
316 ty => {
317 return Err(CodegenError::Serialize {
318 msg: format!("Cannot serialize type kind {:?}", ty),
319 loc: get_loc(item),
320 })
321 }
322 };
323
324 if !stack.is_empty() {
325 write!(writer, " ")?;
326 while let Some(item) = stack.pop() {
327 write!(writer, "{}", item)?;
328 }
329 }
330
331 Ok(())
332 }
333 }
334
serialize_sep< W: Write, F: FnMut(I::Item, &BindgenContext, &mut W) -> Result<(), CodegenError>, I: Iterator, >( sep: &str, mut iter: I, ctx: &BindgenContext, buf: &mut W, mut f: F, ) -> Result<(), CodegenError>335 fn serialize_sep<
336 W: Write,
337 F: FnMut(I::Item, &BindgenContext, &mut W) -> Result<(), CodegenError>,
338 I: Iterator,
339 >(
340 sep: &str,
341 mut iter: I,
342 ctx: &BindgenContext,
343 buf: &mut W,
344 mut f: F,
345 ) -> Result<(), CodegenError> {
346 if let Some(item) = iter.next() {
347 f(item, ctx, buf)?;
348 let sep = sep.as_bytes();
349 for item in iter {
350 buf.write_all(sep)?;
351 f(item, ctx, buf)?;
352 }
353 }
354
355 Ok(())
356 }
357