Remove Specialization in favour of generic typedef

This commit is contained in:
Ingvar Stepanyan
2017-11-16 04:08:43 +00:00
committed by Ryan Hunt
parent 4ee1a8bcc8
commit fada89c7f4
26 changed files with 154 additions and 472 deletions
-3
View File
@@ -109,9 +109,6 @@ impl Bindings {
&ItemContainer::Union(ref x) => x.write(&self.config, &mut out),
&ItemContainer::OpaqueItem(ref x) => x.write(&self.config, &mut out),
&ItemContainer::Typedef(ref x) => x.write(&self.config, &mut out),
&ItemContainer::Specialization(_) => {
unreachable!("should not encounter a specialization in a generated library")
}
}
out.new_line();
}
-1
View File
@@ -217,7 +217,6 @@ impl Builder {
result.unions,
result.opaque_items,
result.typedefs,
result.specializations,
result.functions).generate()
}
}
+1 -6
View File
@@ -8,8 +8,7 @@ use std::mem;
use syn;
use bindgen::config::{Config, Language};
use bindgen::ir::{AnnotationSet, Cfg, Documentation, Item, ItemContainer, Specialization, Type};
use bindgen::library::Library;
use bindgen::ir::{AnnotationSet, Cfg, Documentation, Item, ItemContainer, Type};
use bindgen::writer::{Source, SourceWriter};
#[derive(Debug, Clone)]
@@ -120,10 +119,6 @@ impl Item for Constant {
fn container(&self) -> ItemContainer {
ItemContainer::Constant(self.clone())
}
fn specialize(&self, _library: &Library, _aliasee: &Specialization) -> Result<Box<Item>, String> {
unreachable!();
}
}
impl Source for Constant {
+1 -13
View File
@@ -7,8 +7,7 @@ use std::io::Write;
use syn;
use bindgen::config::{Config, Language};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, ItemContainer, Item, Repr, Specialization};
use bindgen::library::Library;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, ItemContainer, Item, Repr};
use bindgen::rename::{IdentifierType, RenameRule};
use bindgen::utilities::{find_first_some};
use bindgen::writer::{Source, SourceWriter};
@@ -111,17 +110,6 @@ impl Item for Enum {
ItemContainer::Enum(self.clone())
}
fn specialize(&self, _: &Library, aliasee: &Specialization) -> Result<Box<Item>, String> {
Ok(Box::new(Enum {
name: aliasee.name.clone(),
repr: self.repr.clone(),
values: self.values.clone(),
cfg: aliasee.cfg.clone(),
annotations: aliasee.annotations.clone(),
documentation: aliasee.documentation.clone(),
}))
}
fn rename_for_config(&mut self, config: &Config) {
if config.language == Language::C
&& (config.enumeration.prefix_with_name
+1 -5
View File
@@ -8,7 +8,7 @@ use syn;
use bindgen::config::Config;
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, Documentation, Item, ItemContainer, Specialization, Type};
use bindgen::ir::{AnnotationSet, Cfg, Documentation, Item, ItemContainer, Type};
use bindgen::library::Library;
use bindgen::writer::{Source, SourceWriter};
@@ -75,10 +75,6 @@ impl Item for Static {
ItemContainer::Static(self.clone())
}
fn specialize(&self, _library: &Library, _aliasee: &Specialization) -> Result<Box<Item>, String> {
unreachable!();
}
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
self.ty.add_dependencies(library, out);
}
+1 -13
View File
@@ -7,7 +7,7 @@ use std::mem;
use bindgen::config::Config;
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Specialization, Static, Struct, Type, Typedef, Union};
use bindgen::ir::{AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Static, Struct, Type, Typedef, Union};
use bindgen::library::Library;
use bindgen::monomorph::Monomorphs;
@@ -20,8 +20,6 @@ pub trait Item {
fn container(&self) -> ItemContainer;
fn specialize(&self, library: &Library, aliasee: &Specialization) -> Result<Box<Item>, String>;
fn rename_for_config(&mut self, _config: &Config) { }
fn add_dependencies(&self, _library: &Library, _out: &mut Dependencies) { }
fn instantiate_monomorph(&self, _generics: &Vec<Type>, _library: &Library, _out: &mut Monomorphs) { }
@@ -36,7 +34,6 @@ pub enum ItemContainer {
Union(Union),
Enum(Enum),
Typedef(Typedef),
Specialization(Specialization),
}
impl ItemContainer {
@@ -49,7 +46,6 @@ impl ItemContainer {
&ItemContainer::Union(ref x) => x,
&ItemContainer::Enum(ref x) => x,
&ItemContainer::Typedef(ref x) => x,
&ItemContainer::Specialization(ref x) => x,
}
}
}
@@ -72,14 +68,6 @@ impl<T: Item + Clone> ItemMap<T> {
}
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn try_insert(&mut self, item: T) -> bool {
match (item.cfg().is_some(), self.data.get_mut(item.name())) {
(true, Some(&mut ItemValue::Cfg(ref mut items))) => {
-2
View File
@@ -13,7 +13,6 @@ pub mod item;
pub mod opaque;
pub mod path;
pub mod repr;
pub mod specialization;
pub mod structure;
pub mod ty;
pub mod typedef;
@@ -31,7 +30,6 @@ pub use self::item::*;
pub use self::opaque::*;
pub use self::path::*;
pub use self::repr::*;
pub use self::specialization::*;
pub use self::structure::*;
pub use self::ty::*;
pub use self::typedef::*;
+1 -16
View File
@@ -8,7 +8,7 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Path, Specialization, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Path, Type};
use bindgen::library::Library;
use bindgen::mangle;
use bindgen::monomorph::Monomorphs;
@@ -73,21 +73,6 @@ impl Item for OpaqueItem {
ItemContainer::OpaqueItem(self.clone())
}
fn specialize(&self, _: &Library, aliasee: &Specialization) -> Result<Box<Item>, String> {
if aliasee.aliased.generics.len() !=
self.generic_params.len() {
return Err("Incomplete specialization, the amount of generics in the path doesn't match the amount of generics in the item.".to_owned());
}
Ok(Box::new(OpaqueItem {
name: aliasee.name.clone(),
generic_params: aliasee.generic_params.clone(),
cfg: aliasee.cfg.clone(),
annotations: aliasee.annotations.clone(),
documentation: aliasee.documentation.clone(),
}))
}
fn add_dependencies(&self, _: &Library, _: &mut Dependencies) {
}
}
-143
View File
@@ -1,143 +0,0 @@
/* 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 syn;
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, Documentation};
use bindgen::ir::{GenericParams, GenericPath, ItemContainer, Item, PrimitiveType};
use bindgen::library::Library;
/// A type alias that generates a copy of its aliasee with a new name. If the type
/// alias has generic values, it specializes its aliasee. This is useful for
/// presenting an interface that includes generic types without mangling.
#[derive(Debug, Clone)]
pub struct Specialization {
pub name: String,
pub generic_params: GenericParams,
pub aliased: GenericPath,
pub cfg: Option<Cfg>,
pub annotations: AnnotationSet,
pub documentation: Documentation,
}
impl Specialization {
pub fn load(name: String,
generics: &syn::Generics,
ty: &syn::Ty,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Specialization, String>
{
match ty {
&syn::Ty::Path(ref _q, ref p) => {
let path = GenericPath::load(p)?;
if PrimitiveType::maybe(&path.name).is_some() {
return Err("Definition is a primitive, which cannot be specialized.".to_owned());
}
Ok(Specialization {
name: name,
generic_params: GenericParams::new(generics),
aliased: path,
cfg: Cfg::append(mod_cfg, Cfg::load(attrs)),
annotations: AnnotationSet::load(attrs)?,
documentation: Documentation::load(attrs),
})
}
_ => {
Err("Definition is not a path.".to_owned())
}
}
}
pub fn resolve_specialization(&self, library: &Library) -> Result<Box<Item>, String> {
if let Some(items) = library.get_items(&self.aliased.name) {
assert!(items.len() > 0);
if items.len() > 1 {
warn!("Specializing an aliased type with multiple definitions is possible but unsupported currently.");
}
match items[0] {
ItemContainer::Constant(..) => {
unreachable!()
}
ItemContainer::Static(..) => {
unreachable!()
}
ItemContainer::OpaqueItem(ref aliased) => {
aliased.specialize(library, self)
}
ItemContainer::Struct(ref aliased) => {
aliased.specialize(library, self)
}
ItemContainer::Union(ref aliased) => {
aliased.specialize(library, self)
}
ItemContainer::Enum(ref aliased) => {
aliased.specialize(library, self)
}
ItemContainer::Typedef(ref aliased) => {
aliased.specialize(library, self)
}
ItemContainer::Specialization(ref aliased) => {
aliased.specialize(library, self)
}
}
} else {
Err(format!("Couldn't find aliased type {:?} for specializing.", self.aliased))
}
}
}
impl Item for Specialization {
fn name(&self) -> &str {
&self.name
}
fn cfg(&self) -> &Option<Cfg> {
&self.cfg
}
fn annotations(&self) -> &AnnotationSet {
&self.annotations
}
fn annotations_mut(&mut self) -> &mut AnnotationSet {
&mut self.annotations
}
fn container(&self) -> ItemContainer {
ItemContainer::Specialization(self.clone())
}
fn specialize(&self, library: &Library, aliasee: &Specialization) -> Result<Box<Item>, String> {
if aliasee.aliased.generics.len() !=
self.generic_params.len() {
return Err("Incomplete specialization, the amount of generics in the path doesn't match the amount of generics in the item.".to_owned());
}
let mappings = self.generic_params.iter()
.zip(aliasee.aliased.generics.iter())
.collect::<Vec<_>>();
let generics = self.aliased.generics.iter()
.map(|x| x.specialize(&mappings))
.collect();
Specialization {
name: aliasee.name.clone(),
generic_params: aliasee.generic_params.clone(),
aliased: GenericPath::new(self.aliased.name.clone(), generics),
cfg: aliasee.cfg.clone(),
annotations: aliasee.annotations.clone(),
documentation: aliasee.documentation.clone(),
}.resolve_specialization(library)
}
fn add_dependencies(&self, _: &Library, _: &mut Dependencies) {
unreachable!("Specializations must be specialized before dependency gathering.");
}
}
+1 -24
View File
@@ -8,7 +8,7 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Repr, Specialization, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Repr, Type};
use bindgen::library::Library;
use bindgen::mangle;
use bindgen::monomorph::Monomorphs;
@@ -184,29 +184,6 @@ impl Item for Struct {
out.insert_struct(self, monomorph, generic_values.clone());
}
fn specialize(&self, _: &Library, aliasee: &Specialization) -> Result<Box<Item>, String> {
if aliasee.aliased.generics.len() !=
self.generic_params.len() {
return Err("Incomplete specialization, the amount of generics in the path doesn't match the amount of generics in the item.".to_owned());
}
let mappings = self.generic_params.iter()
.zip(aliasee.aliased.generics.iter())
.collect::<Vec<_>>();
Ok(Box::new(Struct {
name: aliasee.name.clone(),
generic_params: aliasee.generic_params.clone(),
fields: self.fields.iter()
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
tuple_struct: self.tuple_struct,
cfg: aliasee.cfg.clone(),
annotations: aliasee.annotations.clone(),
documentation: aliasee.documentation.clone(),
}))
}
}
impl Source for Struct {
+2 -5
View File
@@ -438,11 +438,8 @@ impl Type {
ItemContainer::Enum(..) => {
warn!("Cannot instantiate a generic enum.")
},
ItemContainer::Typedef(..) => {
warn!("Cannot instantiate a generic typedef.")
},
ItemContainer::Specialization(..) => {
warn!("Cannot instantiate a generic specialization.")
ItemContainer::Typedef(ref x) => {
x.instantiate_monomorph(&path.generics, library, out);
},
}
}
+48 -14
View File
@@ -7,10 +7,11 @@ use std::io::Write;
use syn;
use bindgen::config::Config;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, ItemContainer, Item, Path, Specialization, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Path, Type};
use bindgen::library::Library;
use bindgen::mangle;
use bindgen::monomorph::Monomorphs;
use bindgen::writer::{Source, SourceWriter};
@@ -18,6 +19,7 @@ use bindgen::writer::{Source, SourceWriter};
#[derive(Debug, Clone)]
pub struct Typedef {
pub name: String,
pub generic_params: GenericParams,
pub aliased: Type,
pub cfg: Option<Cfg>,
pub annotations: AnnotationSet,
@@ -27,11 +29,13 @@ pub struct Typedef {
impl Typedef {
pub fn load(name: String,
ty: &syn::Ty,
generics: &syn::Generics,
attrs: &Vec<syn::Attribute>,
mod_cfg: &Option<Cfg>) -> Result<Typedef, String> {
if let Some(x) = Type::load(ty)? {
Ok(Typedef {
name: name,
generic_params: GenericParams::new(generics),
aliased: x,
cfg: Cfg::append(mod_cfg, Cfg::load(attrs)),
annotations: AnnotationSet::load(attrs)?,
@@ -66,7 +70,17 @@ impl Typedef {
}
}
pub fn is_generic(&self) -> bool {
self.generic_params.len() > 0
}
pub fn add_monomorphs(&self, library: &Library, out: &mut Monomorphs) {
// Generic structs can instantiate monomorphs only once they've been
// instantiated. See `instantiate_monomorph` for more details.
if self.is_generic() {
return;
}
self.aliased.add_monomorphs(library, out);
}
@@ -96,18 +110,31 @@ impl Item for Typedef {
ItemContainer::Typedef(self.clone())
}
fn specialize(&self, _: &Library, aliasee: &Specialization) -> Result<Box<Item>, String> {
Ok(Box::new(Typedef {
name: aliasee.name.clone(),
aliased: self.aliased.clone(),
cfg: aliasee.cfg.clone(),
annotations: aliasee.annotations.clone(),
documentation: aliasee.documentation.clone(),
}))
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
self.aliased.add_dependencies_ignoring_generics(&self.generic_params, library, out);
}
fn add_dependencies(&self, library: &Library, out: &mut Dependencies) {
self.aliased.add_dependencies(library, out);
fn instantiate_monomorph(&self, generic_values: &Vec<Type>, library: &Library, out: &mut Monomorphs) {
assert!(self.generic_params.len() > 0 &&
self.generic_params.len() == generic_values.len());
let mappings = self.generic_params.iter()
.zip(generic_values.iter())
.collect::<Vec<_>>();
let monomorph = Typedef {
name: mangle::mangle_path(&self.name, generic_values),
generic_params: GenericParams::default(),
aliased: self.aliased.specialize(&mappings),
cfg: self.cfg.clone(),
annotations: self.annotations.clone(),
documentation: self.documentation.clone(),
};
// Instantiate any monomorphs for any generic paths we may have just created.
monomorph.add_monomorphs(library, out);
out.insert_typedef(self, monomorph, generic_values.clone());
}
}
@@ -117,8 +144,15 @@ impl Source for Typedef {
self.documentation.write(config, out);
out.write("typedef ");
(self.name.clone(), self.aliased.clone()).write(config, out);
self.generic_params.write(config, out);
if config.language == Language::C {
out.write("typedef ");
(self.name.clone(), self.aliased.clone()).write(config, out);
} else {
write!(out, "using {} = ", self.name);
self.aliased.write(config, out);
}
out.write(";");
self.cfg.write_after(config, out);
+1 -24
View File
@@ -8,7 +8,7 @@ use syn;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Repr, Specialization, Type};
use bindgen::ir::{AnnotationSet, Cfg, CfgWrite, Documentation, GenericParams, ItemContainer, Item, Repr, Type};
use bindgen::ir::SynFieldHelpers;
use bindgen::library::Library;
use bindgen::mangle;
@@ -185,29 +185,6 @@ impl Item for Union {
out.insert_union(self, monomorph, generic_values.clone());
}
fn specialize(&self, _: &Library, aliasee: &Specialization) -> Result<Box<Item>, String> {
if aliasee.aliased.generics.len() !=
self.generic_params.len() {
return Err("Incomplete specialization, the amount of generics in the path doesn't match the amount of generics in the item.".to_owned());
}
let mappings = self.generic_params.iter()
.zip(aliasee.aliased.generics.iter())
.collect::<Vec<_>>();
Ok(Box::new(Union {
name: aliasee.name.clone(),
generic_params: aliasee.generic_params.clone(),
fields: self.fields.iter()
.map(|x| (x.0.clone(), x.1.specialize(&mappings), x.2.clone()))
.collect(),
tuple_union: self.tuple_union,
cfg: aliasee.cfg.clone(),
annotations: aliasee.annotations.clone(),
documentation: aliasee.documentation.clone(),
}))
}
}
impl Source for Union {
+6 -73
View File
@@ -9,7 +9,7 @@ use bindgen::bindings::Bindings;
use bindgen::config::{Config, Language};
use bindgen::dependencies::Dependencies;
use bindgen::ir::{Constant, Enum, Function, ItemContainer, ItemMap, Item};
use bindgen::ir::{OpaqueItem, Path, Specialization, Static, Struct, Typedef, Union};
use bindgen::ir::{OpaqueItem, Path, Static, Struct, Typedef, Union};
use bindgen::monomorph::Monomorphs;
#[derive(Debug, Clone)]
@@ -22,7 +22,6 @@ pub struct Library {
unions: ItemMap<Union>,
opaque_items: ItemMap<OpaqueItem>,
typedefs: ItemMap<Typedef>,
specializations: ItemMap<Specialization>,
functions: Vec<Function>,
}
@@ -35,7 +34,6 @@ impl Library {
unions: ItemMap<Union>,
opaque_items: ItemMap<OpaqueItem>,
typedefs: ItemMap<Typedef>,
specializations: ItemMap<Specialization>,
functions: Vec<Function>) -> Library {
Library {
config: config,
@@ -46,7 +44,6 @@ impl Library {
unions: unions,
opaque_items: opaque_items,
typedefs: typedefs,
specializations: specializations,
functions: functions,
}
}
@@ -56,7 +53,6 @@ impl Library {
self.transfer_annotations();
self.rename_items();
self.specialize_items();
self.simplify_option_to_ptr();
if self.config.language == Language::C {
@@ -102,42 +98,10 @@ impl Library {
if let Some(x) = self.typedefs.get_items(p) {
return Some(x);
}
if let Some(x) = self.specializations.get_items(p) {
return Some(x);
}
None
}
fn insert_item(&mut self, item: ItemContainer) {
match item {
ItemContainer::Constant(x) => {
self.constants.try_insert(x);
},
ItemContainer::Static(x) => {
self.globals.try_insert(x);
},
ItemContainer::OpaqueItem(x) => {
self.opaque_items.try_insert(x);
},
ItemContainer::Struct(x) => {
self.structs.try_insert(x);
},
ItemContainer::Union(x) => {
self.unions.try_insert(x);
},
ItemContainer::Enum(x) => {
self.enums.try_insert(x);
},
ItemContainer::Typedef(x) => {
self.typedefs.try_insert(x);
},
ItemContainer::Specialization(x) => {
self.specializations.try_insert(x);
},
};
}
fn transfer_annotations(&mut self) {
let mut annotations = HashMap::new();
@@ -197,18 +161,6 @@ impl Library {
if transferred {
continue;
}
self.specializations.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
transferred = true;
} else {
warn!("Can't transfer annotations from typedef to alias ({}) that already has annotations.",
alias_path);
}
});
if transferred {
continue;
}
self.typedefs.for_items_mut(&alias_path, |x| {
if x.annotations().is_empty() {
*x.annotations_mut() = annotations.clone();
@@ -235,27 +187,6 @@ impl Library {
}
}
fn specialize_items(&mut self) {
let mut specializations = Vec::new();
self.specializations.for_all_items(|x| {
match x.resolve_specialization(&self) {
Ok(specialization) => {
specializations.push(specialization);
}
Err(msg) => {
warn!("Specializing {} failed - ({}).", x.name.clone(), msg);
}
}
});
for specialization in specializations {
self.insert_item(specialization.container());
}
self.specializations.clear();
}
fn simplify_option_to_ptr(&mut self) {
self.structs.for_all_items_mut(|x| {
x.simplify_option_to_ptr();
@@ -275,10 +206,8 @@ impl Library {
}
fn instantiate_monomorphs(&mut self) {
assert!(self.specializations.len() == 0);
// Collect a list of monomorphs
let mut monomorphs = Monomorphs::new();
let mut monomorphs = Monomorphs::default();
self.structs.for_all_items(|x| {
x.add_monomorphs(self, &mut monomorphs);
@@ -303,11 +232,15 @@ impl Library {
for monomorph in monomorphs.drain_opaques() {
self.opaque_items.try_insert(monomorph);
}
for monomorph in monomorphs.drain_typedefs() {
self.typedefs.try_insert(monomorph);
}
// Remove structs and opaque items that are generic
self.opaque_items.filter(|x| x.generic_params.len() > 0);
self.structs.filter(|x| x.generic_params.len() > 0);
self.unions.filter(|x| x.generic_params.len() > 0);
self.typedefs.filter(|x| x.generic_params.len() > 0);
// Mangle the paths that remain
self.unions.for_all_items_mut(|x| x.mangle_paths(&monomorphs));
+20 -11
View File
@@ -5,26 +5,18 @@
use std::collections::HashMap;
use std::mem;
use bindgen::ir::{GenericPath, OpaqueItem, Path, Struct, Type, Union};
use bindgen::ir::{GenericPath, OpaqueItem, Path, Struct, Type, Typedef, Union};
#[derive(Clone, Debug)]
#[derive(Default, Clone, Debug)]
pub struct Monomorphs {
replacements: HashMap<GenericPath, Path>,
opaques: Vec<OpaqueItem>,
structs: Vec<Struct>,
unions: Vec<Union>,
typedefs: Vec<Typedef>,
}
impl Monomorphs {
pub fn new() -> Monomorphs {
Monomorphs {
replacements: HashMap::new(),
opaques: Vec::new(),
structs: Vec::new(),
unions: Vec::new(),
}
}
pub fn contains(&self, path: &GenericPath) -> bool {
self.replacements.contains_key(path)
}
@@ -68,6 +60,19 @@ impl Monomorphs {
self.opaques.push(monomorph);
}
pub fn insert_typedef(&mut self,
generic: &Typedef,
monomorph: Typedef,
parameters: Vec<Type>) {
let replacement_path = GenericPath::new(generic.name.clone(), parameters);
debug_assert!(generic.generic_params.len() > 0);
debug_assert!(!self.contains(&replacement_path));
self.replacements.insert(replacement_path, monomorph.name.clone());
self.typedefs.push(monomorph);
}
pub fn mangle_path(&self, path: &GenericPath) -> Option<&Path> {
self.replacements.get(path)
}
@@ -83,4 +88,8 @@ impl Monomorphs {
pub fn drain_unions(&mut self) -> Vec<Union> {
mem::replace(&mut self.unions, Vec::new())
}
pub fn drain_typedefs(&mut self) -> Vec<Typedef> {
mem::replace(&mut self.typedefs, Vec::new())
}
}
+20 -39
View File
@@ -11,7 +11,7 @@ use syn;
use bindgen::cargo::{Cargo, PackageRef};
use bindgen::ir::{AnnotationSet, Cfg, Constant, Documentation, Enum, Function, GenericParams};
use bindgen::ir::{ItemMap, OpaqueItem, Specialization, Static, Struct, Typedef, Union};
use bindgen::ir::{ItemMap, OpaqueItem, Static, Struct, Typedef, Union};
use bindgen::utilities::{SynAbiHelpers, SynItemHelpers};
const STD_CRATES: &'static [&'static str] = &["std",
@@ -348,7 +348,6 @@ pub struct Parse {
pub unions: ItemMap<Union>,
pub opaque_items: ItemMap<OpaqueItem>,
pub typedefs: ItemMap<Typedef>,
pub specializations: ItemMap<Specialization>,
pub functions: Vec<Function>,
}
@@ -362,7 +361,6 @@ impl Parse {
unions: ItemMap::new(),
opaque_items: ItemMap::new(),
typedefs: ItemMap::new(),
specializations: ItemMap::new(),
functions: Vec::new(),
}
}
@@ -405,7 +403,6 @@ impl Parse {
self.unions.extend_with(&other.unions);
self.opaque_items.extend_with(&other.opaque_items);
self.typedefs.extend_with(&other.typedefs);
self.specializations.extend_with(&other.specializations);
self.functions.extend_from_slice(&other.functions);
}
@@ -742,42 +739,26 @@ impl Parse {
generics: &syn::Generics) {
let alias_name = item.ident.to_string();
let fail1 = if generics.lifetimes.is_empty() &&
generics.ty_params.is_empty()
{
match Typedef::load(alias_name.clone(),
ty,
&item.attrs,
mod_cfg)
{
Ok(typedef) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.typedefs.try_insert(typedef);
return;
}
Err(msg) => msg,
}
} else {
format!("Cannot have generics in typedef.")
};
let fail2 = match Specialization::load(alias_name.clone(),
generics,
ty,
&item.attrs,
mod_cfg) {
Ok(spec) => {
match Typedef::load(alias_name.clone(),
ty,
generics,
&item.attrs,
mod_cfg) {
Ok(st) => {
info!("Take {}::{}.", crate_name, &item.ident);
self.specializations.try_insert(spec);
return;
}
Err(msg) => msg,
};
info!("Skip {}::{} - ({} and {}).",
crate_name,
&item.ident,
fail1,
fail2);
self.typedefs.try_insert(st);
}
Err(msg) => {
info!("Take {}::{} - opaque ({}).",
crate_name,
&item.ident,
msg);
self.opaque_items.try_insert(OpaqueItem::new(alias_name,
generics,
&item.attrs,
mod_cfg));
}
}
}
}
+4 -4
View File
@@ -18,13 +18,13 @@ struct Foo {
Dep c;
};
typedef Foo<int32_t> IntFoo;
using IntFoo = Foo<int32_t>;
typedef Foo<double> DoubleFoo;
using DoubleFoo = Foo<double>;
typedef int32_t Unit;
using Unit = int32_t;
typedef Status SpecialStatus;
using SpecialStatus = Status;
extern "C" {
+14 -14
View File
@@ -1,33 +1,33 @@
#include <cstdint>
#include <cstdlib>
typedef void (*A)();
using A = void(*)();
typedef void (*B)();
using B = void(*)();
typedef bool (*C)(int32_t, int32_t);
using C = bool(*)(int32_t, int32_t);
typedef bool (*(*D)(int32_t))(float);
using D = bool(*(*)(int32_t))(float);
typedef int32_t (*(*E)())[16];
using E = int32_t(*(*)())[16];
typedef const int32_t *F;
using F = const int32_t*;
typedef const int32_t *const *G;
using G = const int32_t*const *;
typedef int32_t *const *H;
using H = int32_t*const *;
typedef int32_t (*I)[16];
using I = int32_t(*)[16];
typedef double (**J)(float);
using J = double(**)(float);
typedef int32_t K[16];
using K = int32_t[16];
typedef const int32_t *L[16];
using L = const int32_t*[16];
typedef bool (*M[16])(int32_t, int32_t);
using M = bool(*[16])(int32_t, int32_t);
typedef void (*N[16])(int32_t, int32_t);
using N = void(*[16])(int32_t, int32_t);
extern "C" {
+5 -21
View File
@@ -10,9 +10,7 @@ typedef struct {
float _0;
} TypedLength_f32__LayoutUnit;
typedef struct {
float _0;
} Length_f32;
typedef TypedLength_f32__UnknownUnit Length_f32;
typedef TypedLength_f32__LayoutUnit LayoutLength;
@@ -30,12 +28,7 @@ typedef struct {
float left;
} TypedSideOffsets2D_f32__LayoutUnit;
typedef struct {
float top;
float right;
float bottom;
float left;
} SideOffsets2D_f32;
typedef TypedSideOffsets2D_f32__UnknownUnit SideOffsets2D_f32;
typedef TypedSideOffsets2D_f32__LayoutUnit LayoutSideOffsets2D;
@@ -49,10 +42,7 @@ typedef struct {
float height;
} TypedSize2D_f32__LayoutUnit;
typedef struct {
float width;
float height;
} Size2D_f32;
typedef TypedSize2D_f32__UnknownUnit Size2D_f32;
typedef TypedSize2D_f32__LayoutUnit LayoutSize2D;
@@ -66,10 +56,7 @@ typedef struct {
float y;
} TypedPoint2D_f32__LayoutUnit;
typedef struct {
float x;
float y;
} Point2D_f32;
typedef TypedPoint2D_f32__UnknownUnit Point2D_f32;
typedef TypedPoint2D_f32__LayoutUnit LayoutPoint2D;
@@ -83,10 +70,7 @@ typedef struct {
TypedSize2D_f32__LayoutUnit size;
} TypedRect_f32__LayoutUnit;
typedef struct {
TypedPoint2D_f32__UnknownUnit origin;
TypedSize2D_f32__UnknownUnit size;
} Rect_f32;
typedef TypedRect_f32__UnknownUnit Rect_f32;
typedef TypedRect_f32__LayoutUnit LayoutRect;
+10 -26
View File
@@ -11,11 +11,9 @@ struct TypedLength {
};
template<typename T>
struct Length {
T _0;
};
using Length = TypedLength<T, UnknownUnit>;
typedef TypedLength<float, LayoutUnit> LayoutLength;
using LayoutLength = TypedLength<float, LayoutUnit>;
template<typename T, typename U>
struct TypedSideOffsets2D {
@@ -26,14 +24,9 @@ struct TypedSideOffsets2D {
};
template<typename T>
struct SideOffsets2D {
T top;
T right;
T bottom;
T left;
};
using SideOffsets2D = TypedSideOffsets2D<T, UnknownUnit>;
typedef TypedSideOffsets2D<float, LayoutUnit> LayoutSideOffsets2D;
using LayoutSideOffsets2D = TypedSideOffsets2D<float, LayoutUnit>;
template<typename T, typename U>
struct TypedSize2D {
@@ -42,12 +35,9 @@ struct TypedSize2D {
};
template<typename T>
struct Size2D {
T width;
T height;
};
using Size2D = TypedSize2D<T, UnknownUnit>;
typedef TypedSize2D<float, LayoutUnit> LayoutSize2D;
using LayoutSize2D = TypedSize2D<float, LayoutUnit>;
template<typename T, typename U>
struct TypedPoint2D {
@@ -56,12 +46,9 @@ struct TypedPoint2D {
};
template<typename T>
struct Point2D {
T x;
T y;
};
using Point2D = TypedPoint2D<T, UnknownUnit>;
typedef TypedPoint2D<float, LayoutUnit> LayoutPoint2D;
using LayoutPoint2D = TypedPoint2D<float, LayoutUnit>;
template<typename T, typename U>
struct TypedRect {
@@ -70,12 +57,9 @@ struct TypedRect {
};
template<typename T>
struct Rect {
TypedPoint2D<T, UnknownUnit> origin;
TypedSize2D<T, UnknownUnit> size;
};
using Rect = TypedRect<T, UnknownUnit>;
typedef TypedRect<float, LayoutUnit> LayoutRect;
using LayoutRect = TypedRect<float, LayoutUnit>;
template<typename T, typename Src, typename Dst>
struct TypedTransform2D {
+3 -1
View File
@@ -28,7 +28,9 @@ typedef struct {
typedef struct {
const float *a;
const float *b;
} Indirection_f32;
} Tuple_f32__f32;
typedef Tuple_f32__f32 Indirection_f32;
void root(Foo_i32 a,
Foo_f32 b,
+1 -4
View File
@@ -16,10 +16,7 @@ struct Tuple {
};
template<typename T>
struct Indirection {
const T *a;
const float *b;
};
using Indirection = Tuple<T, float>;
extern "C" {
+3 -1
View File
@@ -28,7 +28,9 @@ typedef union {
typedef union {
const float *a;
const float *b;
} Indirection_f32;
} Tuple_f32__f32;
typedef Tuple_f32__f32 Indirection_f32;
void root(Foo_i32 a,
Foo_f32 b,
+1 -4
View File
@@ -16,10 +16,7 @@ union Tuple {
};
template<typename T>
union Indirection {
const T *a;
const float *b;
};
using Indirection = Tuple<T, float>;
extern "C" {
+3 -1
View File
@@ -5,6 +5,8 @@
typedef struct {
int32_t x;
int32_t y;
} IntFoo_i32;
} Foo_i32__i32;
typedef Foo_i32__i32 IntFoo_i32;
void root(IntFoo_i32 a);
+7 -4
View File
@@ -1,12 +1,15 @@
#include <cstdint>
#include <cstdlib>
template<typename T>
struct IntFoo {
int32_t x;
T y;
template<typename T, typename U>
struct Foo {
T x;
U y;
};
template<typename T>
using IntFoo = Foo<int32_t, T>;
extern "C" {
void root(IntFoo<int32_t> a);