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::mem;
7
8use crate::bindgen::ir::{
9 Enum, GenericArgument, GenericPath, OpaqueItem, Path, Struct, Typedef, Union,
10};
11use crate::bindgen::library::Library;
12
13#[derive(Default, Clone, Debug)]
14pub struct Monomorphs {
15 replacements: HashMap<GenericPath, Path>,
16 opaques: Vec<OpaqueItem>,
17 structs: Vec<Struct>,
18 unions: Vec<Union>,
19 typedefs: Vec<Typedef>,
20 enums: Vec<Enum>,
21}
22
23impl Monomorphs {
24 pub fn contains(&self, path: &GenericPath) -> bool {
25 self.replacements.contains_key(path)
26 }
27
28 pub fn insert_struct(
29 &mut self,
30 library: &Library,
31 generic: &Struct,
32 monomorph: Struct,
33 arguments: Vec<GenericArgument>,
34 ) {
35 let replacement_path = GenericPath::new(generic.path.clone(), arguments);
36
37 debug_assert!(generic.generic_params.len() > 0);
38 debug_assert!(!self.contains(&replacement_path));
39
40 self.replacements
41 .insert(replacement_path, monomorph.path.clone());
42
43 monomorph.add_monomorphs(library, self);
44
45 self.structs.push(monomorph);
46 }
47
48 pub fn insert_enum(
49 &mut self,
50 library: &Library,
51 generic: &Enum,
52 monomorph: Enum,
53 arguments: Vec<GenericArgument>,
54 ) {
55 let replacement_path = GenericPath::new(generic.path.clone(), arguments);
56
57 debug_assert!(generic.generic_params.len() > 0);
58 debug_assert!(!self.contains(&replacement_path));
59
60 self.replacements
61 .insert(replacement_path, monomorph.path.clone());
62
63 monomorph.add_monomorphs(library, self);
64
65 self.enums.push(monomorph);
66 }
67
68 pub fn insert_union(
69 &mut self,
70 library: &Library,
71 generic: &Union,
72 monomorph: Union,
73 arguments: Vec<GenericArgument>,
74 ) {
75 let replacement_path = GenericPath::new(generic.path.clone(), arguments);
76
77 debug_assert!(generic.generic_params.len() > 0);
78 debug_assert!(!self.contains(&replacement_path));
79
80 self.replacements
81 .insert(replacement_path, monomorph.path.clone());
82
83 monomorph.add_monomorphs(library, self);
84
85 self.unions.push(monomorph);
86 }
87
88 pub fn insert_opaque(
89 &mut self,
90 generic: &OpaqueItem,
91 monomorph: OpaqueItem,
92 arguments: Vec<GenericArgument>,
93 ) {
94 let replacement_path = GenericPath::new(generic.path.clone(), arguments);
95
96 debug_assert!(generic.generic_params.len() > 0);
97 debug_assert!(!self.contains(&replacement_path));
98
99 self.replacements
100 .insert(replacement_path, monomorph.path.clone());
101 self.opaques.push(monomorph);
102 }
103
104 pub fn insert_typedef(
105 &mut self,
106 library: &Library,
107 generic: &Typedef,
108 monomorph: Typedef,
109 arguments: Vec<GenericArgument>,
110 ) {
111 let replacement_path = GenericPath::new(generic.path.clone(), arguments);
112
113 debug_assert!(generic.generic_params.len() > 0);
114 debug_assert!(!self.contains(&replacement_path));
115
116 self.replacements
117 .insert(replacement_path, monomorph.path.clone());
118
119 monomorph.add_monomorphs(library, self);
120
121 self.typedefs.push(monomorph);
122 }
123
124 pub fn mangle_path(&self, path: &GenericPath) -> Option<&Path> {
125 self.replacements.get(path)
126 }
127
128 pub fn drain_opaques(&mut self) -> Vec<OpaqueItem> {
129 mem::take(&mut self.opaques)
130 }
131
132 pub fn drain_structs(&mut self) -> Vec<Struct> {
133 mem::take(&mut self.structs)
134 }
135
136 pub fn drain_unions(&mut self) -> Vec<Union> {
137 mem::take(&mut self.unions)
138 }
139
140 pub fn drain_typedefs(&mut self) -> Vec<Typedef> {
141 mem::take(&mut self.typedefs)
142 }
143
144 pub fn drain_enums(&mut self) -> Vec<Enum> {
145 mem::take(&mut self.enums)
146 }
147}
148