2016-10-24 14:13:13 -07:00
|
|
|
//! Generate Rust bindings for C and C++ libraries.
|
|
|
|
//!
|
|
|
|
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
|
|
|
|
//! functions and use types defined in the header.
|
|
|
|
//!
|
2017-04-24 01:08:19 -07:00
|
|
|
//! See the [`Builder`](./struct.Builder.html) struct for usage.
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
#![deny(missing_docs)]
|
2016-10-31 15:27:44 +01:00
|
|
|
#![deny(warnings)]
|
2016-12-23 12:37:16 +01:00
|
|
|
#![deny(unused_extern_crates)]
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
// We internally use the deprecated BindgenOptions all over the place. Once we
|
|
|
|
// remove its `pub` declaration, we can un-deprecate it and remove this pragma.
|
|
|
|
#![allow(deprecated)]
|
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
// To avoid rather annoying warnings when matching with CXCursor_xxx as a
|
|
|
|
// constant.
|
|
|
|
#![allow(non_upper_case_globals)]
|
|
|
|
|
2016-10-24 14:58:10 -07:00
|
|
|
#[macro_use]
|
2016-12-23 12:37:16 +01:00
|
|
|
#[allow(unused_extern_crates)]
|
2016-10-24 14:58:10 -07:00
|
|
|
extern crate cfg_if;
|
2016-11-06 14:36:47 +01:00
|
|
|
extern crate cexpr;
|
2015-05-03 11:40:47 +01:00
|
|
|
extern crate syntex_syntax as syntax;
|
2016-07-09 13:04:29 -07:00
|
|
|
extern crate aster;
|
|
|
|
extern crate quasi;
|
2016-07-03 20:26:13 -07:00
|
|
|
extern crate clang_sys;
|
2017-05-17 16:37:06 -07:00
|
|
|
extern crate peeking_take_while;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
extern crate regex;
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
#[macro_use]
|
2016-11-16 09:27:13 +11:00
|
|
|
extern crate lazy_static;
|
|
|
|
|
|
|
|
#[cfg(feature = "logging")]
|
|
|
|
#[macro_use]
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
extern crate log;
|
2016-11-16 09:27:13 +11:00
|
|
|
|
|
|
|
#[cfg(not(feature = "logging"))]
|
2016-10-22 19:39:37 +08:00
|
|
|
#[macro_use]
|
2016-11-16 09:27:13 +11:00
|
|
|
mod log_stubs;
|
2014-05-15 17:33:42 +01:00
|
|
|
|
2017-04-06 15:21:33 -07:00
|
|
|
#[macro_use]
|
|
|
|
mod extra_assertions;
|
|
|
|
|
2016-10-24 14:58:10 -07:00
|
|
|
// A macro to declare an internal module for which we *must* provide
|
2017-04-06 14:38:05 -07:00
|
|
|
// documentation for. If we are building with the "testing_only_docs" feature,
|
|
|
|
// then the module is declared public, and our `#![deny(missing_docs)]` pragma
|
|
|
|
// applies to it. This feature is used in CI, so we won't let anything slip by
|
2016-10-24 14:58:10 -07:00
|
|
|
// undocumented. Normal builds, however, will leave the module private, so that
|
|
|
|
// we don't expose internals to library consumers.
|
|
|
|
macro_rules! doc_mod {
|
2016-11-01 12:39:37 +01:00
|
|
|
($m:ident, $doc_mod_name:ident) => {
|
2016-10-24 14:58:10 -07:00
|
|
|
cfg_if! {
|
2017-04-06 14:38:05 -07:00
|
|
|
if #[cfg(feature = "testing_only_docs")] {
|
2016-11-01 12:39:37 +01:00
|
|
|
pub mod $doc_mod_name {
|
|
|
|
//! Autogenerated documentation module.
|
|
|
|
pub use super::$m::*;
|
|
|
|
}
|
2016-10-24 14:58:10 -07:00
|
|
|
} else {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2016-11-01 12:39:37 +01:00
|
|
|
mod clang;
|
|
|
|
mod ir;
|
|
|
|
mod parse;
|
|
|
|
mod regex_set;
|
2016-10-31 16:29:02 -07:00
|
|
|
mod uses;
|
2016-11-01 12:39:37 +01:00
|
|
|
|
2017-03-17 12:16:26 -04:00
|
|
|
pub mod callbacks;
|
2016-11-06 20:32:37 +01:00
|
|
|
|
2016-11-01 12:47:32 +01:00
|
|
|
#[cfg(rustfmt)]
|
|
|
|
mod codegen;
|
|
|
|
|
2016-11-01 12:39:37 +01:00
|
|
|
doc_mod!(clang, clang_docs);
|
|
|
|
doc_mod!(ir, ir_docs);
|
|
|
|
doc_mod!(parse, parse_docs);
|
|
|
|
doc_mod!(regex_set, regex_set_docs);
|
2016-10-31 16:29:02 -07:00
|
|
|
doc_mod!(uses, uses_docs);
|
2016-10-24 14:58:10 -07:00
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
mod codegen {
|
|
|
|
include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
|
|
|
|
}
|
|
|
|
|
2016-11-15 18:32:41 +01:00
|
|
|
use ir::context::{BindgenContext, ItemId};
|
|
|
|
use ir::item::Item;
|
2016-11-01 12:56:14 +01:00
|
|
|
use parse::{ClangItemParser, ParseError};
|
|
|
|
use regex_set::RegexSet;
|
2016-10-31 16:29:02 -07:00
|
|
|
|
2015-05-06 12:27:56 +01:00
|
|
|
use std::fs::OpenOptions;
|
2017-07-13 13:19:33 -07:00
|
|
|
use std::iter;
|
2016-11-01 12:56:14 +01:00
|
|
|
use std::io::{self, Write};
|
2016-07-03 20:26:13 -07:00
|
|
|
use std::path::Path;
|
2017-02-19 12:51:30 +01:00
|
|
|
use std::sync::Arc;
|
2014-06-15 17:48:18 +08:00
|
|
|
|
2014-05-16 19:56:47 +01:00
|
|
|
use syntax::ast;
|
2014-12-23 20:46:13 +01:00
|
|
|
use syntax::codemap::{DUMMY_SP, Span};
|
|
|
|
use syntax::print::pp::eof;
|
2016-11-01 12:56:14 +01:00
|
|
|
use syntax::print::pprust;
|
2014-09-18 16:33:26 +01:00
|
|
|
use syntax::ptr::P;
|
2014-05-16 19:56:47 +01:00
|
|
|
|
2016-12-04 15:15:56 +01:00
|
|
|
/// A type used to indicate which kind of items do we have to generate.
|
|
|
|
///
|
|
|
|
/// TODO(emilio): Use `bitflags!`
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
pub struct CodegenConfig {
|
|
|
|
/// Whether to generate functions.
|
|
|
|
pub functions: bool,
|
|
|
|
/// Whether to generate types.
|
|
|
|
pub types: bool,
|
|
|
|
/// Whether to generate constants.
|
|
|
|
pub vars: bool,
|
|
|
|
/// Whether to generate methods.
|
|
|
|
pub methods: bool,
|
2016-12-12 16:11:43 +01:00
|
|
|
/// Whether to generate constructors.
|
|
|
|
pub constructors: bool,
|
2017-04-03 13:15:24 +02:00
|
|
|
/// Whether to generate destructors.
|
|
|
|
pub destructors: bool,
|
2016-12-04 15:15:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl CodegenConfig {
|
|
|
|
/// Generate all kinds of items.
|
|
|
|
pub fn all() -> Self {
|
|
|
|
CodegenConfig {
|
|
|
|
functions: true,
|
|
|
|
types: true,
|
|
|
|
vars: true,
|
|
|
|
methods: true,
|
2016-12-12 16:11:43 +01:00
|
|
|
constructors: true,
|
2017-04-03 13:15:24 +02:00
|
|
|
destructors: true,
|
2016-12-04 15:15:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Generate nothing.
|
|
|
|
pub fn nothing() -> Self {
|
|
|
|
CodegenConfig {
|
|
|
|
functions: false,
|
|
|
|
types: false,
|
|
|
|
vars: false,
|
|
|
|
methods: false,
|
2016-12-12 16:11:43 +01:00
|
|
|
constructors: false,
|
2017-04-03 13:15:24 +02:00
|
|
|
destructors: false,
|
2016-12-04 15:15:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Default for CodegenConfig {
|
|
|
|
fn default() -> Self {
|
|
|
|
CodegenConfig::all()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Configure and generate Rust bindings for a C/C++ header.
|
|
|
|
///
|
|
|
|
/// This is the main entry point to the library.
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// use bindgen::builder;
|
|
|
|
///
|
|
|
|
/// // Configure and generate bindings.
|
|
|
|
/// let bindings = try!(builder().header("path/to/input/header")
|
|
|
|
/// .whitelisted_type("SomeCoolClass")
|
|
|
|
/// .whitelisted_function("do_some_cool_thing")
|
|
|
|
/// .generate());
|
|
|
|
///
|
|
|
|
/// // Write the generated bindings to an output file.
|
|
|
|
/// try!(bindings.write_to_file("path/to/output.rs"));
|
|
|
|
/// ```
|
2016-10-07 23:27:43 +11:00
|
|
|
#[derive(Debug,Default)]
|
|
|
|
pub struct Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
options: BindgenOptions,
|
2017-07-13 13:19:33 -07:00
|
|
|
input_headers: Vec<String>,
|
|
|
|
// Tuples of unsaved file contents of the form (name, contents).
|
|
|
|
input_header_contents: Vec<(String, String)>,
|
2015-05-06 12:27:56 +01:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Construct a new [`Builder`](./struct.Builder.html).
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn builder() -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
Default::default()
|
|
|
|
}
|
|
|
|
|
2016-10-07 23:27:43 +11:00
|
|
|
impl Builder {
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Generates the command line flags use for creating `Builder`.
|
2017-04-13 08:15:11 +05:45
|
|
|
pub fn command_line_flags(&self) -> Vec<String> {
|
|
|
|
let mut output_vector: Vec<String> = Vec::new();
|
|
|
|
|
2017-07-13 13:19:33 -07:00
|
|
|
if let Some(header) = self.input_headers.last().cloned() {
|
|
|
|
// Positional argument 'header'
|
|
|
|
output_vector.push(header);
|
2017-04-13 08:15:11 +05:45
|
|
|
}
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.bitfield_enums
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--bitfield-enum".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.constified_enums
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--constified-enum".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-06-11 13:26:13 -07:00
|
|
|
self.options
|
|
|
|
.constified_enum_modules
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--constified-enum-module".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-04-13 08:15:11 +05:45
|
|
|
self.options
|
|
|
|
.hidden_types
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--blacklist-type".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.layout_tests {
|
|
|
|
output_vector.push("--no-layout-tests".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
if !self.options.derive_debug {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-derive-debug".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.derive_default {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-derive-default".into());
|
|
|
|
} else {
|
|
|
|
output_vector.push("--with-derive-default".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.generate_comments {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-doc-comments".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.whitelist_recursively {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-recursive-whitelist".into());
|
|
|
|
}
|
2017-04-14 14:37:09 -07:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.objc_extern_crate {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--objc-extern-crate".into());
|
|
|
|
}
|
2017-04-14 14:37:09 -07:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.builtins {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--builtins".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(ref prefix) = self.options.ctypes_prefix {
|
|
|
|
output_vector.push("--ctypes-prefix".into());
|
|
|
|
output_vector.push(prefix.clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
if let Some(ref dummy) = self.options.dummy_uses {
|
|
|
|
output_vector.push("--dummy-uses".into());
|
|
|
|
output_vector.push(dummy.clone());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.emit_ast {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--emit-clang-ast".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.emit_ir {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--emit-ir".into());
|
|
|
|
}
|
|
|
|
if let Some(ref graph) = self.options.emit_ir_graphviz {
|
|
|
|
output_vector.push("--emit-ir-graphviz".into());
|
|
|
|
output_vector.push(graph.clone())
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.enable_cxx_namespaces {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--enable-cxx-namespaces".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.disable_name_namespacing {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--disable-name-namespacing".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.links
|
|
|
|
.iter()
|
|
|
|
.map(|&(ref item, _)| {
|
|
|
|
output_vector.push("--framework".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.codegen_config.functions {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--ignore-functions".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
output_vector.push("--generate".into());
|
|
|
|
|
|
|
|
//Temporary placeholder for below 4 options
|
|
|
|
let mut options:Vec<String> = Vec::new();
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.codegen_config.functions {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("function".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.codegen_config.types {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("types".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.codegen_config.vars {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("vars".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.codegen_config.methods {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("methods".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.codegen_config.constructors {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("constructors".into());
|
|
|
|
}
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.codegen_config.destructors {
|
2017-04-13 08:15:11 +05:45
|
|
|
options.push("destructors".into());
|
|
|
|
}
|
2017-04-14 14:37:09 -07:00
|
|
|
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push(options.join(","));
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.codegen_config.methods {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--ignore-methods".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.links
|
|
|
|
.iter()
|
|
|
|
.map(|&(ref item, _)| {
|
|
|
|
output_vector.push("--clang-args".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.convert_floats {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-convert-floats".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.prepend_enum_name {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--no-prepend-enum-name".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if !self.options.unstable_rust {
|
2017-06-19 01:09:33 +02:00
|
|
|
output_vector.push("--unstable-rust".into());
|
2017-04-13 08:15:11 +05:45
|
|
|
}
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.opaque_types
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--opaque-type".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.raw_lines
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--raw-line".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.links
|
|
|
|
.iter()
|
|
|
|
.map(|&(ref item, _)| {
|
|
|
|
output_vector.push("--static".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.use_core {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--use-core".into());
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
if self.options.conservative_inline_namespaces {
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector.push("--conservative-inline-namespaces".into());
|
|
|
|
}
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.whitelisted_functions
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--whitelist-function".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.whitelisted_types
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--whitelist-type".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
|
|
|
self.options
|
|
|
|
.whitelisted_vars
|
|
|
|
.get_items()
|
|
|
|
.iter()
|
|
|
|
.map(|item| {
|
|
|
|
output_vector.push("--whitelist-var".into());
|
|
|
|
output_vector.push(item.trim_left_matches("^").trim_right_matches("$").into());
|
|
|
|
})
|
|
|
|
.count();
|
|
|
|
|
2017-07-13 13:19:33 -07:00
|
|
|
output_vector.push("--".into());
|
|
|
|
|
2017-04-14 14:37:09 -07:00
|
|
|
if !self.options.clang_args.is_empty() {
|
2017-07-13 13:19:33 -07:00
|
|
|
output_vector.extend(
|
|
|
|
self.options
|
|
|
|
.clang_args
|
|
|
|
.iter()
|
|
|
|
.cloned()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.input_headers.len() > 1 {
|
|
|
|
output_vector.extend(self.input_headers[..self.input_headers.len() - 1].iter().cloned());
|
2017-04-14 14:37:09 -07:00
|
|
|
}
|
|
|
|
|
2017-04-13 08:15:11 +05:45
|
|
|
output_vector
|
|
|
|
}
|
|
|
|
|
2017-05-01 13:37:42 -07:00
|
|
|
/// Add an input C/C++ header to generate bindings for.
|
|
|
|
///
|
|
|
|
/// This can be used to generate bindings to a single header:
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// let bindings = bindgen::Builder::default()
|
|
|
|
/// .header("input.h")
|
|
|
|
/// .generate()
|
|
|
|
/// .unwrap();
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Or you can invoke it multiple times to generate bindings to multiple
|
|
|
|
/// headers:
|
|
|
|
///
|
|
|
|
/// ```ignore
|
|
|
|
/// let bindings = bindgen::Builder::default()
|
|
|
|
/// .header("first.h")
|
|
|
|
/// .header("second.h")
|
|
|
|
/// .header("third.h")
|
|
|
|
/// .generate()
|
|
|
|
/// .unwrap();
|
|
|
|
/// ```
|
2016-10-31 16:29:02 -07:00
|
|
|
pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
|
2017-07-13 13:19:33 -07:00
|
|
|
self.input_headers.push(header.into());
|
2016-12-11 09:46:49 +01:00
|
|
|
self
|
2015-06-07 18:25:33 -04:00
|
|
|
}
|
|
|
|
|
2017-03-27 13:02:33 -04:00
|
|
|
/// Add `contents` as an input C/C++ header named `name`.
|
|
|
|
///
|
|
|
|
/// The file `name` will be added to the clang arguments.
|
|
|
|
pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
|
2017-07-13 13:19:33 -07:00
|
|
|
self.input_header_contents.push((name.into(), contents.into()));
|
2017-03-27 13:02:33 -04:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-02-13 22:35:28 +03:00
|
|
|
/// Set the output graphviz file.
|
|
|
|
pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
|
|
|
|
let path = path.into();
|
|
|
|
self.options.emit_ir_graphviz = Some(path);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-26 17:09:28 +01:00
|
|
|
/// Whether the generated bindings should contain documentation comments or
|
|
|
|
/// not.
|
|
|
|
///
|
|
|
|
/// This ideally will always be true, but it may need to be false until we
|
|
|
|
/// implement some processing on comments to work around issues as described
|
|
|
|
/// in:
|
|
|
|
///
|
|
|
|
/// https://github.com/servo/rust-bindgen/issues/426
|
|
|
|
pub fn generate_comments(mut self, doit: bool) -> Self {
|
|
|
|
self.options.generate_comments = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-26 17:26:02 +01:00
|
|
|
/// Whether to whitelist types recursively or not. Defaults to true.
|
|
|
|
///
|
|
|
|
/// This can be used to get bindgen to generate _exactly_ the types you want
|
|
|
|
/// in your bindings, and then import other types manually via other means
|
2017-04-24 01:08:19 -07:00
|
|
|
/// (like [`raw_line`](#method.raw_line)).
|
2017-01-26 17:26:02 +01:00
|
|
|
pub fn whitelist_recursively(mut self, doit: bool) -> Self {
|
|
|
|
self.options.whitelist_recursively = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
|
2017-01-29 01:10:38 +02:00
|
|
|
/// in the prologue of the files generated from objective-c files
|
|
|
|
pub fn objc_extern_crate(mut self, doit: bool) -> Self {
|
|
|
|
self.options.objc_extern_crate = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Whether to use the clang-provided name mangling. This is true by default
|
|
|
|
/// and probably needed for C++ features.
|
2017-02-18 19:30:00 +01:00
|
|
|
///
|
|
|
|
/// However, some old libclang versions seem to return incorrect results in
|
|
|
|
/// some cases for non-mangled functions, see [1], so we allow disabling it.
|
|
|
|
///
|
|
|
|
/// [1]: https://github.com/servo/rust-bindgen/issues/528
|
|
|
|
pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
|
|
|
|
self.options.enable_mangling = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-31 16:29:02 -07:00
|
|
|
/// Generate a C/C++ file that includes the header and has dummy uses of
|
|
|
|
/// every type defined in the header.
|
|
|
|
pub fn dummy_uses<T: Into<String>>(mut self, dummy_uses: T) -> Builder {
|
|
|
|
self.options.dummy_uses = Some(dummy_uses.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-24 10:51:19 +01:00
|
|
|
/// Hide the given type from the generated bindings. Regular expressions are
|
|
|
|
/// supported.
|
2017-01-05 23:59:47 -08:00
|
|
|
pub fn hide_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.hidden_types.insert(arg);
|
2016-03-20 18:30:54 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-24 10:51:19 +01:00
|
|
|
/// Treat the given type as opaque in the generated bindings. Regular
|
|
|
|
/// expressions are supported.
|
2017-01-05 23:59:47 -08:00
|
|
|
pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.opaque_types.insert(arg);
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Whitelist the given type so that it (and all types that it transitively
|
2017-01-24 10:51:19 +01:00
|
|
|
/// refers to) appears in the generated bindings. Regular expressions are
|
|
|
|
/// supported.
|
2017-01-05 23:59:47 -08:00
|
|
|
pub fn whitelisted_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.whitelisted_types.insert(arg);
|
2016-03-23 22:45:09 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Whitelist the given function so that it (and all types that it
|
2017-01-24 10:51:19 +01:00
|
|
|
/// transitively refers to) appears in the generated bindings. Regular
|
|
|
|
/// expressions are supported.
|
2017-01-05 23:59:47 -08:00
|
|
|
pub fn whitelisted_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.whitelisted_functions.insert(arg);
|
2016-10-08 00:20:11 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Whitelist the given variable so that it (and all types that it
|
2017-01-24 10:51:19 +01:00
|
|
|
/// transitively refers to) appears in the generated bindings. Regular
|
|
|
|
/// expressions are supported.
|
2017-01-05 23:59:47 -08:00
|
|
|
pub fn whitelisted_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.whitelisted_vars.insert(arg);
|
2016-10-08 00:58:33 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 07:31:53 +01:00
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as being
|
2017-01-24 00:51:19 -08:00
|
|
|
/// bitfield-like. Regular expressions are supported.
|
2016-11-08 07:31:53 +01:00
|
|
|
///
|
2017-01-24 10:51:19 +01:00
|
|
|
/// This makes bindgen generate a type that isn't a rust `enum`. Regular
|
|
|
|
/// expressions are supported.
|
2017-01-05 23:59:47 -08:00
|
|
|
pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.bitfield_enums.insert(arg);
|
2016-11-08 07:31:53 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-06-11 13:26:13 -07:00
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a set of
|
|
|
|
/// constants.
|
2017-01-24 10:51:19 +01:00
|
|
|
///
|
|
|
|
/// This makes bindgen generate constants instead of enums. Regular
|
|
|
|
/// expressions are supported.
|
|
|
|
pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.constified_enums.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-06-11 13:26:13 -07:00
|
|
|
/// Mark the given enum (or set of enums, if using a pattern) as a set of
|
|
|
|
/// constants that should be put into a module.
|
|
|
|
///
|
|
|
|
/// This makes bindgen generate a modules containing constants instead of
|
|
|
|
/// enums. Regular expressions are supported.
|
|
|
|
pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
|
|
|
|
self.options.constified_enum_modules.insert(arg);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Add a string to prepend to the generated bindings. The string is passed
|
|
|
|
/// through without any modification.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
|
2016-04-03 01:03:06 +02:00
|
|
|
self.options.raw_lines.push(arg.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Add an argument to be passed straight through to clang.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
|
2015-06-07 18:25:33 -04:00
|
|
|
self.options.clang_args.push(arg.into());
|
2015-05-06 12:27:56 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-17 18:28:51 +09:00
|
|
|
/// Add arguments to be passed straight through to clang.
|
|
|
|
pub fn clang_args<I>(mut self, iter: I) -> Builder
|
|
|
|
where I: IntoIterator,
|
|
|
|
I::Item: AsRef<str> {
|
|
|
|
for arg in iter {
|
|
|
|
self = self.clang_arg(arg.as_ref())
|
|
|
|
}
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Make the generated bindings link the given shared library.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
self.options.links.push((library.into(), LinkType::Default));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Make the generated bindings link the given static library.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
self.options.links.push((library.into(), LinkType::Static));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Make the generated bindings link the given framework.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
self.options.links.push((library.into(), LinkType::Framework));
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Emit bindings for builtin definitions (for example `__builtin_va_list`)
|
|
|
|
/// in the generated Rust.
|
2016-10-07 23:27:43 +11:00
|
|
|
pub fn emit_builtins(mut self) -> Builder {
|
2015-05-06 12:27:56 +01:00
|
|
|
self.options.builtins = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Avoid converting floats to `f32`/`f64` by default.
|
2016-11-06 20:52:01 +01:00
|
|
|
pub fn no_convert_floats(mut self) -> Self {
|
|
|
|
self.options.convert_floats = false;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// Set whether layout tests should be generated.
|
|
|
|
pub fn layout_tests(mut self, doit: bool) -> Self {
|
|
|
|
self.options.layout_tests = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-24 09:49:49 +01:00
|
|
|
/// Set whether `Debug` should be derived by default.
|
|
|
|
pub fn derive_debug(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_debug = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-02-05 17:12:05 +08:00
|
|
|
/// Set whether `Default` should be derived by default.
|
|
|
|
pub fn derive_default(mut self, doit: bool) -> Self {
|
|
|
|
self.options.derive_default = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 19:55:49 +11:00
|
|
|
/// Emit Clang AST.
|
|
|
|
pub fn emit_clang_ast(mut self) -> Builder {
|
|
|
|
self.options.emit_ast = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-15 10:26:26 -08:00
|
|
|
/// Emit IR.
|
|
|
|
pub fn emit_ir(mut self) -> Builder {
|
|
|
|
self.options.emit_ir = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 19:55:49 +11:00
|
|
|
/// Enable C++ namespaces.
|
|
|
|
pub fn enable_cxx_namespaces(mut self) -> Builder {
|
|
|
|
self.options.enable_cxx_namespaces = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Disable name auto-namespacing.
|
2016-11-24 21:06:42 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// By default, bindgen mangles names like `foo::bar::Baz` to look like
|
|
|
|
/// `foo_bar_Baz` instead of just `Baz`.
|
2016-11-24 21:06:42 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// This method disables that behavior.
|
2016-11-24 21:06:42 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Note that this intentionally does not change the names used for
|
|
|
|
/// whitelisting and blacklisting, which should still be mangled with the
|
2016-11-24 21:06:42 +01:00
|
|
|
/// namespaces.
|
2016-11-29 20:37:22 +01:00
|
|
|
///
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Note, also, that this option may cause bindgen to generate duplicate
|
|
|
|
/// names.
|
2016-11-24 21:06:42 +01:00
|
|
|
pub fn disable_name_namespacing(mut self) -> Builder {
|
|
|
|
self.options.disable_name_namespacing = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-07 02:30:51 +01:00
|
|
|
/// Treat inline namespaces conservatively.
|
|
|
|
///
|
|
|
|
/// This is tricky, because in C++ is technically legal to override an item
|
|
|
|
/// defined in an inline namespace:
|
|
|
|
///
|
|
|
|
/// ```cpp
|
|
|
|
/// inline namespace foo {
|
|
|
|
/// using Bar = int;
|
|
|
|
/// }
|
|
|
|
/// using Bar = long;
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// Even though referencing `Bar` is a compiler error.
|
|
|
|
///
|
|
|
|
/// We want to support this (arguably esoteric) use case, but we don't want
|
|
|
|
/// to make the rest of bindgen users pay an usability penalty for that.
|
|
|
|
///
|
|
|
|
/// To support this, we need to keep all the inline namespaces around, but
|
|
|
|
/// then bindgen usage is a bit more difficult, because you cannot
|
|
|
|
/// reference, e.g., `std::string` (you'd need to use the proper inline
|
|
|
|
/// namespace).
|
|
|
|
///
|
|
|
|
/// We could complicate a lot of the logic to detect name collisions, and if
|
|
|
|
/// not detected generate a `pub use inline_ns::*` or something like that.
|
|
|
|
///
|
|
|
|
/// That's probably something we can do if we see this option is needed in a
|
|
|
|
/// lot of cases, to improve it's usability, but my guess is that this is
|
|
|
|
/// not going to be too useful.
|
|
|
|
pub fn conservative_inline_namespaces(mut self) -> Builder {
|
|
|
|
self.options.conservative_inline_namespaces = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-03-20 14:37:41 +01:00
|
|
|
/// Whether inline functions should be generated or not.
|
|
|
|
///
|
|
|
|
/// Note that they will usually not work. However you can use
|
|
|
|
/// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
|
|
|
|
/// responsible of compiling the library to make them callable.
|
|
|
|
pub fn generate_inline_functions(mut self, doit: bool) -> Self {
|
|
|
|
self.options.generate_inline_functions = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-11-08 19:55:49 +11:00
|
|
|
/// Ignore functions.
|
|
|
|
pub fn ignore_functions(mut self) -> Builder {
|
2016-12-04 15:15:56 +01:00
|
|
|
self.options.codegen_config.functions = false;
|
2016-11-08 19:55:49 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Ignore methods.
|
|
|
|
pub fn ignore_methods(mut self) -> Builder {
|
2016-12-04 15:15:56 +01:00
|
|
|
self.options.codegen_config.methods = false;
|
2016-11-08 19:55:49 +11:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-01-24 00:51:19 -08:00
|
|
|
/// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
|
2017-06-19 01:09:33 +02:00
|
|
|
pub fn unstable_rust(mut self, doit: bool) -> Self {
|
|
|
|
self.options.unstable_rust = doit;
|
2016-07-09 13:04:29 -07:00
|
|
|
self
|
|
|
|
}
|
2016-03-10 22:48:23 +01:00
|
|
|
|
2016-11-06 12:02:44 +01:00
|
|
|
/// Use core instead of libstd in the generated bindings.
|
|
|
|
pub fn use_core(mut self) -> Builder {
|
|
|
|
self.options.use_core = true;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Use the given prefix for the raw types instead of `::std::os::raw`.
|
|
|
|
pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
|
|
|
|
self.options.ctypes_prefix = Some(prefix.into());
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Allows configuring types in different situations, see the
|
|
|
|
/// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
|
2017-03-17 12:16:26 -04:00
|
|
|
pub fn parse_callbacks(mut self, cb: Box<callbacks::ParseCallbacks>) -> Self {
|
|
|
|
self.options.parse_callbacks = Some(cb);
|
2016-11-06 20:32:37 +01:00
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-04-24 01:08:19 -07:00
|
|
|
/// Choose what to generate using a
|
|
|
|
/// [`CodegenConfig`](./struct.CodegenConfig.html).
|
2016-12-04 15:15:56 +01:00
|
|
|
pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
|
|
|
|
self.options.codegen_config = config;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2017-02-27 18:17:28 +01:00
|
|
|
/// Prepend the enum name to constant or bitfield variants.
|
|
|
|
pub fn prepend_enum_name(mut self, doit: bool) -> Self {
|
|
|
|
self.options.prepend_enum_name = doit;
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Generate the Rust bindings using the options built up thus far.
|
2017-07-13 13:19:33 -07:00
|
|
|
pub fn generate<'ctx>(mut self) -> Result<Bindings<'ctx>, ()> {
|
|
|
|
self.options.input_header = self.input_headers.pop();
|
|
|
|
self.options.clang_args.extend(
|
|
|
|
self.input_headers
|
|
|
|
.drain(..)
|
|
|
|
.flat_map(|header| {
|
|
|
|
iter::once("-include".into())
|
|
|
|
.chain(iter::once(header))
|
|
|
|
})
|
|
|
|
);
|
|
|
|
|
|
|
|
self.options.input_unsaved_files.extend(
|
|
|
|
self.input_header_contents
|
|
|
|
.drain(..)
|
|
|
|
.map(|(name, contents)| clang::UnsavedFile::new(&name, &contents))
|
|
|
|
);
|
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
Bindings::generate(self.options, None)
|
2015-05-06 12:27:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Configuration options for generated bindings.
|
|
|
|
///
|
|
|
|
/// Deprecated: use a `Builder` instead.
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
#[derive(Debug)]
|
2016-10-24 14:13:13 -07:00
|
|
|
#[deprecated]
|
2014-05-16 19:56:47 +01:00
|
|
|
pub struct BindgenOptions {
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The set of types that have been blacklisted and should not appear
|
|
|
|
/// anywhere in the generated code.
|
2017-01-05 18:55:44 -08:00
|
|
|
pub hidden_types: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// The set of types that should be treated as opaque structures in the
|
|
|
|
/// generated code.
|
2017-01-05 18:55:44 -08:00
|
|
|
pub opaque_types: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// The set of types that we should have bindings for in the generated
|
|
|
|
/// code.
|
|
|
|
///
|
|
|
|
/// This includes all types transitively reachable from any type in this
|
|
|
|
/// set. One might think of whitelisted types/vars/functions as GC roots,
|
|
|
|
/// and the generated Rust code as including everything that gets marked.
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
pub whitelisted_types: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// Whitelisted functions. See docs for `whitelisted_types` for more.
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
pub whitelisted_functions: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// Whitelisted variables. See docs for `whitelisted_types` for more.
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
pub whitelisted_vars: RegexSet,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2016-11-08 07:31:53 +01:00
|
|
|
/// The enum patterns to mark an enum as bitfield.
|
|
|
|
pub bitfield_enums: RegexSet,
|
|
|
|
|
2017-01-24 10:51:19 +01:00
|
|
|
/// The enum patterns to mark an enum as constant.
|
|
|
|
pub constified_enums: RegexSet,
|
|
|
|
|
2017-06-11 13:26:13 -07:00
|
|
|
/// The enum patterns to mark an enum as a module of constants.
|
|
|
|
pub constified_enum_modules: RegexSet,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Whether we should generate builtins or not.
|
2014-05-16 19:56:47 +01:00
|
|
|
pub builtins: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// The set of libraries we should link in the generated Rust code.
|
2014-12-23 20:46:13 +01:00
|
|
|
pub links: Vec<(String, LinkType)>,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// True if we should dump the Clang AST for debugging purposes.
|
2014-05-16 19:56:47 +01:00
|
|
|
pub emit_ast: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2016-11-15 10:26:26 -08:00
|
|
|
/// True if we should dump our internal IR for debugging purposes.
|
|
|
|
pub emit_ir: bool,
|
|
|
|
|
2017-02-13 22:35:28 +03:00
|
|
|
/// Output graphviz dot file.
|
|
|
|
pub emit_ir_graphviz: Option<String>,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// True if we should emulate C++ namespaces with Rust modules in the
|
|
|
|
/// generated bindings.
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
pub enable_cxx_namespaces: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2016-11-24 21:06:42 +01:00
|
|
|
/// True if we should avoid mangling names with namespaces.
|
|
|
|
pub disable_name_namespacing: bool,
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// True if we should generate layout tests for generated structures.
|
|
|
|
pub layout_tests: bool,
|
|
|
|
|
|
|
|
/// True if we should derive Debug trait implementations for C/C++ structures
|
2016-10-24 14:13:13 -07:00
|
|
|
/// and types.
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
pub derive_debug: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
/// True if we should derive Default trait implementations for C/C++ structures
|
2017-02-05 17:12:05 +08:00
|
|
|
/// and types.
|
|
|
|
pub derive_default: bool,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// True if we can use unstable Rust code in the bindings, false if we
|
|
|
|
/// cannot.
|
2016-07-09 13:04:29 -07:00
|
|
|
pub unstable_rust: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2016-11-06 12:02:44 +01:00
|
|
|
/// True if we should avoid using libstd to use libcore instead.
|
|
|
|
pub use_core: bool,
|
|
|
|
|
|
|
|
/// An optional prefix for the "raw" types, like `c_int`, `c_void`...
|
|
|
|
pub ctypes_prefix: Option<String>,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// True if we should generate constant names that are **directly** under
|
|
|
|
/// namespaces.
|
2016-07-04 20:32:33 -07:00
|
|
|
pub namespaced_constants: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// True if we should use MSVC name mangling rules.
|
2016-05-31 10:29:28 -04:00
|
|
|
pub msvc_mangling: bool,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
2016-11-06 20:52:01 +01:00
|
|
|
/// Whether we should convert float types to f32/f64 types.
|
|
|
|
pub convert_floats: bool,
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The set of raw lines to prepend to the generated Rust code.
|
2016-04-03 01:03:06 +02:00
|
|
|
pub raw_lines: Vec<String>,
|
2016-10-24 14:13:13 -07:00
|
|
|
|
|
|
|
/// The set of arguments to pass straight through to Clang.
|
2014-05-26 11:11:30 +08:00
|
|
|
pub clang_args: Vec<String>,
|
2016-10-31 16:29:02 -07:00
|
|
|
|
|
|
|
/// The input header file.
|
|
|
|
pub input_header: Option<String>,
|
|
|
|
|
2017-03-27 13:02:33 -04:00
|
|
|
/// Unsaved files for input.
|
|
|
|
pub input_unsaved_files: Vec<clang::UnsavedFile>,
|
|
|
|
|
2016-10-31 16:29:02 -07:00
|
|
|
/// Generate a dummy C/C++ file that includes the header and has dummy uses
|
|
|
|
/// of all types defined therein. See the `uses` module for more.
|
|
|
|
pub dummy_uses: Option<String>,
|
2016-11-06 20:32:37 +01:00
|
|
|
|
2017-03-17 12:16:26 -04:00
|
|
|
/// A user-provided visitor to allow customizing different kinds of
|
2016-11-06 20:32:37 +01:00
|
|
|
/// situations.
|
2017-03-17 12:16:26 -04:00
|
|
|
pub parse_callbacks: Option<Box<callbacks::ParseCallbacks>>,
|
2016-12-04 15:15:56 +01:00
|
|
|
|
|
|
|
/// Which kind of items should we generate? By default, we'll generate all
|
|
|
|
/// of them.
|
|
|
|
pub codegen_config: CodegenConfig,
|
2017-01-07 02:30:51 +01:00
|
|
|
|
|
|
|
/// Whether to treat inline namespaces conservatively.
|
|
|
|
///
|
|
|
|
/// See the builder method description for more details.
|
|
|
|
pub conservative_inline_namespaces: bool,
|
2017-01-26 17:09:28 +01:00
|
|
|
|
|
|
|
/// Wether to keep documentation comments in the generated output. See the
|
|
|
|
/// documentation for more details.
|
|
|
|
pub generate_comments: bool,
|
2017-01-26 17:26:02 +01:00
|
|
|
|
2017-03-20 14:37:41 +01:00
|
|
|
/// Whether to generate inline functions. Defaults to false.
|
|
|
|
pub generate_inline_functions: bool,
|
|
|
|
|
2017-01-26 17:26:02 +01:00
|
|
|
/// Wether to whitelist types recursively. Defaults to true.
|
|
|
|
pub whitelist_recursively: bool,
|
2017-01-29 01:10:38 +02:00
|
|
|
|
|
|
|
/// Intead of emitting 'use objc;' to files generated from objective c files,
|
|
|
|
/// generate '#[macro_use] extern crate objc;'
|
|
|
|
pub objc_extern_crate: bool,
|
2017-02-18 19:30:00 +01:00
|
|
|
|
|
|
|
/// Whether to use the clang-provided name mangling. This is true and
|
|
|
|
/// probably needed for C++ features.
|
|
|
|
///
|
|
|
|
/// However, some old libclang versions seem to return incorrect results in
|
|
|
|
/// some cases for non-mangled functions, see [1], so we allow disabling it.
|
|
|
|
///
|
|
|
|
/// [1]: https://github.com/servo/rust-bindgen/issues/528
|
|
|
|
pub enable_mangling: bool,
|
2017-02-27 18:17:28 +01:00
|
|
|
|
|
|
|
/// Whether to prepend the enum name to bitfield or constant variants.
|
|
|
|
pub prepend_enum_name: bool,
|
2014-05-16 19:56:47 +01:00
|
|
|
}
|
|
|
|
|
2017-01-30 11:36:56 -05:00
|
|
|
/// TODO(emilio): This is sort of a lie (see the error message that results from
|
|
|
|
/// removing this), but since we don't share references across panic boundaries
|
|
|
|
/// it's ok.
|
|
|
|
impl ::std::panic::UnwindSafe for BindgenOptions {}
|
|
|
|
|
2017-01-05 23:59:47 -08:00
|
|
|
impl BindgenOptions {
|
|
|
|
fn build(&mut self) {
|
|
|
|
self.whitelisted_vars.build();
|
|
|
|
self.whitelisted_types.build();
|
|
|
|
self.whitelisted_functions.build();
|
|
|
|
self.hidden_types.build();
|
|
|
|
self.opaque_types.build();
|
|
|
|
self.bitfield_enums.build();
|
2017-06-11 13:26:13 -07:00
|
|
|
self.constified_enum_modules.build();
|
2017-01-24 10:51:19 +01:00
|
|
|
self.constified_enums.build();
|
2017-01-05 23:59:47 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-16 19:56:47 +01:00
|
|
|
impl Default for BindgenOptions {
|
|
|
|
fn default() -> BindgenOptions {
|
|
|
|
BindgenOptions {
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
hidden_types: Default::default(),
|
|
|
|
opaque_types: Default::default(),
|
|
|
|
whitelisted_types: Default::default(),
|
|
|
|
whitelisted_functions: Default::default(),
|
|
|
|
whitelisted_vars: Default::default(),
|
2016-11-08 07:31:53 +01:00
|
|
|
bitfield_enums: Default::default(),
|
2017-01-24 10:51:19 +01:00
|
|
|
constified_enums: Default::default(),
|
2017-06-11 13:26:13 -07:00
|
|
|
constified_enum_modules: Default::default(),
|
2014-05-16 19:56:47 +01:00
|
|
|
builtins: false,
|
2016-04-14 14:34:16 +02:00
|
|
|
links: vec![],
|
2014-05-16 19:56:47 +01:00
|
|
|
emit_ast: false,
|
2016-11-15 10:26:26 -08:00
|
|
|
emit_ir: false,
|
2017-02-13 22:35:28 +03:00
|
|
|
emit_ir_graphviz: None,
|
2017-04-14 12:37:44 +01:00
|
|
|
layout_tests: true,
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
derive_debug: true,
|
2017-02-05 17:12:05 +08:00
|
|
|
derive_default: false,
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
enable_cxx_namespaces: false,
|
2016-11-24 21:06:42 +01:00
|
|
|
disable_name_namespacing: false,
|
2017-06-19 01:09:33 +02:00
|
|
|
unstable_rust: false,
|
2016-11-06 12:02:44 +01:00
|
|
|
use_core: false,
|
|
|
|
ctypes_prefix: None,
|
2016-07-04 20:32:33 -07:00
|
|
|
namespaced_constants: true,
|
2016-05-31 10:29:28 -04:00
|
|
|
msvc_mangling: false,
|
2016-11-06 20:52:01 +01:00
|
|
|
convert_floats: true,
|
2016-04-03 01:03:06 +02:00
|
|
|
raw_lines: vec![],
|
2016-04-14 14:34:16 +02:00
|
|
|
clang_args: vec![],
|
2016-10-31 16:29:02 -07:00
|
|
|
input_header: None,
|
2017-03-27 13:02:33 -04:00
|
|
|
input_unsaved_files: vec![],
|
2016-10-31 16:29:02 -07:00
|
|
|
dummy_uses: None,
|
2017-03-17 12:16:26 -04:00
|
|
|
parse_callbacks: None,
|
2016-12-04 15:15:56 +01:00
|
|
|
codegen_config: CodegenConfig::all(),
|
2017-01-07 02:30:51 +01:00
|
|
|
conservative_inline_namespaces: false,
|
2017-01-26 17:09:28 +01:00
|
|
|
generate_comments: true,
|
2017-03-20 14:37:41 +01:00
|
|
|
generate_inline_functions: false,
|
2017-01-26 17:26:02 +01:00
|
|
|
whitelist_recursively: true,
|
2017-01-29 01:10:38 +02:00
|
|
|
objc_extern_crate: false,
|
2017-02-18 19:30:00 +01:00
|
|
|
enable_mangling: true,
|
2017-02-27 18:17:28 +01:00
|
|
|
prepend_enum_name: true,
|
2014-05-16 19:56:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The linking type to use with a given library.
|
2016-10-24 14:31:07 -07:00
|
|
|
///
|
|
|
|
/// TODO: #104: This is ignored at the moment, but shouldn't be.
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
2014-12-23 20:46:13 +01:00
|
|
|
pub enum LinkType {
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Use shared library linking. This is the default.
|
2014-12-23 20:46:13 +01:00
|
|
|
Default,
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Use static linking.
|
2014-12-23 20:46:13 +01:00
|
|
|
Static,
|
2016-10-24 14:13:13 -07:00
|
|
|
/// The library is an OSX framework.
|
2016-11-01 12:56:14 +01:00
|
|
|
Framework,
|
2014-12-23 20:46:13 +01:00
|
|
|
}
|
|
|
|
|
2016-12-21 16:07:09 -08:00
|
|
|
fn ensure_libclang_is_loaded() {
|
|
|
|
if clang_sys::is_loaded() {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// XXX (issue #350): Ensure that our dynamically loaded `libclang`
|
|
|
|
// doesn't get dropped prematurely, nor is loaded multiple times
|
|
|
|
// across different threads.
|
|
|
|
|
|
|
|
lazy_static! {
|
2017-02-19 12:51:30 +01:00
|
|
|
static ref LIBCLANG: Arc<clang_sys::SharedLibrary> = {
|
|
|
|
clang_sys::load().expect("Unable to find libclang");
|
|
|
|
clang_sys::get_library()
|
|
|
|
.expect("We just loaded libclang and it had better still be \
|
|
|
|
here!")
|
2016-12-21 16:07:09 -08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2017-02-19 12:51:30 +01:00
|
|
|
clang_sys::set_library(Some(LIBCLANG.clone()));
|
2016-12-21 16:07:09 -08:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Generated Rust bindings.
|
2016-10-31 16:29:02 -07:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct Bindings<'ctx> {
|
|
|
|
context: BindgenContext<'ctx>,
|
2016-04-03 01:03:06 +02:00
|
|
|
module: ast::Mod,
|
2014-05-16 19:56:47 +01:00
|
|
|
}
|
|
|
|
|
2016-10-31 16:29:02 -07:00
|
|
|
impl<'ctx> Bindings<'ctx> {
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Generate bindings for the given options.
|
|
|
|
///
|
2015-05-06 12:27:56 +01:00
|
|
|
/// Deprecated - use a `Builder` instead
|
2016-10-24 14:13:13 -07:00
|
|
|
#[deprecated]
|
2016-12-11 09:46:49 +01:00
|
|
|
pub fn generate(mut options: BindgenOptions,
|
2016-11-01 12:56:14 +01:00
|
|
|
span: Option<Span>)
|
2016-10-31 16:29:02 -07:00
|
|
|
-> Result<Bindings<'ctx>, ()> {
|
SM hacks squash
Generate better enums
Squash of...
Disable prefixing
Default to failing on unknown types
Add support for Char16
Emit errors for unknown cursor kinds
Hack in support for classes
Recurse into unexposed decls
This fixes functions that use extern "C".
Add support for generating unmangled functions
Prefix unnamed data structures with the file name
Recurse into namespaced things
Avoid rust reserved keywords in unmangle func args
Don't create variadic unmangled funcs
Don't translate typedefs to the same name
Ignore operator overloads
Avoid templates
Handle class declarations
Number duplicate demangle functions
Implement copy on enums
Translate stdint types into standard rust int types
Switch enums to i32 for better compatibility
Correctly deal with mangled functions with unnamed args
Mark unmangling functions as unsafe
Attempt to produce structs for C++ classes
Convert references
Generate better func decls for void returns
Make every function callback unsafe
Add support for generics in typedefs
Add support for class templates
Aggressively trim duplicates
Don't generate default impl for templates
Improve handling of templates
Fix function numbering
Fix deduplication
Make unmangling functions extern "C"
Convert all int/float typedefs to standard rust ints/floats
This also gives better information to the bitfield parsing and allows uint32_t and other stdint bitfields to be processed properly
Add support for wchar
Add support for bitfield setter generation
Fix floats
Squash of...
Shorten generated bitfield names
Add support for generating whole bitfields
Add support for enums nested inside structs/classes
Rustup
Fixes #184.
Rustup to b301e02f3 2015-05-19
Inline demangling functions
Add support for base classes/types
Generate bindings for methods
Make duplicate detection less aggressive
Avoid converting long/unsigned longs to rust types.
This fixes 64/32bit issues in structs.
Generate bitfields correctly for typedefs
Convert stdint types to rust types
Derive Debug on BindgenOptions, Bindings, and LinkType.
Remove +'static when writing bindings
Generate virtual function tables
Resolve some warnings
Add NotConst where Constness params are required
Generate real bools when applicable
Squash of...
Add support for comments
Improve bitfield support using const fn
Add limited support for references
Add comments to fields
Don't generate empty comments
Convert char16_t to u16 rather than i16
Convert signed chars to libc::c_char
Fix Cargo.toml rebasing breakage
Fix compiler errors
This gets bindgen to compile and run again, but all but one `cargo
test` tests fail. Not sure if that’s because of mistakes on my part or
if the sm-hacks branch never passed those tests.
Fix build warnings
Use link_name attr for mangled function names
Handle mangled global vars
Only generate bindings for visible symbols
Don't generate arrays for blobs when the length is 1
Name enums inside classes better
Handle template args inside typedefs better
Filter out duplicate decls better
Generate correctly sized enums
Squash of...
Fix bitfield accessor method generation for bools
Insert phantom fields in empty structs
Don't mark unmangling methods as extern "C"
Add back comment support for functions
Add basic annotation support
Don't generate univariant enums
Add support for hide annotation and adjust syntax
Don't generate unsupported structs
Don't parse hidden fields
Don't derive Copy for structs with destructors
Don't implement Clone or Default
Derive Clone when deriving Copy
Bypass single member unions
Disable references in function args for now
Remove extra underscore in mangled names on OSX
Don't translate private methods
Support generating consts from macros that are defined as integer literals.
Handle mangling better
Squash of...
Update README.md for fork
Generate docs for enum items
Generate docs for typedefs
Generate docs for enums
Update syntex_syntax to 0.24.*
Update clang info in README.md
Spit errors and warnings to stdout.
The correct thing to do here is to use env_logger, but that was causing cargo
troubles for me, and this is preferable to swallowing them.
Add the -ignore-functions argument.
Handle 1 << 63 as enum value.
Don't try to convert standard int types in rust_type_id.
It looks like mwu added this, but I'm pretty sure it's a category error. This
function appears to be designed to reproducibly permute C identifiers so that
they don't conflict with builtin rust types. It's specifically _not_ a type
translator (which would happen at the type level, rather than the string
level), and using it as such with callers like ctypedef_to_rs causes us to
generate things like:
type u64 = u64;
While processing stdint.h, which is clearly wrong.
Stop patching in placeholder names for CompInfo and EnumInfo instances during code generator.
As best as I can tell, it's done this way (rather than my way) because bindgen tries
to recognize struct and enums typedefs of the form:
/* This is a common idiom in C, not so much in C++ */
typdef struct {
...
} Foo;
The intention, I think, is to avoid generating rust code for a struct with a placeholder
name followed by a typedef, and just give the struct the right name initially.
This seems like a reasonable goal, though not a particularly important one. However, in
my testing this never actually happens, because we end up calling unnamed_name anyway
during the GComp(ci) case of gen_mod before we get to evaluting the typedef.
So let's just remove that stuff and simplify the code. This lets us remove all the
borrow_mut calls during code generation, which seems necessary for soundness.
gen: Allow empty union members
Use full paths in generation.
Fix test compilation
parser: Add support for parsing namespaces
Partial C++ namespaces support
We currently generate the modules as expected, but we don't resolve the
names from external namespaces well.
Remove unnecesary return statements
Put namespaces behind a flag
Overall now that they aren't complete still.
Moar refactoring
Finally take rid of all the warnings
Even moar
gen: Avoid so much cloning
parser: Refactor the way submodules are stored
This way we can share the global map, while having each module custom
globals.
gen: Checkpoint before the refactoring
This actually keeps working as before.
gen: Make modules (almost) work for typedef'd types
We generate almost valid code, we just have to add some use statements.
Or maybe is a better idea to add an unintelligible name to the root
mod, and actually output a root mod plus a use root::* before.
gen: Document the current submodule approach and some desirable
alternative
gen: Make it actually compilable \o/
gen: Make the code generation usable for every type.
There's just an edge case I've detected, and it's when we remove the
instantiation of C<int>, and another module uses it, because that means
we only know of its existance in that other module.
Probably we might want to use cursor_getSemanticParent to get the real
class instead of the instantiated, but I'm not too confident about that.
Fix a corner case when a template was instantiated in another module.
Added an example of the namespace resolution.
Don't panic when not finding the specialised template
This can be annoying if filtering files out.
Straight rebase completed, let's fix that build errors
wip
Pair up with master
nits
Update AST
Add -no-rename-fields option
This is for compatibility between C bindings and C++ bindings (in C
`struct Foo` and `enum Foo`, are different, while in C++ they aren't).
wip
Add enum tests pass, and add C++ tests
Make a few more struct-related tests pass
2015-03-25 00:39:01 -04:00
|
|
|
let span = span.unwrap_or(DUMMY_SP);
|
2016-12-21 16:07:09 -08:00
|
|
|
ensure_libclang_is_loaded();
|
2014-12-23 20:46:13 +01:00
|
|
|
|
2017-01-05 23:59:47 -08:00
|
|
|
options.build();
|
|
|
|
|
2016-12-11 15:38:53 +01:00
|
|
|
// TODO: Make this path fixup configurable?
|
2017-07-01 01:38:01 +08:00
|
|
|
if let Some(clang) = clang_sys::support::Clang::find(None, &options.clang_args) {
|
2016-12-11 15:38:53 +01:00
|
|
|
// If --target is specified, assume caller knows what they're doing
|
|
|
|
// and don't mess with include paths for them
|
2016-12-21 16:09:09 -08:00
|
|
|
let has_target_arg = options.clang_args
|
|
|
|
.iter()
|
2016-12-11 15:38:53 +01:00
|
|
|
.rposition(|arg| arg.starts_with("--target"))
|
|
|
|
.is_some();
|
|
|
|
if !has_target_arg {
|
|
|
|
// TODO: distinguish C and C++ paths? C++'s should be enough, I
|
|
|
|
// guess.
|
2017-05-08 12:46:09 -04:00
|
|
|
if let Some(cpp_search_paths) = clang.cpp_search_paths {
|
|
|
|
for path in cpp_search_paths.into_iter() {
|
|
|
|
if let Ok(path) = path.into_os_string().into_string() {
|
|
|
|
options.clang_args.push("-isystem".to_owned());
|
|
|
|
options.clang_args.push(path);
|
|
|
|
}
|
2016-12-11 15:38:53 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-11 09:46:49 +01:00
|
|
|
if let Some(h) = options.input_header.as_ref() {
|
|
|
|
options.clang_args.push(h.clone())
|
|
|
|
}
|
|
|
|
|
2017-03-27 13:02:33 -04:00
|
|
|
for f in options.input_unsaved_files.iter() {
|
|
|
|
options.clang_args.push(f.name.to_str().unwrap().to_owned())
|
|
|
|
}
|
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
let mut context = BindgenContext::new(options);
|
2016-12-10 18:19:25 -10:00
|
|
|
try!(parse(&mut context));
|
2014-12-23 20:46:13 +01:00
|
|
|
|
|
|
|
let module = ast::Mod {
|
|
|
|
inner: span,
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
items: codegen::codegen(&mut context),
|
2014-12-23 20:46:13 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
Ok(Bindings {
|
2016-10-31 16:29:02 -07:00
|
|
|
context: context,
|
2016-04-03 01:03:06 +02:00
|
|
|
module: module,
|
2014-12-23 20:46:13 +01:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Convert these bindings into a Rust AST.
|
2014-12-23 20:46:13 +01:00
|
|
|
pub fn into_ast(self) -> Vec<P<ast::Item>> {
|
|
|
|
self.module.items
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Convert these bindings into source text (with raw lines prepended).
|
2014-12-23 20:46:13 +01:00
|
|
|
pub fn to_string(&self) -> String {
|
2016-04-14 14:34:16 +02:00
|
|
|
let mut mod_str = vec![];
|
2015-05-03 11:40:47 +01:00
|
|
|
{
|
|
|
|
let ref_writer = Box::new(mod_str.by_ref()) as Box<Write>;
|
2016-01-15 02:24:03 +01:00
|
|
|
self.write(ref_writer).expect("Could not write bindings to string");
|
2015-05-03 11:40:47 +01:00
|
|
|
}
|
|
|
|
String::from_utf8(mod_str).unwrap()
|
2014-12-23 20:46:13 +01:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Write these bindings as source text to a file.
|
2015-05-06 12:27:56 +01:00
|
|
|
pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
|
2016-11-01 12:56:14 +01:00
|
|
|
let file = try!(OpenOptions::new()
|
|
|
|
.write(true)
|
|
|
|
.truncate(true)
|
|
|
|
.create(true)
|
|
|
|
.open(path));
|
2015-05-06 12:27:56 +01:00
|
|
|
self.write(Box::new(file))
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Write these bindings as source text to the given `Write`able.
|
2016-01-15 02:24:03 +01:00
|
|
|
pub fn write<'a>(&self, mut writer: Box<Write + 'a>) -> io::Result<()> {
|
2016-11-01 12:56:14 +01:00
|
|
|
try!(writer.write("/* automatically generated by rust-bindgen */\n\n"
|
|
|
|
.as_bytes()));
|
2016-04-03 01:03:06 +02:00
|
|
|
|
2016-10-31 16:29:02 -07:00
|
|
|
for line in self.context.options().raw_lines.iter() {
|
2016-04-03 01:03:06 +02:00
|
|
|
try!(writer.write(line.as_bytes()));
|
2016-04-16 04:08:52 +02:00
|
|
|
try!(writer.write("\n".as_bytes()));
|
2016-04-03 01:03:06 +02:00
|
|
|
}
|
2016-10-31 16:29:02 -07:00
|
|
|
if !self.context.options().raw_lines.is_empty() {
|
2016-04-16 04:08:52 +02:00
|
|
|
try!(writer.write("\n".as_bytes()));
|
2016-04-03 01:03:06 +02:00
|
|
|
}
|
|
|
|
|
2014-12-23 20:46:13 +01:00
|
|
|
let mut ps = pprust::rust_printer(writer);
|
|
|
|
try!(ps.print_mod(&self.module, &[]));
|
|
|
|
try!(ps.print_remaining_comments());
|
|
|
|
try!(eof(&mut ps.s));
|
|
|
|
ps.s.out.flush()
|
|
|
|
}
|
2016-10-31 16:29:02 -07:00
|
|
|
|
|
|
|
/// Generate and write dummy uses of all the types we parsed, if we've been
|
|
|
|
/// requested to do so in the options.
|
|
|
|
///
|
|
|
|
/// See the `uses` module for more information.
|
|
|
|
pub fn write_dummy_uses(&mut self) -> io::Result<()> {
|
2017-02-03 10:03:23 -08:00
|
|
|
let file = if let Some(ref dummy_path) =
|
|
|
|
self.context.options().dummy_uses {
|
|
|
|
Some(try!(OpenOptions::new()
|
2016-12-22 12:46:27 +01:00
|
|
|
.write(true)
|
|
|
|
.truncate(true)
|
|
|
|
.create(true)
|
|
|
|
.open(dummy_path)))
|
2017-02-03 10:03:23 -08:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
2016-10-31 16:29:02 -07:00
|
|
|
|
|
|
|
if let Some(file) = file {
|
|
|
|
try!(uses::generate_dummy_uses(&mut self.context, file));
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2014-12-23 20:46:13 +01:00
|
|
|
}
|
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
/// Determines whether the given cursor is in any of the files matched by the
|
|
|
|
/// options.
|
|
|
|
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
|
2017-03-09 01:10:49 +01:00
|
|
|
ctx.options().builtins || !cursor.is_builtin()
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Parse one `Item` from the Clang cursor.
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
pub fn parse_one(ctx: &mut BindgenContext,
|
|
|
|
cursor: clang::Cursor,
|
2016-11-22 20:01:29 +01:00
|
|
|
parent: Option<ItemId>)
|
2016-12-13 16:35:28 +01:00
|
|
|
-> clang_sys::CXChildVisitResult {
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
if !filter_builtins(ctx, &cursor) {
|
2016-11-01 12:56:14 +01:00
|
|
|
return CXChildVisit_Continue;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
2016-12-13 16:35:28 +01:00
|
|
|
use clang_sys::CXChildVisit_Continue;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
match Item::parse(cursor, parent, ctx) {
|
2016-12-21 16:09:09 -08:00
|
|
|
Ok(..) => {}
|
2016-11-01 12:56:14 +01:00
|
|
|
Err(ParseError::Continue) => {}
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
Err(ParseError::Recurse) => {
|
2016-11-22 20:01:29 +01:00
|
|
|
cursor.visit(|child| parse_one(ctx, child, parent));
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CXChildVisit_Continue
|
|
|
|
}
|
|
|
|
|
2016-10-24 14:13:13 -07:00
|
|
|
/// Parse the Clang AST into our `Item` internal representation.
|
2016-12-10 18:19:25 -10:00
|
|
|
fn parse(context: &mut BindgenContext) -> Result<(), ()> {
|
2016-12-13 16:35:28 +01:00
|
|
|
use clang_sys::*;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
|
2016-12-10 18:19:25 -10:00
|
|
|
let mut any_error = false;
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
for d in context.translation_unit().diags().iter() {
|
2016-12-13 16:35:28 +01:00
|
|
|
let msg = d.format();
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
let is_err = d.severity() >= CXDiagnostic_Error;
|
|
|
|
println!("{}, err: {}", msg, is_err);
|
2016-12-10 18:19:25 -10:00
|
|
|
any_error |= is_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if any_error {
|
|
|
|
return Err(());
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
let cursor = context.translation_unit().cursor();
|
2017-03-30 12:26:02 +02:00
|
|
|
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
if context.options().emit_ast {
|
2017-03-30 12:26:02 +02:00
|
|
|
|
|
|
|
fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
|
|
|
|
if !cur.is_builtin() {
|
|
|
|
clang::ast_dump(&cur, 0)
|
|
|
|
} else {
|
|
|
|
CXChildVisit_Continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cursor.visit(|cur| dump_if_not_builtin(&cur));
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
let root = context.root_module();
|
2016-11-22 20:01:29 +01:00
|
|
|
context.with_module(root, |context| {
|
|
|
|
cursor.visit(|cursor| parse_one(context, cursor, None))
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
});
|
|
|
|
|
|
|
|
assert!(context.current_module() == context.root_module(),
|
|
|
|
"How did this happen?");
|
2016-12-10 18:19:25 -10:00
|
|
|
Ok(())
|
Rewrite the core of the binding generator.
TL;DR: The binding generator is a mess as of right now. At first it was funny
(in a "this is challenging" sense) to improve on it, but this is not
sustainable.
The truth is that the current architecture of the binding generator is a huge
pile of hacks, so these few days I've been working on rewriting it with a few
goals.
1) Have the hacks as contained and identified as possible. They're sometimes
needed because how clang exposes the AST, but ideally those hacks are well
identified and don't interact randomly with each others.
As an example, in the current bindgen when scanning the parameters of a
function that references a struct clones all the struct information, then if
the struct name changes (because we mangle it), everything breaks.
2) Support extending the bindgen output without having to deal with clang. The
way I'm aiming to do this is separating completely the parsing stage from
the code generation one, and providing a single id for each item the binding
generator provides.
3) No more random mutation of the internal representation from anywhere. That
means no more Rc<RefCell<T>>, no more random circular references, no more
borrow_state... nothing.
4) No more deduplication of declarations before code generation.
Current bindgen has a stage, called `tag_dup_decl`[1], that takes care of
deduplicating declarations. That's completely buggy, and for C++ it's a
complete mess, since we YOLO modify the world.
I've managed to take rid of this using the clang canonical declaration, and
the definition, to avoid scanning any type/item twice.
5) Code generation should not modify any internal data structure. It can lookup
things, traverse whatever it needs, but not modifying randomly.
6) Each item should have a canonical name, and a single source of mangling
logic, and that should be computed from the inmutable state, at code
generation.
I've put a few canonical_name stuff in the code generation phase, but it's
still not complete, and should change if I implement namespaces.
Improvements pending until this can land:
1) Add support for missing core stuff, mainly generating functions (note that
we parse the signatures for types correctly though), bitfields, generating
C++ methods.
2) Add support for the necessary features that were added to work around some
C++ pitfalls, like opaque types, etc...
3) Add support for the sugar that Manish added recently.
4) Optionally (and I guess this can land without it, because basically nobody
uses it since it's so buggy), bring back namespace support.
These are not completely trivial, but I think I can do them quite easily with
the current architecture.
I'm putting the current state of affairs here as a request for comments... Any
thoughts? Note that there are still a few smells I want to eventually
re-redesign, like the ParseError::Recurse thing, but until that happens I'm
way happier with this kind of architecture.
I'm keeping the old `parser.rs` and `gen.rs` in tree just for reference while I
code, but they will go away.
[1]: https://github.com/Yamakaky/rust-bindgen/blob/master/src/gen.rs#L448
2016-08-20 22:32:16 -07:00
|
|
|
}
|
2016-11-01 17:10:55 -05:00
|
|
|
|
2016-11-01 23:31:42 -05:00
|
|
|
/// Extracted Clang version data
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ClangVersion {
|
2016-11-03 13:28:33 -05:00
|
|
|
/// Major and minor semvar, if parsing was successful
|
2016-11-04 16:34:36 +01:00
|
|
|
pub parsed: Option<(u32, u32)>,
|
2016-11-01 23:31:42 -05:00
|
|
|
/// full version string
|
|
|
|
pub full: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Get the major and the minor semvar numbers of Clang's version
|
2016-11-03 13:28:33 -05:00
|
|
|
pub fn clang_version() -> ClangVersion {
|
2016-12-13 18:18:00 +01:00
|
|
|
if !clang_sys::is_loaded() {
|
|
|
|
// TODO(emilio): Return meaningful error (breaking).
|
|
|
|
clang_sys::load().expect("Unable to find libclang");
|
|
|
|
}
|
|
|
|
|
2016-11-03 13:28:33 -05:00
|
|
|
let raw_v: String = clang::extract_clang_version();
|
2016-11-04 16:34:36 +01:00
|
|
|
let split_v: Option<Vec<&str>> = raw_v.split_whitespace()
|
2016-11-03 13:28:33 -05:00
|
|
|
.nth(2)
|
|
|
|
.map(|v| v.split('.').collect());
|
|
|
|
match split_v {
|
|
|
|
Some(v) => {
|
|
|
|
if v.len() >= 2 {
|
|
|
|
let maybe_major = v[0].parse::<u32>();
|
|
|
|
let maybe_minor = v[1].parse::<u32>();
|
2016-11-04 16:34:36 +01:00
|
|
|
match (maybe_major, maybe_minor) {
|
|
|
|
(Ok(major), Ok(minor)) => {
|
|
|
|
return ClangVersion {
|
|
|
|
parsed: Some((major, minor)),
|
|
|
|
full: raw_v.clone(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
2016-11-03 13:28:33 -05:00
|
|
|
}
|
|
|
|
}
|
2016-11-04 16:34:36 +01:00
|
|
|
}
|
|
|
|
None => {}
|
2016-11-01 23:31:42 -05:00
|
|
|
};
|
2016-11-04 16:34:36 +01:00
|
|
|
ClangVersion {
|
|
|
|
parsed: None,
|
|
|
|
full: raw_v.clone(),
|
|
|
|
}
|
2016-11-01 17:10:55 -05:00
|
|
|
}
|
2017-04-13 08:15:11 +05:45
|
|
|
|
|
|
|
/// Test command_line_flag function.
|
|
|
|
#[test]
|
|
|
|
fn commandline_flag_unit_test_function() {
|
|
|
|
//Test 1
|
|
|
|
let bindings = ::builder();
|
|
|
|
let command_line_flags = bindings.command_line_flags();
|
|
|
|
|
|
|
|
let test_cases = vec!["--no-derive-default",
|
|
|
|
"--generate", "function,types,vars,methods,constructors,destructors"]
|
|
|
|
.iter()
|
|
|
|
.map(|&x| x.into())
|
|
|
|
.collect::<Vec<String>>();
|
|
|
|
|
|
|
|
assert!(test_cases.iter().all(|ref x| command_line_flags.contains(x)) );
|
|
|
|
|
2017-04-14 14:37:09 -07:00
|
|
|
//Test 2
|
2017-04-13 08:15:11 +05:45
|
|
|
let bindings = ::builder().header("input_header")
|
|
|
|
.whitelisted_type("Distinct_Type")
|
|
|
|
.whitelisted_function("safe_function");
|
|
|
|
|
|
|
|
let command_line_flags = bindings.command_line_flags();
|
|
|
|
let test_cases = vec!["input_header",
|
|
|
|
"--no-derive-default",
|
|
|
|
"--generate", "function,types,vars,methods,constructors,destructors",
|
|
|
|
"--whitelist-type", "Distinct_Type",
|
|
|
|
"--whitelist-function", "safe_function"]
|
|
|
|
.iter()
|
|
|
|
.map(|&x| x.into())
|
|
|
|
.collect::<Vec<String>>();
|
|
|
|
println!("{:?}", command_line_flags);
|
|
|
|
|
|
|
|
assert!(test_cases.iter().all(|ref x| command_line_flags.contains(x)) );
|
|
|
|
|
2017-04-14 12:37:44 +01:00
|
|
|
}
|