/* 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, opaques: Vec, structs: Vec, unions: Vec, typedefs: Vec, enums: Vec, } 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, ) { 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, ) { 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, ) { 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, ) { 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, ) { 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 { mem::take(&mut self.opaques) } pub fn drain_structs(&mut self) -> Vec { mem::take(&mut self.structs) } pub fn drain_unions(&mut self) -> Vec { mem::take(&mut self.unions) } pub fn drain_typedefs(&mut self) -> Vec { mem::take(&mut self.typedefs) } pub fn drain_enums(&mut self) -> Vec { mem::take(&mut self.enums) } }