From 8142eed2f610596b55d23cb8812176c12eec9da8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 22 Sep 2016 02:36:04 +0200 Subject: [PATCH 1/4] Put our dependencies in shape. --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 883e40df81..cd32574bbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ doc = false name = "bindgen" [build-dependencies] -quasi_codegen = "0.15" +quasi_codegen = "0.20" [dependencies] clang-sys = "0.8.0" @@ -27,12 +27,12 @@ libc = "0.2" log = "0.3" env_logger = "0.3" rustc-serialize = "0.3.19" -syntex_syntax = "0.43" +syntex_syntax = "0.44" regex = "0.1" [dependencies.aster] features = ["with-syntex"] -version = "0.26" +version = "0.28" [dependencies.clippy] optional = true @@ -40,7 +40,7 @@ version = "*" [dependencies.quasi] features = ["with-syntex"] -version = "0.19" +version = "0.20" [features] llvm_stable = [] From c41a1c28ef54fbc3a61d56777696860aae2c23c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 22 Sep 2016 02:39:14 +0200 Subject: [PATCH 2/4] Union support. --- src/codegen/mod.rs | 26 ++++++++++++++--------- src/ir/comp.rs | 52 ++++++++++++++++++++++++++++++++-------------- src/ir/context.rs | 2 +- src/ir/item.rs | 8 +++++++ src/ir/ty.rs | 14 ++++++------- 5 files changed, 68 insertions(+), 34 deletions(-) diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 36f20689ec..d95364a2bc 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -546,13 +546,14 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::repr("C")); } + let is_union = self.kind() == CompKind::Union; let mut derives = vec![]; let ty = item.expect_type(); if ty.can_derive_debug(ctx) { derives.push("Debug"); } - if ty.can_derive_copy(ctx) && !item.annotations().disallow_copy() { + if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() { derives.push("Copy"); if !applicable_template_args.is_empty() { // FIXME: This requires extra logic if you have a big array in a @@ -573,9 +574,15 @@ impl CodeGenerator for CompInfo { let mut template_args_used = vec![false; applicable_template_args.len()]; let canonical_name = item.canonical_name(ctx); - let builder = aster::AstBuilder::new().item().pub_() - .with_attrs(attributes) - .struct_(&canonical_name); + let builder = if is_union && ctx.options().unstable_rust { + aster::AstBuilder::new().item().pub_() + .with_attrs(attributes) + .union_(&canonical_name) + } else { + aster::AstBuilder::new().item().pub_() + .with_attrs(attributes) + .struct_(&canonical_name) + }; // Generate the vtable from the method list if appropriate. // TODO: I don't know how this could play with virtual methods that are @@ -633,8 +640,6 @@ impl CodeGenerator for CompInfo { .pub_().build_ty(inner); fields.push(field); } - - let is_union = self.kind() == CompKind::Union; if is_union { result.saw_union(); } @@ -705,7 +710,8 @@ impl CodeGenerator for CompInfo { let ty = field.ty().to_rust_ty(ctx); - let ty = if is_union { + // NB: In unstable rust we use proper `union` types. + let ty = if is_union && !ctx.options().unstable_rust { quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>) } else { ty @@ -817,7 +823,7 @@ impl CodeGenerator for CompInfo { } debug_assert!(current_bitfield_fields.is_empty()); - if is_union { + if is_union && !ctx.options().unstable_rust { let layout = layout.expect("Unable to get layout information?"); let ty = BlobTyBuilder::new(layout).build(); let field = StructFieldBuilder::named("bindgen_union_field").pub_() @@ -1375,7 +1381,7 @@ impl ToRustTy for Type { } None => { warn!("Couldn't compute layout for a type with non \ - template params or opaque, expect dragons!"); + type template params or opaque, expect dragons!"); aster::AstBuilder::new().ty().unit() } } @@ -1756,7 +1762,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec> { } let saw_union = result.saw_union; let mut result = result.items; - if saw_union { + if saw_union && !context.options().unstable_rust { utils::prepend_union_types(context, &mut result); } result diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 1e6bf555f7..d31b7adf12 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -215,6 +215,10 @@ impl CompInfo { } if self.kind == CompKind::Union { + if type_resolver.options().unstable_rust { + return false; + } + let layout = layout.unwrap_or_else(Layout::zero); let size_divisor = cmp::max(1, layout.align); return layout.size / size_divisor <= RUST_DERIVE_IN_ARRAY_LIMIT; @@ -223,6 +227,10 @@ impl CompInfo { self.detect_derive_debug_cycle.set(true); let can_derive_debug = + self.base_members.iter().all(|ty| { + type_resolver.resolve_type(*ty) + .can_derive_debug(type_resolver) + }) && self.template_args.iter().all(|ty| { type_resolver.resolve_type(*ty) .can_derive_debug(type_resolver) @@ -230,6 +238,10 @@ impl CompInfo { self.fields.iter().all(|field| { type_resolver.resolve_type(field.ty) .can_derive_debug(type_resolver) + }) && + self.ref_template.map_or(true, |template| { + type_resolver.resolve_type(template) + .can_derive_debug(type_resolver) }); self.detect_derive_debug_cycle.set(false); @@ -287,7 +299,7 @@ impl CompInfo { has_destructor } - pub fn can_derive_copy(&self, type_resolver: &TypeResolver) -> bool { + pub fn can_derive_copy(&self, type_resolver: &TypeResolver, item: &Item) -> bool { // NOTE: Take into account that while unions in C and C++ are copied by // default, the may have an explicit destructor in C++, so we can't // defer this check just for the union case. @@ -295,23 +307,31 @@ impl CompInfo { return false; } - match self.kind { - CompKind::Union => true, - CompKind::Struct => { - // With template args, use a safe subset of the types, - // since copyability depends on the types itself. - self.ref_template.as_ref().map_or(true, |t| { - type_resolver.resolve_type(*t).can_derive_copy(type_resolver) - }) && - self.base_members.iter().all(|t| { - type_resolver.resolve_type(*t).can_derive_copy(type_resolver) - }) && - self.fields.iter().all(|field| { - type_resolver.resolve_type(field.ty) - .can_derive_copy(type_resolver) - }) + if self.kind == CompKind::Union { + if !type_resolver.options().unstable_rust { + return true; + } + + // https://github.com/rust-lang/rust/issues/36640 + if !self.template_args.is_empty() || + self.ref_template.is_some() || + !item.applicable_template_args(type_resolver).is_empty() { + return false; } } + + // With template args, use a safe subset of the types, + // since copyability depends on the types itself. + self.ref_template.as_ref().map_or(true, |t| { + type_resolver.resolve_item(*t).can_derive_copy(type_resolver) + }) && + self.base_members.iter().all(|t| { + type_resolver.resolve_item(*t).can_derive_copy(type_resolver) + }) && + self.fields.iter().all(|field| { + type_resolver.resolve_item(field.ty) + .can_derive_copy(type_resolver) + }) } pub fn is_template_specialization(&self) -> bool { diff --git a/src/ir/context.rs b/src/ir/context.rs index 559dd2bacc..4842eb94c7 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -333,7 +333,7 @@ impl<'ctx> BindgenContext<'ctx> { let cfg = ExpansionConfig::default("xxx".to_owned()); let sess = parse::ParseSess::new(); - let mut loader = base::DummyMacroLoader; + let mut loader = base::DummyResolver; let mut ctx = GenContext(base::ExtCtxt::new(&sess, vec![], cfg, &mut loader)); diff --git a/src/ir/item.rs b/src/ir/item.rs index 75c3b857e5..80085c8b5a 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -338,6 +338,14 @@ impl Item { _ => None, } } + + pub fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { + self.expect_type().can_derive_copy(ctx, self) + } + + pub fn can_derive_copy_in_array(&self, ctx: &BindgenContext) -> bool { + self.expect_type().can_derive_copy_in_array(ctx, self) + } } impl ClangItemParser for Item { diff --git a/src/ir/ty.rs b/src/ir/ty.rs index 97cdf9255d..74452243f6 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -175,32 +175,32 @@ impl Type { // is an error. // // That's the point of the existence of can_derive_copy_in_array(). - pub fn can_derive_copy_in_array(&self, type_resolver: &TypeResolver) -> bool { + pub fn can_derive_copy_in_array(&self, type_resolver: &TypeResolver, item: &Item) -> bool { match self.kind { TypeKind::ResolvedTypeRef(t) | TypeKind::Alias(_, t) | TypeKind::Array(t, _) => { - type_resolver.resolve_type(t) + type_resolver.resolve_item(t) .can_derive_copy_in_array(type_resolver) } TypeKind::Named(..) => false, - _ => self.can_derive_copy(type_resolver), + _ => self.can_derive_copy(type_resolver, item), } } - pub fn can_derive_copy(&self, type_resolver: &TypeResolver) -> bool { + pub fn can_derive_copy(&self, type_resolver: &TypeResolver, item: &Item) -> bool { !self.is_opaque(type_resolver) && match self.kind { TypeKind::Array(t, len) => { len <= RUST_DERIVE_IN_ARRAY_LIMIT && - type_resolver.resolve_type(t).can_derive_copy_in_array(type_resolver) + type_resolver.resolve_item(t).can_derive_copy_in_array(type_resolver) } TypeKind::ResolvedTypeRef(t) | TypeKind::TemplateRef(t, _) | TypeKind::Alias(_, t) => { - type_resolver.resolve_type(t).can_derive_copy(type_resolver) + type_resolver.resolve_item(t).can_derive_copy(type_resolver) } TypeKind::Comp(ref info) => { - info.can_derive_copy(type_resolver) + info.can_derive_copy(type_resolver, item) } _ => true, } From 2916beaf1d6115b80902b847cd786f81dd14208c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 22 Sep 2016 02:41:26 +0200 Subject: [PATCH 3/4] Use the upstreamed version of the array builder. --- src/codegen/helpers.rs | 42 +----------------------------------------- src/codegen/mod.rs | 6 +++--- 2 files changed, 4 insertions(+), 44 deletions(-) diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index e2fc11201a..e82d5c59de 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -3,7 +3,6 @@ use aster; use ir::layout::Layout; use syntax::ast; -use syntax::codemap::respan; use syntax::ptr::P; @@ -68,46 +67,7 @@ impl BlobTyBuilder { if data_len == 1 { inner_ty } else { - ArrayTyBuilder::new().with_len(data_len).build(inner_ty) + aster::ty::TyBuilder::new().array(data_len).build(inner_ty) } } } - -pub struct ArrayTyBuilder { - len: usize, -} - -impl ArrayTyBuilder { - pub fn new() -> Self { - ArrayTyBuilder { - len: 0, - } - } - - pub fn with_len(mut self, len: usize) -> Self { - self.len = len; - self - } - - pub fn build(self, ty: P) -> P { - use syntax::codemap::DUMMY_SP; - let size = - ast::LitKind::Int(self.len as u64, - ast::LitIntType::Unsigned(ast::UintTy::Us)); - let size = ast::ExprKind::Lit(P(respan(DUMMY_SP, size))); - let array_kind = ast::TyKind::FixedLengthVec(ty, - P(ast::Expr { - id: ast::DUMMY_NODE_ID, - node: size, - span: DUMMY_SP, - attrs: ast::ThinVec::new(), - }) - ); - - P(ast::Ty { - id: ast::DUMMY_NODE_ID, - node: array_kind, - span: DUMMY_SP, - }) - } -} diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index d95364a2bc..7350bb4920 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1,6 +1,6 @@ mod helpers; -use self::helpers::{attributes, ArrayTyBuilder, BlobTyBuilder}; +use self::helpers::{attributes, BlobTyBuilder}; use ir::context::BindgenContext; use ir::item::{Item, ItemId, ItemCanonicalName, ItemCanonicalPath}; @@ -1317,7 +1317,7 @@ impl ToRustTy for Type { // can't do better right now. We should be able to use // i128/u128 when they're available. IntKind::U128 | - IntKind::I128 => ArrayTyBuilder::new().with_len(2).build(aster::ty::TyBuilder::new().u64()), + IntKind::I128 => aster::ty::TyBuilder::new().array(2).u64(), } } TypeKind::Float(fk) => { @@ -1336,7 +1336,7 @@ impl ToRustTy for Type { } TypeKind::Array(item, len) => { let inner = item.to_rust_ty(ctx); - ArrayTyBuilder::new().with_len(len).build(inner) + aster::ty::TyBuilder::new().array(len).build(inner) } TypeKind::Enum(..) => { let path = item.canonical_path(ctx); From 9e1ddf9632ed4ffb04b49e7d317d15b32de6225c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 22 Sep 2016 03:37:53 +0200 Subject: [PATCH 4/4] Run tests on stable. --- tests/tools/run-bindgen.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/tools/run-bindgen.py b/tests/tools/run-bindgen.py index d58a028a48..0d8ed580bb 100755 --- a/tests/tools/run-bindgen.py +++ b/tests/tools/run-bindgen.py @@ -17,12 +17,12 @@ [_, bindgen_path, c_path, rust_path] = sys.argv -flags = [] +flags = ["--no-unstable-rust"] with open(sys.argv[2]) as f: for line in f: if line.startswith(BINDGEN_FLAGS_PREFIX): - flags = line.strip().split(BINDGEN_FLAGS_PREFIX)[1].split(" ") + flags.extend(line.strip().split(BINDGEN_FLAGS_PREFIX)[1].split(" ")) break base_command = [bindgen_path, "-o", rust_path]