cbindgen/bindgen/
library.rs1use std::collections::HashMap;
6use std::path::PathBuf;
7
8use crate::bindgen::bindings::Bindings;
9use crate::bindgen::config::{Config, Language, SortKey};
10use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver;
11use crate::bindgen::dependencies::Dependencies;
12use crate::bindgen::error::Error;
13use crate::bindgen::ir::{Constant, Enum, Function, Item, ItemContainer, ItemMap};
14use crate::bindgen::ir::{OpaqueItem, Path, Static, Struct, Typedef, Union};
15use crate::bindgen::monomorph::Monomorphs;
16use crate::bindgen::ItemType;
17
18#[derive(Debug, Clone)]
19pub struct Library {
20 config: Config,
21 constants: ItemMap<Constant>,
22 globals: ItemMap<Static>,
23 enums: ItemMap<Enum>,
24 structs: ItemMap<Struct>,
25 unions: ItemMap<Union>,
26 opaque_items: ItemMap<OpaqueItem>,
27 typedefs: ItemMap<Typedef>,
28 functions: Vec<Function>,
29 source_files: Vec<PathBuf>,
30 package_version: String,
31}
32
33impl Library {
34 #[allow(clippy::too_many_arguments)]
35 pub fn new(
36 config: Config,
37 constants: ItemMap<Constant>,
38 globals: ItemMap<Static>,
39 enums: ItemMap<Enum>,
40 structs: ItemMap<Struct>,
41 unions: ItemMap<Union>,
42 opaque_items: ItemMap<OpaqueItem>,
43 typedefs: ItemMap<Typedef>,
44 functions: Vec<Function>,
45 source_files: Vec<PathBuf>,
46 package_version: String,
47 ) -> Library {
48 Library {
49 config,
50 constants,
51 globals,
52 enums,
53 structs,
54 unions,
55 opaque_items,
56 typedefs,
57 functions,
58 source_files,
59 package_version,
60 }
61 }
62
63 pub fn generate(mut self) -> Result<Bindings, Error> {
64 self.transfer_annotations();
65 self.simplify_standard_types();
66
67 match self.config.function.sort_by.unwrap_or(self.config.sort_by) {
68 SortKey::Name => self.functions.sort_by(|x, y| x.path.cmp(&y.path)),
69 SortKey::None => { }
70 }
71
72 if self.config.language != Language::Cxx {
73 self.instantiate_monomorphs();
74 }
75 self.remove_excluded();
76 if self.config.language == Language::C {
77 self.resolve_declaration_types();
78 }
79
80 self.rename_items();
81
82 let mut dependencies = Dependencies::new();
83
84 for function in &self.functions {
85 function.add_dependencies(&self, &mut dependencies);
86 }
87 self.globals.for_all_items(|global| {
88 global.add_dependencies(&self, &mut dependencies);
89 });
90 self.constants.for_all_items(|constant| {
91 constant.add_dependencies(&self, &mut dependencies);
92 });
93 for name in &self.config.export.include {
94 let path = Path::new(name.clone());
95 if let Some(items) = self.get_items(&path) {
96 if dependencies.items.insert(path) {
97 for item in &items {
98 item.deref().add_dependencies(&self, &mut dependencies);
99 }
100 for item in items {
101 dependencies.order.push(item);
102 }
103 }
104 }
105 }
106
107 dependencies.sort();
108
109 let items = dependencies.order;
110 let constants = if self.config.export.should_generate(ItemType::Constants) {
111 let mut constants = self.constants.to_vec();
112 match self.config.constant.sort_by.unwrap_or(self.config.sort_by) {
113 SortKey::Name => constants.sort_by(|x, y| x.path.cmp(&y.path)),
114 SortKey::None => { }
115 }
116 constants
117 } else {
118 vec![]
119 };
120
121 let globals = if self.config.export.should_generate(ItemType::Globals) {
122 let mut globals = self.globals.to_vec();
123 match self.config.constant.sort_by.unwrap_or(self.config.sort_by) {
124 SortKey::Name => globals.sort_by(|x, y| x.path.cmp(&y.path)),
125 SortKey::None => { }
126 }
127 globals
128 } else {
129 vec![]
130 };
131 let functions = if self.config.export.should_generate(ItemType::Functions) {
132 self.functions
133 } else {
134 vec![]
135 };
136
137 Ok(Bindings::new(
138 self.config,
139 self.structs,
140 self.typedefs,
141 constants,
142 globals,
143 items,
144 functions,
145 self.source_files,
146 false,
147 self.package_version,
148 ))
149 }
150
151 pub fn get_items(&self, p: &Path) -> Option<Vec<ItemContainer>> {
152 macro_rules! find {
153 ($field:ident, $kind:ident) => {
154 if self.config.export.should_generate(ItemType::$kind) {
155 if let Some(x) = self.$field.get_items(p) {
156 return Some(x);
157 }
158 }
159 };
160 }
161
162 find!(enums, Enums);
163 find!(structs, Structs);
164 find!(unions, Unions);
165 find!(opaque_items, OpaqueItems);
166 find!(typedefs, Typedefs);
167
168 None
169 }
170
171 pub fn get_config(&self) -> &Config {
172 &self.config
173 }
174
175 fn remove_excluded(&mut self) {
176 let config = &self.config;
177 self.functions
179 .retain(|x| !config.export.exclude.iter().any(|y| y == x.path().name()));
180 self.enums
181 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
182 self.structs
183 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
184 self.unions
185 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
186 self.opaque_items
187 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
188 self.typedefs
189 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
190 self.globals
191 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
192 self.constants
193 .filter(|x| config.export.exclude.iter().any(|y| y == x.path().name()));
194 }
195
196 fn transfer_annotations(&mut self) {
197 let mut annotations = HashMap::new();
198
199 self.typedefs.for_all_items_mut(|x| {
200 x.transfer_annotations(&mut annotations);
201 });
202
203 for (alias_path, annotations) in annotations {
204 let mut transferred = false;
206
207 self.enums.for_items_mut(&alias_path, |x| {
208 if x.annotations().is_empty() {
209 *x.annotations_mut() = annotations.clone();
210 transferred = true;
211 } else {
212 warn!(
213 "Can't transfer annotations from typedef to alias ({alias_path}) \
214 that already has annotations."
215 );
216 }
217 });
218 if transferred {
219 continue;
220 }
221 self.structs.for_items_mut(&alias_path, |x| {
222 if x.annotations().is_empty() {
223 *x.annotations_mut() = annotations.clone();
224 transferred = true;
225 } else {
226 warn!(
227 "Can't transfer annotations from typedef to alias ({alias_path}) \
228 that already has annotations."
229 );
230 }
231 });
232 if transferred {
233 continue;
234 }
235 self.unions.for_items_mut(&alias_path, |x| {
236 if x.annotations().is_empty() {
237 *x.annotations_mut() = annotations.clone();
238 transferred = true;
239 } else {
240 warn!(
241 "Can't transfer annotations from typedef to alias ({alias_path}) \
242 that already has annotations."
243 );
244 }
245 });
246 if transferred {
247 continue;
248 }
249 self.opaque_items.for_items_mut(&alias_path, |x| {
250 if x.annotations().is_empty() {
251 *x.annotations_mut() = annotations.clone();
252 transferred = true;
253 } else {
254 warn!(
255 "Can't transfer annotations from typedef to alias ({alias_path}) \
256 that already has annotations."
257 );
258 }
259 });
260 if transferred {
261 continue;
262 }
263 self.typedefs.for_items_mut(&alias_path, |x| {
264 if x.annotations().is_empty() {
265 *x.annotations_mut() = annotations.clone();
266 transferred = true;
267 } else {
268 warn!(
269 "Can't transfer annotations from typedef to alias ({alias_path}) \
270 that already has annotations."
271 );
272 }
273 });
274 if transferred {
275 continue;
276 }
277 }
278 }
279
280 fn rename_items(&mut self) {
281 let config = &self.config;
282
283 self.globals
284 .for_all_items_mut(|x| x.rename_for_config(config));
285 self.globals.rebuild();
286
287 self.constants
288 .for_all_items_mut(|x| x.rename_for_config(config));
289 self.constants.rebuild();
290
291 self.structs
292 .for_all_items_mut(|x| x.rename_for_config(config));
293 self.structs.rebuild();
294
295 self.unions
296 .for_all_items_mut(|x| x.rename_for_config(config));
297 self.unions.rebuild();
298
299 self.enums
300 .for_all_items_mut(|x| x.rename_for_config(config));
301 self.enums.rebuild();
302
303 self.opaque_items
304 .for_all_items_mut(|x| x.rename_for_config(config));
305 self.opaque_items.rebuild();
306
307 self.typedefs
308 .for_all_items_mut(|x| x.rename_for_config(config));
309 self.typedefs.rebuild();
310
311 for item in &mut self.functions {
312 item.rename_for_config(&self.config);
313 }
314 }
315
316 fn resolve_declaration_types(&mut self) {
317 if !self.config.style.generate_tag() {
318 return;
319 }
320
321 let mut resolver = DeclarationTypeResolver::default();
322
323 self.structs.for_all_items(|x| {
324 x.collect_declaration_types(&mut resolver);
325 });
326
327 self.enums.for_all_items(|x| {
328 x.collect_declaration_types(&mut resolver);
329 });
330
331 self.unions.for_all_items(|x| {
332 x.collect_declaration_types(&mut resolver);
333 });
334
335 self.typedefs.for_all_items(|x| {
336 x.collect_declaration_types(&mut resolver);
337 });
338
339 self.opaque_items.for_all_items(|x| {
342 x.collect_declaration_types(&mut resolver);
343 });
344
345 self.enums
346 .for_all_items_mut(|x| x.resolve_declaration_types(&resolver));
347
348 self.structs
349 .for_all_items_mut(|x| x.resolve_declaration_types(&resolver));
350
351 self.unions
352 .for_all_items_mut(|x| x.resolve_declaration_types(&resolver));
353
354 self.typedefs
355 .for_all_items_mut(|x| x.resolve_declaration_types(&resolver));
356
357 self.globals
358 .for_all_items_mut(|x| x.resolve_declaration_types(&resolver));
359
360 for item in &mut self.functions {
361 item.resolve_declaration_types(&resolver);
362 }
363 }
364
365 fn simplify_standard_types(&mut self) {
366 let config = &self.config;
367
368 self.structs.for_all_items_mut(|x| {
369 x.simplify_standard_types(config);
370 });
371 self.enums.for_all_items_mut(|x| {
372 x.simplify_standard_types(config);
373 });
374 self.unions.for_all_items_mut(|x| {
375 x.simplify_standard_types(config);
376 });
377 self.globals.for_all_items_mut(|x| {
378 x.simplify_standard_types(config);
379 });
380 self.typedefs.for_all_items_mut(|x| {
381 x.simplify_standard_types(config);
382 });
383 for x in &mut self.functions {
384 x.simplify_standard_types(config);
385 }
386 }
387
388 fn instantiate_monomorphs(&mut self) {
389 let mut monomorphs = Monomorphs::default();
391
392 self.structs.for_all_items(|x| {
393 x.add_monomorphs(self, &mut monomorphs);
394 });
395 self.unions.for_all_items(|x| {
396 x.add_monomorphs(self, &mut monomorphs);
397 });
398 self.enums.for_all_items(|x| {
399 x.add_monomorphs(self, &mut monomorphs);
400 });
401 self.typedefs.for_all_items(|x| {
402 x.add_monomorphs(self, &mut monomorphs);
403 });
404 for x in &self.functions {
405 x.add_monomorphs(self, &mut monomorphs);
406 }
407
408 for monomorph in monomorphs.drain_structs() {
410 self.structs.try_insert(monomorph);
411 }
412 for monomorph in monomorphs.drain_unions() {
413 self.unions.try_insert(monomorph);
414 }
415 for monomorph in monomorphs.drain_opaques() {
416 self.opaque_items.try_insert(monomorph);
417 }
418 for monomorph in monomorphs.drain_typedefs() {
419 self.typedefs.try_insert(monomorph);
420 }
421 for monomorph in monomorphs.drain_enums() {
422 self.enums.try_insert(monomorph);
423 }
424
425 self.opaque_items.filter(|x| x.is_generic());
427 self.structs.filter(|x| x.is_generic());
428 self.unions.filter(|x| x.is_generic());
429 self.enums.filter(|x| x.is_generic());
430 self.typedefs.filter(|x| x.is_generic());
431
432 self.unions
434 .for_all_items_mut(|x| x.mangle_paths(&monomorphs));
435 self.structs
436 .for_all_items_mut(|x| x.mangle_paths(&monomorphs));
437 self.enums
438 .for_all_items_mut(|x| x.mangle_paths(&monomorphs));
439 self.typedefs
440 .for_all_items_mut(|x| x.mangle_paths(&monomorphs));
441 for x in &mut self.functions {
442 x.mangle_paths(&monomorphs);
443 }
444 }
445}