summaryrefslogtreecommitdiffstats
path: root/src/bindgen/monomorph.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindgen/monomorph.rs')
-rw-r--r--src/bindgen/monomorph.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/src/bindgen/monomorph.rs b/src/bindgen/monomorph.rs
new file mode 100644
index 0000000..db6dce6
--- /dev/null
+++ b/src/bindgen/monomorph.rs
@@ -0,0 +1,147 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use std::collections::HashMap;
+use std::mem;
+
+use crate::bindgen::ir::{
+ Enum, GenericArgument, GenericPath, OpaqueItem, Path, Struct, Typedef, Union,
+};
+use crate::bindgen::library::Library;
+
+#[derive(Default, Clone, Debug)]
+pub struct Monomorphs {
+ replacements: HashMap<GenericPath, Path>,
+ opaques: Vec<OpaqueItem>,
+ structs: Vec<Struct>,
+ unions: Vec<Union>,
+ typedefs: Vec<Typedef>,
+ enums: Vec<Enum>,
+}
+
+impl Monomorphs {
+ pub fn contains(&self, path: &GenericPath) -> bool {
+ self.replacements.contains_key(path)
+ }
+
+ pub fn insert_struct(
+ &mut self,
+ library: &Library,
+ generic: &Struct,
+ monomorph: Struct,
+ arguments: Vec<GenericArgument>,
+ ) {
+ let replacement_path = GenericPath::new(generic.path.clone(), arguments);
+
+ debug_assert!(generic.generic_params.len() > 0);
+ debug_assert!(!self.contains(&replacement_path));
+
+ self.replacements
+ .insert(replacement_path, monomorph.path.clone());
+
+ monomorph.add_monomorphs(library, self);
+
+ self.structs.push(monomorph);
+ }
+
+ pub fn insert_enum(
+ &mut self,
+ library: &Library,
+ generic: &Enum,
+ monomorph: Enum,
+ arguments: Vec<GenericArgument>,
+ ) {
+ let replacement_path = GenericPath::new(generic.path.clone(), arguments);
+
+ debug_assert!(generic.generic_params.len() > 0);
+ debug_assert!(!self.contains(&replacement_path));
+
+ self.replacements
+ .insert(replacement_path, monomorph.path.clone());
+
+ monomorph.add_monomorphs(library, self);
+
+ self.enums.push(monomorph);
+ }
+
+ pub fn insert_union(
+ &mut self,
+ library: &Library,
+ generic: &Union,
+ monomorph: Union,
+ arguments: Vec<GenericArgument>,
+ ) {
+ let replacement_path = GenericPath::new(generic.path.clone(), arguments);
+
+ debug_assert!(generic.generic_params.len() > 0);
+ debug_assert!(!self.contains(&replacement_path));
+
+ self.replacements
+ .insert(replacement_path, monomorph.path.clone());
+
+ monomorph.add_monomorphs(library, self);
+
+ self.unions.push(monomorph);
+ }
+
+ pub fn insert_opaque(
+ &mut self,
+ generic: &OpaqueItem,
+ monomorph: OpaqueItem,
+ arguments: Vec<GenericArgument>,
+ ) {
+ let replacement_path = GenericPath::new(generic.path.clone(), arguments);
+
+ debug_assert!(generic.generic_params.len() > 0);
+ debug_assert!(!self.contains(&replacement_path));
+
+ self.replacements
+ .insert(replacement_path, monomorph.path.clone());
+ self.opaques.push(monomorph);
+ }
+
+ pub fn insert_typedef(
+ &mut self,
+ library: &Library,
+ generic: &Typedef,
+ monomorph: Typedef,
+ arguments: Vec<GenericArgument>,
+ ) {
+ let replacement_path = GenericPath::new(generic.path.clone(), arguments);
+
+ debug_assert!(generic.generic_params.len() > 0);
+ debug_assert!(!self.contains(&replacement_path));
+
+ self.replacements
+ .insert(replacement_path, monomorph.path.clone());
+
+ monomorph.add_monomorphs(library, self);
+
+ self.typedefs.push(monomorph);
+ }
+
+ pub fn mangle_path(&self, path: &GenericPath) -> Option<&Path> {
+ self.replacements.get(path)
+ }
+
+ pub fn drain_opaques(&mut self) -> Vec<OpaqueItem> {
+ mem::take(&mut self.opaques)
+ }
+
+ pub fn drain_structs(&mut self) -> Vec<Struct> {
+ mem::take(&mut self.structs)
+ }
+
+ pub fn drain_unions(&mut self) -> Vec<Union> {
+ mem::take(&mut self.unions)
+ }
+
+ pub fn drain_typedefs(&mut self) -> Vec<Typedef> {
+ mem::take(&mut self.typedefs)
+ }
+
+ pub fn drain_enums(&mut self) -> Vec<Enum> {
+ mem::take(&mut self.enums)
+ }
+}