Remove Specialization in favour of generic typedef
This commit is contained in:
committed by
Ryan Hunt
parent
4ee1a8bcc8
commit
fada89c7f4
@@ -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();
|
||||
}
|
||||
|
||||
@@ -217,7 +217,6 @@ impl Builder {
|
||||
result.unions,
|
||||
result.opaque_items,
|
||||
result.typedefs,
|
||||
result.specializations,
|
||||
result.functions).generate()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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))) => {
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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" {
|
||||
|
||||
|
||||
@@ -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" {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -16,10 +16,7 @@ struct Tuple {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct Indirection {
|
||||
const T *a;
|
||||
const float *b;
|
||||
};
|
||||
using Indirection = Tuple<T, float>;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -16,10 +16,7 @@ union Tuple {
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
union Indirection {
|
||||
const T *a;
|
||||
const float *b;
|
||||
};
|
||||
using Indirection = Tuple<T, float>;
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user