Add support for static items
This commit is contained in:
parent
d38ffa5f7d
commit
e6ad035471
15
compile-tests/static.rs
Normal file
15
compile-tests/static.rs
Normal file
@ -0,0 +1,15 @@
|
||||
static NUMBER: i32 = 10;
|
||||
static STRING: &'static libc::c_char = "hello world";
|
||||
|
||||
#[repr(C)]
|
||||
struct Foo {
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
}
|
||||
|
||||
static mut FOO: Foo = Foo { };
|
||||
static BAR: Bar = Bar { };
|
||||
|
||||
#[no_mangle]
|
||||
extern "C" fn root() { }
|
@ -8,12 +8,13 @@ use std::path;
|
||||
use std::fs;
|
||||
|
||||
use bindgen::config::{Config, Language};
|
||||
use bindgen::ir::{Constant, ItemContainer, Function};
|
||||
use bindgen::ir::{Constant, ItemContainer, Function, Static};
|
||||
use bindgen::monomorph::TemplateSpecialization;
|
||||
use bindgen::writer::{ListType, Source, SourceWriter};
|
||||
|
||||
pub struct Bindings {
|
||||
config: Config,
|
||||
globals: Vec<Static>,
|
||||
constants: Vec<Constant>,
|
||||
items: Vec<ItemContainer>,
|
||||
functions: Vec<Function>,
|
||||
@ -23,11 +24,13 @@ pub struct Bindings {
|
||||
impl Bindings {
|
||||
pub fn new(config: Config,
|
||||
constants: Vec<Constant>,
|
||||
globals: Vec<Static>,
|
||||
items: Vec<ItemContainer>,
|
||||
functions: Vec<Function>,
|
||||
template_specializations: Vec<TemplateSpecialization>) -> Bindings {
|
||||
Bindings {
|
||||
config: config,
|
||||
globals: globals,
|
||||
constants: constants,
|
||||
items: items,
|
||||
functions: functions,
|
||||
@ -105,7 +108,8 @@ impl Bindings {
|
||||
|
||||
out.new_line_if_not_start();
|
||||
match item {
|
||||
&ItemContainer::Constant(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::Constant(..) => unreachable!(),
|
||||
&ItemContainer::Static(..) => unreachable!(),
|
||||
&ItemContainer::Enum(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::Struct(ref x) => x.write(&self.config, &mut out),
|
||||
&ItemContainer::OpaqueItem(ref x) => x.write(&self.config, &mut out),
|
||||
@ -117,6 +121,12 @@ impl Bindings {
|
||||
out.new_line();
|
||||
}
|
||||
|
||||
for global in &self.globals {
|
||||
out.new_line_if_not_start();
|
||||
global.write(&self.config, &mut out);
|
||||
out.new_line();
|
||||
}
|
||||
|
||||
if let Some(ref f) = self.config.autogen_warning {
|
||||
out.new_line_if_not_start();
|
||||
out.write(&f);
|
||||
|
@ -9,7 +9,7 @@ use syn;
|
||||
use bindgen::cargo::Cargo;
|
||||
use bindgen::config::Config;
|
||||
use bindgen::ir::{AnnotationSet, Cfg, Constant, Documentation, Enum, Function};
|
||||
use bindgen::ir::{ItemMap, OpaqueItem, Specialization, Struct, Typedef};
|
||||
use bindgen::ir::{ItemMap, OpaqueItem, Specialization, Static, Struct, Typedef};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::rust_lib;
|
||||
use bindgen::utilities::{SynAbiHelpers, SynItemHelpers};
|
||||
@ -81,6 +81,7 @@ impl LibraryBuilder {
|
||||
|
||||
Ok(Library::new(self.config,
|
||||
result.constants,
|
||||
result.globals,
|
||||
result.enums,
|
||||
result.structs,
|
||||
result.opaque_items,
|
||||
@ -93,6 +94,7 @@ impl LibraryBuilder {
|
||||
#[derive(Debug, Clone)]
|
||||
struct LibraryParseResult {
|
||||
constants: ItemMap<Constant>,
|
||||
globals: ItemMap<Static>,
|
||||
enums: ItemMap<Enum>,
|
||||
structs: ItemMap<Struct>,
|
||||
opaque_items: ItemMap<OpaqueItem>,
|
||||
@ -106,6 +108,7 @@ impl LibraryParseResult {
|
||||
LibraryParseResult {
|
||||
enums: ItemMap::new(),
|
||||
constants: ItemMap::new(),
|
||||
globals: ItemMap::new(),
|
||||
structs: ItemMap::new(),
|
||||
opaque_items: ItemMap::new(),
|
||||
typedefs: ItemMap::new(),
|
||||
@ -179,6 +182,14 @@ impl LibraryParseResult {
|
||||
ty,
|
||||
expr);
|
||||
}
|
||||
syn::ItemKind::Static(ref ty, ref mutability, ref _expr) => {
|
||||
self.load_syn_static(binding_crate_name,
|
||||
crate_name,
|
||||
mod_cfg,
|
||||
item,
|
||||
ty,
|
||||
mutability);
|
||||
}
|
||||
syn::ItemKind::Struct(ref variant, ref generics) => {
|
||||
self.load_syn_struct(crate_name, mod_cfg, item, variant, generics);
|
||||
}
|
||||
@ -322,6 +333,42 @@ impl LibraryParseResult {
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a `static` declaration
|
||||
fn load_syn_static(&mut self,
|
||||
binding_crate_name: &str,
|
||||
crate_name: &str,
|
||||
mod_cfg: &Option<Cfg>,
|
||||
item: &syn::Item,
|
||||
ty: &syn::Ty,
|
||||
mutability: &syn::Mutability) {
|
||||
if crate_name != binding_crate_name {
|
||||
info!("Skip {}::{} - (static's outside of the binding crate are not used).",
|
||||
crate_name,
|
||||
&item.ident);
|
||||
return;
|
||||
}
|
||||
|
||||
let static_name = item.ident.to_string();
|
||||
|
||||
match Static::load(static_name.clone(),
|
||||
ty,
|
||||
mutability,
|
||||
&item.attrs,
|
||||
mod_cfg) {
|
||||
Ok(constant) => {
|
||||
info!("Take {}::{}.", crate_name, &item.ident);
|
||||
|
||||
self.globals.try_insert(constant);
|
||||
}
|
||||
Err(msg) => {
|
||||
warn!("Skip {}::{} - ({})",
|
||||
crate_name,
|
||||
&item.ident,
|
||||
msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Loads a `struct` declaration
|
||||
fn load_syn_struct(&mut self,
|
||||
crate_name: &str,
|
||||
|
94
src/bindgen/ir/global.rs
Normal file
94
src/bindgen/ir/global.rs
Normal file
@ -0,0 +1,94 @@
|
||||
/* 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::io::Write;
|
||||
|
||||
use syn;
|
||||
|
||||
use bindgen::config::Config;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{AnnotationSet, Cfg, Documentation, Item, ItemContainer, Specialization, Type};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::writer::{Source, SourceWriter};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Static {
|
||||
pub name: String,
|
||||
pub ty: Type,
|
||||
pub mutable: bool,
|
||||
pub cfg: Option<Cfg>,
|
||||
pub annotations: AnnotationSet,
|
||||
pub documentation: Documentation,
|
||||
}
|
||||
|
||||
|
||||
impl Static {
|
||||
pub fn load(name: String,
|
||||
ty: &syn::Ty,
|
||||
mutable: &syn::Mutability,
|
||||
attrs: &Vec<syn::Attribute>,
|
||||
mod_cfg: &Option<Cfg>) -> Result<Static, String>
|
||||
{
|
||||
let ty = Type::load(ty)?;
|
||||
|
||||
if ty.is_none() {
|
||||
return Err("Cannot have a zero sized static definition.".to_owned());
|
||||
}
|
||||
|
||||
let ty = ty.unwrap();
|
||||
let mutable = mutable == &syn::Mutability::Mutable;
|
||||
|
||||
Ok(Static {
|
||||
name: name,
|
||||
ty: ty,
|
||||
mutable: mutable,
|
||||
cfg: Cfg::append(mod_cfg, Cfg::load(attrs)),
|
||||
annotations: AnnotationSet::load(attrs)?,
|
||||
documentation: Documentation::load(attrs),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Item for Static {
|
||||
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::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);
|
||||
}
|
||||
}
|
||||
|
||||
impl Source for Static {
|
||||
fn write<F: Write>(&self, config: &Config, out: &mut SourceWriter<F>) {
|
||||
out.write("extern ");
|
||||
if let Type::ConstPtr(..) = self.ty { } else {
|
||||
if !self.mutable {
|
||||
out.write("const ");
|
||||
}
|
||||
}
|
||||
self.ty.write(config, out);
|
||||
out.write(&format!(" {};", self.name));
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ use std::mem;
|
||||
|
||||
use bindgen::config::Config;
|
||||
use bindgen::dependencies::Dependencies;
|
||||
use bindgen::ir::{AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Specialization, Struct, Type, Typedef};
|
||||
use bindgen::ir::{AnnotationSet, Cfg, Constant, Enum, OpaqueItem, Specialization, Static, Struct, Type, Typedef};
|
||||
use bindgen::library::Library;
|
||||
use bindgen::monomorph::Monomorphs;
|
||||
|
||||
@ -30,6 +30,7 @@ pub trait Item {
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum ItemContainer {
|
||||
Constant(Constant),
|
||||
Static(Static),
|
||||
OpaqueItem(OpaqueItem),
|
||||
Struct(Struct),
|
||||
Enum(Enum),
|
||||
@ -41,6 +42,7 @@ impl ItemContainer {
|
||||
pub fn deref(&self) -> &Item {
|
||||
match self {
|
||||
&ItemContainer::Constant(ref x) => x,
|
||||
&ItemContainer::Static(ref x) => x,
|
||||
&ItemContainer::OpaqueItem(ref x) => x,
|
||||
&ItemContainer::Struct(ref x) => x,
|
||||
&ItemContainer::Enum(ref x) => x,
|
||||
|
@ -7,6 +7,7 @@ pub mod cfg;
|
||||
pub mod constant;
|
||||
pub mod enumeration;
|
||||
pub mod function;
|
||||
pub mod global;
|
||||
pub mod item;
|
||||
pub mod opaque;
|
||||
pub mod path;
|
||||
@ -22,6 +23,7 @@ pub use self::cfg::*;
|
||||
pub use self::constant::*;
|
||||
pub use self::enumeration::*;
|
||||
pub use self::function::*;
|
||||
pub use self::global::*;
|
||||
pub use self::item::*;
|
||||
pub use self::opaque::*;
|
||||
pub use self::path::*;
|
||||
|
@ -65,8 +65,11 @@ impl Specialization {
|
||||
}
|
||||
|
||||
match items[0] {
|
||||
ItemContainer::Constant(ref aliased) => {
|
||||
aliased.specialize(library, self)
|
||||
ItemContainer::Constant(..) => {
|
||||
unreachable!()
|
||||
}
|
||||
ItemContainer::Static(..) => {
|
||||
unreachable!()
|
||||
}
|
||||
ItemContainer::OpaqueItem(ref aliased) => {
|
||||
aliased.specialize(library, self)
|
||||
|
@ -398,6 +398,9 @@ impl Type {
|
||||
ItemContainer::Constant(..) => {
|
||||
warn!("Cannot instantiate a generic constant.")
|
||||
},
|
||||
ItemContainer::Static(..) => {
|
||||
warn!("Cannot instantiate a generic static.")
|
||||
},
|
||||
ItemContainer::OpaqueItem(ref x) => {
|
||||
x.instantiate_monomorph(&path.generics, out);
|
||||
},
|
||||
|
@ -9,13 +9,14 @@ 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, Struct, Typedef};
|
||||
use bindgen::ir::{OpaqueItem, Path, Specialization, Static, Struct, Typedef};
|
||||
use bindgen::monomorph::{Monomorphs, TemplateSpecialization};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Library {
|
||||
config: Config,
|
||||
constants: ItemMap<Constant>,
|
||||
globals: ItemMap<Static>,
|
||||
enums: ItemMap<Enum>,
|
||||
structs: ItemMap<Struct>,
|
||||
opaque_items: ItemMap<OpaqueItem>,
|
||||
@ -28,6 +29,7 @@ pub struct Library {
|
||||
impl Library {
|
||||
pub fn new(config: Config,
|
||||
constants: ItemMap<Constant>,
|
||||
globals: ItemMap<Static>,
|
||||
enums: ItemMap<Enum>,
|
||||
structs: ItemMap<Struct>,
|
||||
opaque_items: ItemMap<OpaqueItem>,
|
||||
@ -37,6 +39,7 @@ impl Library {
|
||||
Library {
|
||||
config: config,
|
||||
constants: constants,
|
||||
globals: globals,
|
||||
enums: enums,
|
||||
structs: structs,
|
||||
opaque_items: opaque_items,
|
||||
@ -58,6 +61,9 @@ impl Library {
|
||||
for function in &self.functions {
|
||||
function.add_dependencies(&self, &mut dependencies);
|
||||
}
|
||||
self.globals.for_all_items(|global| {
|
||||
global.add_dependencies(&self, &mut dependencies);
|
||||
});
|
||||
|
||||
if self.config.structure.generic_template_specialization &&
|
||||
self.config.language == Language::Cxx {
|
||||
@ -70,11 +76,13 @@ impl Library {
|
||||
|
||||
let items = dependencies.order;
|
||||
let constants = self.constants.to_vec();
|
||||
let globals = self.globals.to_vec();
|
||||
let functions = mem::replace(&mut self.functions, Vec::new());
|
||||
let template_specializations = mem::replace(&mut self.template_specializations, Vec::new());
|
||||
|
||||
Ok(Bindings::new(self.config.clone(),
|
||||
constants,
|
||||
globals,
|
||||
items,
|
||||
functions,
|
||||
template_specializations))
|
||||
@ -105,6 +113,9 @@ impl Library {
|
||||
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);
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user