diff options
21 files changed, 195 insertions, 57 deletions
diff --git a/bindgen-integration/cpp/Test.h b/bindgen-integration/cpp/Test.h index 21f6d1a7..ebd58649 100644 --- a/bindgen-integration/cpp/Test.h +++ b/bindgen-integration/cpp/Test.h @@ -8,3 +8,5 @@ public: Test(int foo); Test(double foo); }; + +typedef Test TypeAlias; diff --git a/libbindgen/Cargo.toml b/libbindgen/Cargo.toml index 0ff11a24..2615b822 100644 --- a/libbindgen/Cargo.toml +++ b/libbindgen/Cargo.toml @@ -29,12 +29,12 @@ cfg-if = "0.1.0" clang-sys = { version = "0.12", features = ["runtime", "clang_3_9"] } lazy_static = "0.2.1" rustc-serialize = "0.3.19" -syntex_syntax = "0.50" +syntex_syntax = "0.54" regex = "0.2" [dependencies.aster] features = ["with-syntex"] -version = "0.34" +version = "0.38" [dependencies.env_logger] optional = true @@ -46,7 +46,7 @@ version = "0.3" [dependencies.quasi] features = ["with-syntex"] -version = "0.26" +version = "0.29" [features] assert_no_dangling_items = [] diff --git a/libbindgen/src/codegen/helpers.rs b/libbindgen/src/codegen/helpers.rs index c09f0071..b4cc75f5 100644 --- a/libbindgen/src/codegen/helpers.rs +++ b/libbindgen/src/codegen/helpers.rs @@ -153,7 +153,7 @@ pub mod ast_ty { } pub fn float_expr(f: f64) -> P<ast::Expr> { - use aster::str::ToInternedString; + use aster::symbol::ToSymbol; let mut string = f.to_string(); // So it gets properly recognised as a floating point constant. @@ -161,8 +161,7 @@ pub mod ast_ty { string.push('.'); } - let interned_str = string.as_str().to_interned_string(); - let kind = ast::LitKind::FloatUnsuffixed(interned_str); + let kind = ast::LitKind::FloatUnsuffixed(string.as_str().to_symbol()); aster::AstBuilder::new().expr().lit().build_lit(kind) } diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 38cf6958..7451dd11 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -523,22 +523,46 @@ impl CodeGenerator for Type { typedef = typedef.attr().doc(comment); } - let mut generics = typedef.type_(rust_name).generics(); - for template_arg in applicable_template_args.iter() { - let template_arg = ctx.resolve_type(*template_arg); - if template_arg.is_named() { - let name = template_arg.name().unwrap(); - if name.contains("typename ") { - warn!("Item contained `typename`'d template \ - parameter: {:?}", item); - return; + // We prefer using `pub use` over `pub type` because of: + // https://github.com/rust-lang/rust/issues/26264 + let simple_enum_path = match inner_rust_type.node { + ast::TyKind::Path(None, ref p) => { + if applicable_template_args.is_empty() && + !inner_item.expect_type().canonical_type(ctx).is_builtin_or_named() && + p.segments.iter().all(|p| p.parameters.is_none()) { + Some(p.clone()) + } else { + None } - generics = - generics.ty_param_id(template_arg.name().unwrap()); - } - } + }, + _ => None, + }; - let typedef = generics.build().build_ty(inner_rust_type); + let typedef = if let Some(mut p) = simple_enum_path { + if p.segments.len() == 1 { + p.segments.insert(0, ast::PathSegment { + identifier: ctx.ext_cx().ident_of("self"), + parameters: None, + }); + } + typedef.use_().build(p).as_(rust_name) + } else { + let mut generics = typedef.type_(rust_name).generics(); + for template_arg in applicable_template_args.iter() { + let template_arg = ctx.resolve_type(*template_arg); + if template_arg.is_named() { + let name = template_arg.name().unwrap(); + if name.contains("typename ") { + warn!("Item contained `typename`'d template \ + parameter: {:?}", item); + return; + } + generics = + generics.ty_param_id(template_arg.name().unwrap()); + } + } + generics.build().build_ty(inner_rust_type) + }; result.push(typedef) } TypeKind::Enum(ref ei) => { @@ -1869,16 +1893,19 @@ impl ToRustTy for Type { if let ast::TyKind::Path(_, ref mut path) = inner_ty.node { let template_args = template_args.iter() .map(|arg| arg.to_rust_ty(ctx)) - .collect(); + .collect::<Vec<_>>(); - path.segments.last_mut().unwrap().parameters = - ast::PathParameters::AngleBracketed( + path.segments.last_mut().unwrap().parameters = if template_args.is_empty() { + None + } else { + Some(P(ast::PathParameters::AngleBracketed( ast::AngleBracketedParameterData { lifetimes: vec![], types: P::from_vec(template_args), bindings: P::from_vec(vec![]), } - ); + ))) + } } P(inner_ty) diff --git a/libbindgen/src/ir/comp.rs b/libbindgen/src/ir/comp.rs index 70dfd4a6..0d1c653e 100644 --- a/libbindgen/src/ir/comp.rs +++ b/libbindgen/src/ir/comp.rs @@ -652,29 +652,6 @@ impl CompInfo { ci.has_destructor |= cur.kind() == CXCursor_Destructor; ci.has_vtable |= is_virtual; - let linkage = cur.linkage(); - if linkage != CXLinkage_External { - return CXChildVisit_Continue; - } - - if cur.access_specifier() == CX_CXXPrivate { - return CXChildVisit_Continue; - } - - let visibility = cur.visibility(); - if visibility != CXVisibility_Default { - return CXChildVisit_Continue; - } - - if cur.is_inlined_function() { - return CXChildVisit_Continue; - } - - let spelling = cur.spelling(); - if spelling.starts_with("operator") { - return CXChildVisit_Continue; - } - // This used to not be here, but then I tried generating // stylo bindings with this (without path filters), and // cried a lot with a method in gfx/Point.h @@ -691,8 +668,10 @@ impl CompInfo { // NB: This gets us an owned `Function`, not a // `FunctionSig`. - let signature = Item::parse(cur, Some(potential_id), ctx) - .expect("CXXMethod"); + let signature = match Item::parse(cur, Some(potential_id), ctx) { + Ok(item) if ctx.resolve_item(item).kind().is_function() => item, + _ => return CXChildVisit_Continue, + }; match cur.kind() { CXCursor_Constructor => { @@ -971,6 +950,10 @@ impl TypeCollector for CompInfo { types.insert(ty); } + for &var in self.inner_vars() { + types.insert(var); + } + // FIXME(emilio): Methods, VTable? } } diff --git a/libbindgen/src/ir/context.rs b/libbindgen/src/ir/context.rs index c3de2ca8..b0143bd5 100644 --- a/libbindgen/src/ir/context.rs +++ b/libbindgen/src/ir/context.rs @@ -461,6 +461,7 @@ impl<'ctx> BindgenContext<'ctx> { pub fn gen<F, Out>(&mut self, cb: F) -> Out where F: FnOnce(&Self) -> Out, { + use aster::symbol::ToSymbol; use syntax::ext::expand::ExpansionConfig; use syntax::codemap::{ExpnInfo, MacroBang, NameAndSpan}; use syntax::ext::base; @@ -475,7 +476,7 @@ impl<'ctx> BindgenContext<'ctx> { ctx.0.bt_push(ExpnInfo { call_site: self.span, callee: NameAndSpan { - format: MacroBang(parse::token::intern("")), + format: MacroBang("".to_symbol()), allow_internal_unstable: false, span: None, }, @@ -1255,8 +1256,9 @@ impl<'ctx, 'gen> Iterator for AssertNoDanglingItemIter<'ctx, 'gen> } for sub_id in sub_types { - if let Some(value) = self.seen.insert(id, sub_id) { - self.to_iterate.push_back(value); + if self.seen.insert(sub_id, id).is_none() { + // We've never visited this sub item before. + self.to_iterate.push_back(sub_id); } } diff --git a/libbindgen/src/ir/function.rs b/libbindgen/src/ir/function.rs index 88ab861d..50c442db 100644 --- a/libbindgen/src/ir/function.rs +++ b/libbindgen/src/ir/function.rs @@ -150,6 +150,7 @@ impl FunctionSig { } else { ty.declaration() }; + let mut args: Vec<_> = match cursor.kind() { CXCursor_FunctionDecl | CXCursor_Constructor | @@ -262,6 +263,24 @@ impl ClangSubItemParser for Function { debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type()); + let visibility = cursor.visibility(); + if visibility != CXVisibility_Default { + return Err(ParseError::Continue); + } + + if cursor.access_specifier() == CX_CXXPrivate { + return Err(ParseError::Continue); + } + + if cursor.is_inlined_function() { + return Err(ParseError::Continue); + } + + let linkage = cursor.linkage(); + if linkage != CXLinkage_External && linkage != CXLinkage_UniqueExternal { + return Err(ParseError::Continue); + } + // Grab the signature using Item::from_ty. let sig = try!(Item::from_ty(&cursor.cur_type(), Some(cursor), diff --git a/libbindgen/src/ir/item.rs b/libbindgen/src/ir/item.rs index 3810bc2f..df8fd222 100644 --- a/libbindgen/src/ir/item.rs +++ b/libbindgen/src/ir/item.rs @@ -202,6 +202,9 @@ impl TypeCollector for Item { // be opaque, so we trace across it. types.insert(fun.signature()); } + ItemKind::Var(ref var) => { + types.insert(var.ty()); + } _ => {} // FIXME. } } diff --git a/libbindgen/src/ir/ty.rs b/libbindgen/src/ir/ty.rs index e83ef4fd..c1ed5b64 100644 --- a/libbindgen/src/ir/ty.rs +++ b/libbindgen/src/ir/ty.rs @@ -123,6 +123,14 @@ impl Type { } } + /// Is this an enum type? + pub fn is_enum(&self) -> bool { + match self.kind { + TypeKind::Enum(..) => true, + _ => false, + } + } + /// Is this either a builtin or named type? pub fn is_builtin_or_named(&self) -> bool { match self.kind { diff --git a/libbindgen/tests/expectations/tests/anon_enum.rs b/libbindgen/tests/expectations/tests/anon_enum.rs index 075830e6..3b05eab8 100644 --- a/libbindgen/tests/expectations/tests/anon_enum.rs +++ b/libbindgen/tests/expectations/tests/anon_enum.rs @@ -22,3 +22,9 @@ fn bindgen_test_layout_Test() { impl Clone for Test { fn clone(&self) -> Self { *self } } +pub const Foo: _bindgen_ty_1 = _bindgen_ty_1::Foo; +pub const Bar: _bindgen_ty_1 = _bindgen_ty_1::Bar; +#[repr(u32)] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum _bindgen_ty_1 { Foo = 0, Bar = 1, } +pub use self::_bindgen_ty_1 as Baz; diff --git a/libbindgen/tests/expectations/tests/bitfield_method_mangling.rs b/libbindgen/tests/expectations/tests/bitfield_method_mangling.rs index 5aba8abb..b650a38f 100644 --- a/libbindgen/tests/expectations/tests/bitfield_method_mangling.rs +++ b/libbindgen/tests/expectations/tests/bitfield_method_mangling.rs @@ -46,4 +46,4 @@ impl _bindgen_ty_1 { ((val as u32 as u32) << 24u32) & (4278190080usize as u32); } } -pub type mach_msg_type_descriptor_t = _bindgen_ty_1; +pub use self::_bindgen_ty_1 as mach_msg_type_descriptor_t; diff --git a/libbindgen/tests/expectations/tests/inherit_typedef.rs b/libbindgen/tests/expectations/tests/inherit_typedef.rs index ca9041e2..2b974223 100644 --- a/libbindgen/tests/expectations/tests/inherit_typedef.rs +++ b/libbindgen/tests/expectations/tests/inherit_typedef.rs @@ -17,7 +17,7 @@ fn bindgen_test_layout_Foo() { impl Clone for Foo { fn clone(&self) -> Self { *self } } -pub type TypedefedFoo = Foo; +pub use self::Foo as TypedefedFoo; #[repr(C)] #[derive(Debug, Copy)] pub struct Bar { diff --git a/libbindgen/tests/expectations/tests/inline-function.rs b/libbindgen/tests/expectations/tests/inline-function.rs new file mode 100644 index 00000000..b4b7b2bc --- /dev/null +++ b/libbindgen/tests/expectations/tests/inline-function.rs @@ -0,0 +1,7 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + + diff --git a/libbindgen/tests/expectations/tests/namespace.rs b/libbindgen/tests/expectations/tests/namespace.rs index 3d6e5974..ece4e341 100644 --- a/libbindgen/tests/expectations/tests/namespace.rs +++ b/libbindgen/tests/expectations/tests/namespace.rs @@ -37,9 +37,22 @@ pub mod root { assert_eq!(::std::mem::size_of::<A>() , 4usize); assert_eq!(::std::mem::align_of::<A>() , 4usize); } + extern "C" { + #[link_name = "_ZN12_GLOBAL__N_11A20lets_hope_this_worksEv"] + pub fn A_lets_hope_this_works(this: + *mut root::_bindgen_mod_id_13::A) + -> ::std::os::raw::c_int; + } impl Clone for A { fn clone(&self) -> Self { *self } } + impl A { + #[inline] + pub unsafe fn lets_hope_this_works(&mut self) + -> ::std::os::raw::c_int { + A_lets_hope_this_works(&mut *self) + } + } } #[repr(C)] #[derive(Debug)] diff --git a/libbindgen/tests/expectations/tests/reparented_replacement.rs b/libbindgen/tests/expectations/tests/reparented_replacement.rs index 74ee229c..e8ccc931 100644 --- a/libbindgen/tests/expectations/tests/reparented_replacement.rs +++ b/libbindgen/tests/expectations/tests/reparented_replacement.rs @@ -25,5 +25,5 @@ pub mod root { fn clone(&self) -> Self { *self } } } - pub type ReferencesBar = root::foo::Bar; + pub use root::foo::Bar as ReferencesBar; } diff --git a/libbindgen/tests/expectations/tests/union_fields.rs b/libbindgen/tests/expectations/tests/union_fields.rs index 495e80f9..21d87919 100644 --- a/libbindgen/tests/expectations/tests/union_fields.rs +++ b/libbindgen/tests/expectations/tests/union_fields.rs @@ -44,4 +44,4 @@ fn bindgen_test_layout__bindgen_ty_1() { impl Clone for _bindgen_ty_1 { fn clone(&self) -> Self { *self } } -pub type nsStyleUnion = _bindgen_ty_1; +pub use self::_bindgen_ty_1 as nsStyleUnion; diff --git a/libbindgen/tests/expectations/tests/unknown_attr.rs b/libbindgen/tests/expectations/tests/unknown_attr.rs index fd9cce45..541bee5d 100644 --- a/libbindgen/tests/expectations/tests/unknown_attr.rs +++ b/libbindgen/tests/expectations/tests/unknown_attr.rs @@ -13,4 +13,4 @@ pub struct _bindgen_ty_1 { impl Clone for _bindgen_ty_1 { fn clone(&self) -> Self { *self } } -pub type max_align_t = _bindgen_ty_1; +pub use self::_bindgen_ty_1 as max_align_t; diff --git a/libbindgen/tests/expectations/tests/var-tracing.rs b/libbindgen/tests/expectations/tests/var-tracing.rs new file mode 100644 index 00000000..75c5ebe3 --- /dev/null +++ b/libbindgen/tests/expectations/tests/var-tracing.rs @@ -0,0 +1,48 @@ +/* automatically generated by rust-bindgen */ + + +#![allow(non_snake_case)] + + +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Bar { + pub m_baz: ::std::os::raw::c_int, +} +#[test] +fn bindgen_test_layout_Bar() { + assert_eq!(::std::mem::size_of::<Bar>() , 4usize); + assert_eq!(::std::mem::align_of::<Bar>() , 4usize); +} +extern "C" { + #[link_name = "_ZN3BarC1Ei"] + pub fn Bar_Bar(this: *mut Bar, baz: ::std::os::raw::c_int); +} +impl Clone for Bar { + fn clone(&self) -> Self { *self } +} +impl Bar { + #[inline] + pub unsafe fn new(baz: ::std::os::raw::c_int) -> Self { + let mut __bindgen_tmp = ::std::mem::uninitialized(); + Bar_Bar(&mut __bindgen_tmp, baz); + __bindgen_tmp + } +} +#[repr(C)] +#[derive(Debug, Copy)] +pub struct Baz { + pub _address: u8, +} +extern "C" { + #[link_name = "_ZN3Baz3FOOE"] + pub static mut Baz_FOO: *const Bar; +} +#[test] +fn bindgen_test_layout_Baz() { + assert_eq!(::std::mem::size_of::<Baz>() , 1usize); + assert_eq!(::std::mem::align_of::<Baz>() , 1usize); +} +impl Clone for Baz { + fn clone(&self) -> Self { *self } +} diff --git a/libbindgen/tests/headers/anon_enum.hpp b/libbindgen/tests/headers/anon_enum.hpp index c7405202..1961fe6c 100644 --- a/libbindgen/tests/headers/anon_enum.hpp +++ b/libbindgen/tests/headers/anon_enum.hpp @@ -3,3 +3,8 @@ struct Test { float bar; enum { T_NONE }; }; + +typedef enum { + Foo, + Bar, +} Baz; diff --git a/libbindgen/tests/headers/inline-function.h b/libbindgen/tests/headers/inline-function.h new file mode 100644 index 00000000..02cb7c08 --- /dev/null +++ b/libbindgen/tests/headers/inline-function.h @@ -0,0 +1,6 @@ +// bindgen-unstable + +/** The point of this test is to _not_ generate these functions. */ + +inline static int myadd(const int x, const int y) { return x + y; } +static int mysub(const int x, const int y) { return x - y; } diff --git a/libbindgen/tests/headers/var-tracing.hpp b/libbindgen/tests/headers/var-tracing.hpp new file mode 100644 index 00000000..0d0b0cca --- /dev/null +++ b/libbindgen/tests/headers/var-tracing.hpp @@ -0,0 +1,10 @@ +// bindgen-flags: --whitelist-type Baz + +struct Bar { + const int m_baz; + Bar(int baz); +}; + +class Baz { + static const Bar FOO[]; +}; |