summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ir/analysis/derive_debug.rs17
-rw-r--r--tests/expectations/tests/opaque-template-inst-member.rs41
-rw-r--r--tests/headers/opaque-template-inst-member.hpp12
3 files changed, 64 insertions, 6 deletions
diff --git a/src/ir/analysis/derive_debug.rs b/src/ir/analysis/derive_debug.rs
index 6e72da1f..b9b0be10 100644
--- a/src/ir/analysis/derive_debug.rs
+++ b/src/ir/analysis/derive_debug.rs
@@ -4,6 +4,7 @@ use super::{ConstrainResult, MonotoneFramework};
use std::collections::HashSet;
use std::collections::HashMap;
use ir::context::{BindgenContext, ItemId};
+use ir::item::IsOpaque;
use ir::traversal::EdgeKind;
use ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT;
use ir::ty::TypeKind;
@@ -260,19 +261,23 @@ impl<'ctx, 'gen> MonotoneFramework for CannotDeriveDebug<'ctx, 'gen> {
return self.insert(id);
}
- let ty_cannot_derive = template.template_definition()
+ let template_definition = template.template_definition()
.into_resolver()
.through_type_refs()
.through_type_aliases()
- .resolve(self.ctx)
+ .resolve(self.ctx);
+
+ let ty_cannot_derive = template_definition
.as_type()
.expect("Instantiations of a non-type?")
.as_comp()
.and_then(|c| {
- // For non-type template parameters, we generate an opaque
- // blob, and in this case the instantiation has a better
- // idea of the layout than the definition does.
- if c.has_non_type_template_params() {
+ // For non-type template parameters, or opaque template
+ // definitions, we generate an opaque blob, and in this
+ // case the instantiation has a better idea of the
+ // layout than the definition does.
+ if template_definition.is_opaque(self.ctx, &()) ||
+ c.has_non_type_template_params() {
let opaque = ty.layout(self.ctx)
.or_else(|| {
self.ctx
diff --git a/tests/expectations/tests/opaque-template-inst-member.rs b/tests/expectations/tests/opaque-template-inst-member.rs
new file mode 100644
index 00000000..f7b23546
--- /dev/null
+++ b/tests/expectations/tests/opaque-template-inst-member.rs
@@ -0,0 +1,41 @@
+/* automatically generated by rust-bindgen */
+
+
+#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
+
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+pub struct OpaqueTemplate {
+}
+impl Default for OpaqueTemplate {
+ fn default() -> Self { unsafe { ::std::mem::zeroed() } }
+}
+#[repr(C)]
+#[derive(Debug, Default, Copy)]
+pub struct ContainsOpaqueTemplate {
+ pub mBlah: [u32; 11usize],
+ pub mBaz: ::std::os::raw::c_int,
+}
+#[test]
+fn bindgen_test_layout_ContainsOpaqueTemplate() {
+ assert_eq!(::std::mem::size_of::<ContainsOpaqueTemplate>() , 48usize ,
+ concat ! ( "Size of: " , stringify ! ( ContainsOpaqueTemplate )
+ ));
+ assert_eq! (::std::mem::align_of::<ContainsOpaqueTemplate>() , 4usize ,
+ concat ! (
+ "Alignment of " , stringify ! ( ContainsOpaqueTemplate ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ContainsOpaqueTemplate ) ) . mBlah as *
+ const _ as usize } , 0usize , concat ! (
+ "Alignment of field: " , stringify ! ( ContainsOpaqueTemplate
+ ) , "::" , stringify ! ( mBlah ) ));
+ assert_eq! (unsafe {
+ & ( * ( 0 as * const ContainsOpaqueTemplate ) ) . mBaz as *
+ const _ as usize } , 44usize , concat ! (
+ "Alignment of field: " , stringify ! ( ContainsOpaqueTemplate
+ ) , "::" , stringify ! ( mBaz ) ));
+}
+impl Clone for ContainsOpaqueTemplate {
+ fn clone(&self) -> Self { *self }
+}
diff --git a/tests/headers/opaque-template-inst-member.hpp b/tests/headers/opaque-template-inst-member.hpp
new file mode 100644
index 00000000..9ee356ad
--- /dev/null
+++ b/tests/headers/opaque-template-inst-member.hpp
@@ -0,0 +1,12 @@
+// bindgen-flags: --opaque-type 'OpaqueTemplate'
+
+template<typename T>
+class OpaqueTemplate {
+ T mData;
+ bool mCannotDebug[40];
+};
+
+class ContainsOpaqueTemplate {
+ OpaqueTemplate<int> mBlah;
+ int mBaz;
+};