1use super::*;
2
3#[doc(hidden)]
4pub enum CallingConvention {
5 Stdcall(usize),
6 Cdecl,
7}
8
9// Returns the libraries and their function and stack sizes used by the gnu and msvc tools to build the umbrella libs.
10#[doc(hidden)]
11pub fn libraries() -> BTreeMap<String, BTreeMap<String, CallingConvention>> {
12 let mut libraries: BTreeMap> = BTreeMap::new();
13
14 let reader: &'static Reader = Reader::new(files:expand_input(&["default"]));
15 combine_libraries(reader, &mut libraries);
16 libraries
17}
18
19fn combine_libraries(
20 reader: &Reader,
21 libraries: &mut BTreeMap<String, BTreeMap<String, CallingConvention>>,
22) {
23 for types in reader.values() {
24 for ty in types.values() {
25 let Some(ty) = cpp_fn(ty) else {
26 continue;
27 };
28
29 // Windows libs are always produced with lower case module names.
30 let library = ty.method.module_name().to_lowercase();
31 let impl_map = ty.method.impl_map().unwrap();
32 let flags = impl_map.flags();
33 let name = impl_map.import_name().to_string();
34
35 if flags.contains(PInvokeAttributes::CallConvPlatformapi) {
36 let arches = ty.method.arches();
37 let params = if (arches == 0) || (arches & 1 == 1) {
38 ty.method.signature(ty.namespace, &[]).size()
39 } else {
40 0
41 };
42
43 libraries
44 .entry(library)
45 .or_default()
46 .insert(name, CallingConvention::Stdcall(params));
47 } else if flags.contains(PInvokeAttributes::CallConvCdecl) {
48 libraries
49 .entry(library)
50 .or_default()
51 .insert(name, CallingConvention::Cdecl);
52 } else {
53 panic!();
54 }
55 }
56 }
57}
58
59fn cpp_fn(types: &[Type]) -> Option<CppFn> {
60 let mut functions: Vec = vec![];
61
62 for ty: &Type in types {
63 if let Type::CppFn(ty: &CppFn) = ty {
64 functions.push(ty.clone());
65 }
66 }
67
68 for ty: &CppFn in &functions {
69 let arches: i32 = ty.method.arches();
70 if (arches == 0) || (arches & 1 == 1) {
71 return Some(ty.clone());
72 }
73 }
74
75 functions.first().cloned()
76}
77