Merge pull request #1582 from gmnicke2/issue-1580

Make TypeKind::BlockPointer's canonical type in IR be itself
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 7330933..f54d476 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -346,13 +346,13 @@
             TypeKind::Void |
             TypeKind::NullPtr |
             TypeKind::Pointer(..) |
+            TypeKind::BlockPointer(..) |
             TypeKind::ObjCId |
             TypeKind::ObjCSel |
             TypeKind::ObjCInterface(..) => Some(self),
 
             TypeKind::ResolvedTypeRef(inner) |
             TypeKind::Alias(inner) |
-            TypeKind::BlockPointer(inner) |
             TypeKind::TemplateAlias(inner, _) => {
                 ctx.resolve_type(inner).safe_canonical_type(ctx)
             }
diff --git a/tests/expectations/tests/blocks-signature.rs b/tests/expectations/tests/blocks-signature.rs
index b479dfc..d01e517 100644
--- a/tests/expectations/tests/blocks-signature.rs
+++ b/tests/expectations/tests/blocks-signature.rs
@@ -11,19 +11,71 @@
 extern crate block;
 extern "C" {
     #[link_name = "\u{1}_Z8atexit_bU13block_pointerFvvE"]
-    pub fn atexit_b(arg1: _bindgen_ty_id_25);
+    pub fn atexit_b(arg1: _bindgen_ty_id_33);
 }
 pub type dispatch_data_t = *mut ::std::os::raw::c_void;
-pub type dispatch_data_applier_t = _bindgen_ty_id_32;
+pub type dispatch_data_applier_t = _bindgen_ty_id_40;
 extern "C" {
     #[link_name = "\u{1}_Z19dispatch_data_applyPvU13block_pointerFbS_yPKvyE"]
     pub fn dispatch_data_apply(data: dispatch_data_t, applier: dispatch_data_applier_t) -> bool;
 }
 extern "C" {
     #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"]
-    pub fn foo(arg1: _bindgen_ty_id_42) -> bool;
+    pub fn foo(arg1: _bindgen_ty_id_50) -> bool;
 }
-pub type _bindgen_ty_id_25 = *const ::block::Block<(), ()>;
-pub type _bindgen_ty_id_32 =
+extern "C" {
+    #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"]
+    pub fn foo_ptr(arg1: *mut _bindgen_ty_id_56) -> bool;
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct contains_block_pointers {
+    pub val: contains_block_pointers__bindgen_ty_id_61,
+    pub ptr_val: *mut _bindgen_ty_id_68,
+}
+#[test]
+fn bindgen_test_layout_contains_block_pointers() {
+    assert_eq!(
+        ::std::mem::size_of::<contains_block_pointers>(),
+        16usize,
+        concat!("Size of: ", stringify!(contains_block_pointers))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<contains_block_pointers>(),
+        8usize,
+        concat!("Alignment of ", stringify!(contains_block_pointers))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<contains_block_pointers>())).val as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(contains_block_pointers),
+            "::",
+            stringify!(val)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<contains_block_pointers>())).ptr_val as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(contains_block_pointers),
+            "::",
+            stringify!(ptr_val)
+        )
+    );
+}
+impl Default for contains_block_pointers {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
+pub type _bindgen_ty_id_33 = *const ::block::Block<(), ()>;
+pub type _bindgen_ty_id_40 =
     *const ::block::Block<(dispatch_data_t, usize, *const ::std::os::raw::c_void, usize), bool>;
-pub type _bindgen_ty_id_42 = *const ::block::Block<(usize,), ()>;
+pub type _bindgen_ty_id_50 = *const ::block::Block<(usize,), ()>;
+pub type _bindgen_ty_id_56 = *const ::block::Block<(usize,), ()>;
+pub type contains_block_pointers__bindgen_ty_id_61 =
+    *const ::block::Block<(::std::os::raw::c_int,), ()>;
+pub type _bindgen_ty_id_68 = *const ::block::Block<(::std::os::raw::c_int,), ()>;
diff --git a/tests/expectations/tests/blocks.rs b/tests/expectations/tests/blocks.rs
index 16d144f..1e1def7 100644
--- a/tests/expectations/tests/blocks.rs
+++ b/tests/expectations/tests/blocks.rs
@@ -22,3 +22,51 @@
     #[link_name = "\u{1}_Z3fooU13block_pointerFvyE"]
     pub fn foo(arg1: *mut ::std::os::raw::c_void) -> bool;
 }
+extern "C" {
+    #[link_name = "\u{1}_Z7foo_ptrPU13block_pointerFvyE"]
+    pub fn foo_ptr(arg1: *mut *mut ::std::os::raw::c_void) -> bool;
+}
+#[repr(C)]
+#[derive(Debug, Copy, Clone)]
+pub struct contains_block_pointers {
+    pub val: *mut ::std::os::raw::c_void,
+    pub ptr_val: *mut *mut ::std::os::raw::c_void,
+}
+#[test]
+fn bindgen_test_layout_contains_block_pointers() {
+    assert_eq!(
+        ::std::mem::size_of::<contains_block_pointers>(),
+        16usize,
+        concat!("Size of: ", stringify!(contains_block_pointers))
+    );
+    assert_eq!(
+        ::std::mem::align_of::<contains_block_pointers>(),
+        8usize,
+        concat!("Alignment of ", stringify!(contains_block_pointers))
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<contains_block_pointers>())).val as *const _ as usize },
+        0usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(contains_block_pointers),
+            "::",
+            stringify!(val)
+        )
+    );
+    assert_eq!(
+        unsafe { &(*(::std::ptr::null::<contains_block_pointers>())).ptr_val as *const _ as usize },
+        8usize,
+        concat!(
+            "Offset of field: ",
+            stringify!(contains_block_pointers),
+            "::",
+            stringify!(ptr_val)
+        )
+    );
+}
+impl Default for contains_block_pointers {
+    fn default() -> Self {
+        unsafe { ::std::mem::zeroed() }
+    }
+}
diff --git a/tests/headers/blocks.hpp b/tests/headers/blocks.hpp
index 4b53a8f..a68de7e 100644
--- a/tests/headers/blocks.hpp
+++ b/tests/headers/blocks.hpp
@@ -16,3 +16,10 @@
                          dispatch_data_applier_t applier);
 
 bool foo(void (^)(size_t bar));
+
+bool foo_ptr(void (^*)(size_t bar));
+
+struct contains_block_pointers {
+    void (^val)(int);
+    void (^*ptr_val)(int);
+};