From 515ef38574845b0fbac1bea72269b44bd0642b75 Mon Sep 17 00:00:00 2001 From: Artem Biryukov Date: Wed, 16 Nov 2016 17:40:06 +0300 Subject: [PATCH 1/4] First steps to fix issue #57 --- libbindgen/src/codegen/mod.rs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 6c8a36f733..8b54ab007f 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -656,8 +656,30 @@ impl CodeGenerator for CompInfo { // // TODO: Generate layout tests for template specializations, yay! if self.has_non_type_template_params() || - self.is_template_specialization() { - return; + self.is_template_specialization() { + let layout = item.kind().expect_type().layout(ctx); + let canonical_name = item.canonical_name(ctx); + + if let Some(layout) = layout { + let fn_name = format!("bindgen_test_layout_template_{}", canonical_name); + let fn_name = ctx.rust_ident_raw(&fn_name); + let ident = item.to_rust_ty(ctx); + let prefix = ctx.trait_prefix(); + let size_of_expr = quote_expr!(ctx.ext_cx(), + ::$prefix::mem::size_of::<$ident>()); + let align_of_expr = quote_expr!(ctx.ext_cx(), + ::$prefix::mem::align_of::<$ident>()); + let size = layout.size; + let align = layout.align; + let item = quote_item!(ctx.ext_cx(), + #[test] + fn $fn_name() { + assert_eq!($size_of_expr, $size); + assert_eq!($align_of_expr, $align); + }).unwrap(); + result.push(item); + } + return; } let applicable_template_args = item.applicable_template_args(ctx); From bed241ea45ce82a283f9c5cda3f98bd6969e53c2 Mon Sep 17 00:00:00 2001 From: Artem Biryukov Date: Sun, 20 Nov 2016 11:50:23 +0300 Subject: [PATCH 2/4] Take out template arguments and make unique names --- libbindgen/src/codegen/mod.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 8b54ab007f..c99caf9ea3 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -655,13 +655,25 @@ impl CodeGenerator for CompInfo { // also don't output template specializations, neither total or partial. // // TODO: Generate layout tests for template specializations, yay! + + // TODO (imp): I will keep it like that right now and move it to function later if self.has_non_type_template_params() || self.is_template_specialization() { let layout = item.kind().expect_type().layout(ctx); let canonical_name = item.canonical_name(ctx); if let Some(layout) = layout { - let fn_name = format!("bindgen_test_layout_template_{}", canonical_name); + + let mut types = String::new(); + + for arg in self.template_args() { + if let Some(name) = ctx.resolve_type(*arg).name() { + // hope this isn't bad + types.push_str(format!("{}_", name).as_str()); + } + } + + let fn_name = format!("bindgen_test_layout_template_{}_{}", canonical_name, types); let fn_name = ctx.rust_ident_raw(&fn_name); let ident = item.to_rust_ty(ctx); let prefix = ctx.trait_prefix(); From 5ee3601ea9eb953df23b0454f30662f2c154f7a4 Mon Sep 17 00:00:00 2001 From: Artem Biryukov Date: Sun, 20 Nov 2016 12:11:53 +0300 Subject: [PATCH 3/4] Add new expectations for tests --- libbindgen/src/codegen/mod.rs | 4 ++-- libbindgen/tests/expectations/tests/anon_union.rs | 7 +++++++ .../tests/expectations/tests/class_with_dtor.rs | 7 +++++++ libbindgen/tests/expectations/tests/crtp.rs | 12 ++++++++++++ libbindgen/tests/expectations/tests/template.rs | 14 ++++++++++++++ 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index c99caf9ea3..6730a9100c 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -669,11 +669,11 @@ impl CodeGenerator for CompInfo { for arg in self.template_args() { if let Some(name) = ctx.resolve_type(*arg).name() { // hope this isn't bad - types.push_str(format!("{}_", name).as_str()); + types.push_str(format!("_{}", name).as_str()); } } - let fn_name = format!("bindgen_test_layout_template_{}_{}", canonical_name, types); + let fn_name = format!("bindgen_test_layout_template_{}{}", canonical_name, types); let fn_name = ctx.rust_ident_raw(&fn_name); let ident = item.to_rust_ty(ctx); let prefix = ctx.trait_prefix(); diff --git a/libbindgen/tests/expectations/tests/anon_union.rs b/libbindgen/tests/expectations/tests/anon_union.rs index 8af416c32c..2dc206b728 100644 --- a/libbindgen/tests/expectations/tests/anon_union.rs +++ b/libbindgen/tests/expectations/tests/anon_union.rs @@ -75,3 +75,10 @@ fn bindgen_test_layout_ErrorResult() { impl Clone for ErrorResult { fn clone(&self) -> Self { *self } } +#[test] +fn bindgen_test_layout_template_TErrorResult_int() { + assert_eq!(::std::mem::size_of::>() , + 24usize); + assert_eq!(::std::mem::align_of::>() , + 8usize); +} diff --git a/libbindgen/tests/expectations/tests/class_with_dtor.rs b/libbindgen/tests/expectations/tests/class_with_dtor.rs index 8ed1ddf9fe..f09699ca0e 100644 --- a/libbindgen/tests/expectations/tests/class_with_dtor.rs +++ b/libbindgen/tests/expectations/tests/class_with_dtor.rs @@ -20,3 +20,10 @@ fn bindgen_test_layout_WithoutDtor() { assert_eq!(::std::mem::size_of::() , 8usize); assert_eq!(::std::mem::align_of::() , 8usize); } +#[test] +fn bindgen_test_layout_template_HandleWithDtor_int() { + assert_eq!(::std::mem::size_of::>() + , 8usize); + assert_eq!(::std::mem::align_of::>() + , 8usize); +} diff --git a/libbindgen/tests/expectations/tests/crtp.rs b/libbindgen/tests/expectations/tests/crtp.rs index e4a86b2430..3962959916 100644 --- a/libbindgen/tests/expectations/tests/crtp.rs +++ b/libbindgen/tests/expectations/tests/crtp.rs @@ -23,6 +23,11 @@ fn bindgen_test_layout_Derived() { impl Clone for Derived { fn clone(&self) -> Self { *self } } +#[test] +fn bindgen_test_layout_template_Base() { + assert_eq!(::std::mem::size_of::>() , 1usize); + assert_eq!(::std::mem::align_of::>() , 1usize); +} #[repr(C)] #[derive(Debug)] pub struct BaseWithDestructor { @@ -41,3 +46,10 @@ fn bindgen_test_layout_DerivedFromBaseWithDestructor() { assert_eq!(::std::mem::align_of::() , 1usize); } +#[test] +fn bindgen_test_layout_template_BaseWithDestructor() { + assert_eq!(::std::mem::size_of::>() + , 1usize); + assert_eq!(::std::mem::align_of::>() + , 1usize); +} diff --git a/libbindgen/tests/expectations/tests/template.rs b/libbindgen/tests/expectations/tests/template.rs index 76afc87966..970b9037ac 100644 --- a/libbindgen/tests/expectations/tests/template.rs +++ b/libbindgen/tests/expectations/tests/template.rs @@ -12,6 +12,13 @@ pub struct Foo { pub m_member_arr: [T; 1usize], pub _phantom_1: ::std::marker::PhantomData, } +#[test] +fn bindgen_test_layout_template_Foo_int_int() { + assert_eq!(::std::mem::size_of::>() + , 24usize); + assert_eq!(::std::mem::align_of::>() + , 8usize); +} extern "C" { #[link_name = "_Z3bar3FooIiiE"] pub fn bar(foo: Foo<::std::os::raw::c_int, ::std::os::raw::c_int>); @@ -168,3 +175,10 @@ pub struct TemplateWithVar { pub _address: u8, pub _phantom_0: ::std::marker::PhantomData, } +#[test] +fn bindgen_test_layout_template_WithDtor_int() { + assert_eq!(::std::mem::size_of::>() , + 4usize); + assert_eq!(::std::mem::align_of::>() , + 4usize); +} From 5c764836380a2987da0db3997d26589e9e79d8c8 Mon Sep 17 00:00:00 2001 From: Artem Biryukov Date: Mon, 21 Nov 2016 20:00:19 +0300 Subject: [PATCH 4/4] Apply fixes due code review for issue #57 --- libbindgen/src/codegen/mod.rs | 62 ++++++++----------- .../tests/expectations/tests/anon_union.rs | 2 +- .../expectations/tests/class_with_dtor.rs | 2 +- libbindgen/tests/expectations/tests/crtp.rs | 4 +- .../tests/expectations/tests/template.rs | 4 +- 5 files changed, 31 insertions(+), 43 deletions(-) diff --git a/libbindgen/src/codegen/mod.rs b/libbindgen/src/codegen/mod.rs index 6730a9100c..392ec28a36 100644 --- a/libbindgen/src/codegen/mod.rs +++ b/libbindgen/src/codegen/mod.rs @@ -653,45 +653,33 @@ impl CodeGenerator for CompInfo { // Don't output classes with template parameters that aren't types, and // also don't output template specializations, neither total or partial. - // - // TODO: Generate layout tests for template specializations, yay! - - // TODO (imp): I will keep it like that right now and move it to function later - if self.has_non_type_template_params() || - self.is_template_specialization() { - let layout = item.kind().expect_type().layout(ctx); - let canonical_name = item.canonical_name(ctx); - - if let Some(layout) = layout { + if self.has_non_type_template_params() { + return; + } - let mut types = String::new(); + if self.is_template_specialization() { + let layout = item.kind().expect_type().layout(ctx); - for arg in self.template_args() { - if let Some(name) = ctx.resolve_type(*arg).name() { - // hope this isn't bad - types.push_str(format!("_{}", name).as_str()); - } - } - - let fn_name = format!("bindgen_test_layout_template_{}{}", canonical_name, types); - let fn_name = ctx.rust_ident_raw(&fn_name); - let ident = item.to_rust_ty(ctx); - let prefix = ctx.trait_prefix(); - let size_of_expr = quote_expr!(ctx.ext_cx(), - ::$prefix::mem::size_of::<$ident>()); - let align_of_expr = quote_expr!(ctx.ext_cx(), - ::$prefix::mem::align_of::<$ident>()); - let size = layout.size; - let align = layout.align; - let item = quote_item!(ctx.ext_cx(), - #[test] - fn $fn_name() { - assert_eq!($size_of_expr, $size); - assert_eq!($align_of_expr, $align); - }).unwrap(); - result.push(item); - } - return; + if let Some(layout) = layout { + let fn_name = format!("__bindgen_test_layout_template_{}", item.id().as_usize()); + let fn_name = ctx.rust_ident_raw(&fn_name); + let ident = item.to_rust_ty(ctx); + let prefix = ctx.trait_prefix(); + let size_of_expr = quote_expr!(ctx.ext_cx(), + ::$prefix::mem::size_of::<$ident>()); + let align_of_expr = quote_expr!(ctx.ext_cx(), + ::$prefix::mem::align_of::<$ident>()); + let size = layout.size; + let align = layout.align; + let item = quote_item!(ctx.ext_cx(), + #[test] + fn $fn_name() { + assert_eq!($size_of_expr, $size); + assert_eq!($align_of_expr, $align); + }).unwrap(); + result.push(item); + } + return; } let applicable_template_args = item.applicable_template_args(ctx); diff --git a/libbindgen/tests/expectations/tests/anon_union.rs b/libbindgen/tests/expectations/tests/anon_union.rs index 2dc206b728..915dfbd5b1 100644 --- a/libbindgen/tests/expectations/tests/anon_union.rs +++ b/libbindgen/tests/expectations/tests/anon_union.rs @@ -76,7 +76,7 @@ impl Clone for ErrorResult { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_template_TErrorResult_int() { +fn __bindgen_test_layout_template_17() { assert_eq!(::std::mem::size_of::>() , 24usize); assert_eq!(::std::mem::align_of::>() , diff --git a/libbindgen/tests/expectations/tests/class_with_dtor.rs b/libbindgen/tests/expectations/tests/class_with_dtor.rs index f09699ca0e..88c036b6a4 100644 --- a/libbindgen/tests/expectations/tests/class_with_dtor.rs +++ b/libbindgen/tests/expectations/tests/class_with_dtor.rs @@ -21,7 +21,7 @@ fn bindgen_test_layout_WithoutDtor() { assert_eq!(::std::mem::align_of::() , 8usize); } #[test] -fn bindgen_test_layout_template_HandleWithDtor_int() { +fn __bindgen_test_layout_template_11() { assert_eq!(::std::mem::size_of::>() , 8usize); assert_eq!(::std::mem::align_of::>() diff --git a/libbindgen/tests/expectations/tests/crtp.rs b/libbindgen/tests/expectations/tests/crtp.rs index 3962959916..a50e05e431 100644 --- a/libbindgen/tests/expectations/tests/crtp.rs +++ b/libbindgen/tests/expectations/tests/crtp.rs @@ -24,7 +24,7 @@ impl Clone for Derived { fn clone(&self) -> Self { *self } } #[test] -fn bindgen_test_layout_template_Base() { +fn __bindgen_test_layout_template_5() { assert_eq!(::std::mem::size_of::>() , 1usize); assert_eq!(::std::mem::align_of::>() , 1usize); } @@ -47,7 +47,7 @@ fn bindgen_test_layout_DerivedFromBaseWithDestructor() { 1usize); } #[test] -fn bindgen_test_layout_template_BaseWithDestructor() { +fn __bindgen_test_layout_template_12() { assert_eq!(::std::mem::size_of::>() , 1usize); assert_eq!(::std::mem::align_of::>() diff --git a/libbindgen/tests/expectations/tests/template.rs b/libbindgen/tests/expectations/tests/template.rs index 970b9037ac..21814baa5d 100644 --- a/libbindgen/tests/expectations/tests/template.rs +++ b/libbindgen/tests/expectations/tests/template.rs @@ -13,7 +13,7 @@ pub struct Foo { pub _phantom_1: ::std::marker::PhantomData, } #[test] -fn bindgen_test_layout_template_Foo_int_int() { +fn __bindgen_test_layout_template_10() { assert_eq!(::std::mem::size_of::>() , 24usize); assert_eq!(::std::mem::align_of::>() @@ -176,7 +176,7 @@ pub struct TemplateWithVar { pub _phantom_0: ::std::marker::PhantomData, } #[test] -fn bindgen_test_layout_template_WithDtor_int() { +fn __bindgen_test_layout_template_132() { assert_eq!(::std::mem::size_of::>() , 4usize); assert_eq!(::std::mem::align_of::>() ,