cbindgen/bindgen/
library.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5use 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 => { /* keep input order */ }
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 => { /* keep input order */ }
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 => { /* keep input order */ }
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        // FIXME: interpret `config.export.exclude` as `Path`s.
178        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            // TODO
205            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        // NOTE: Intentionally last, so that in case there's an opaque type
340        // which is conflicting with a non-opaque one, the later wins.
341        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        // Collect a list of monomorphs
390        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        // Insert the monomorphs into self
409        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        // Remove structs and opaque items that are generic
426        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        // Mangle the paths that remain
433        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}