diff options
Diffstat (limited to 'src/bindgen/monomorph.rs')
-rw-r--r-- | src/bindgen/monomorph.rs | 147 |
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) + } +} |