1 //! Macros for checking that types have the same layout as other types. 2 3 #![allow(unused_macros)] 4 5 /// Check that the size and alignment of a type match the `sys` bindings. 6 macro_rules! check_type { 7 ($struct:ident) => { 8 assert_eq_size!($struct, c::$struct); 9 assert_eq_align!($struct, c::$struct); 10 }; 11 } 12 13 /// The same as `check_type`, but for unions and anonymous structs we've 14 /// renamed to avoid having types like `bindgen_ty_1` in the API. 15 macro_rules! check_renamed_type { 16 ($to:ident, $from:ident) => { 17 assert_eq_size!($to, c::$from); 18 assert_eq_align!($to, c::$from); 19 }; 20 } 21 22 /// Check that the field of a struct has the same offset as the corresponding 23 /// field in the `sys` bindings. 24 macro_rules! check_struct_field { 25 ($struct:ident, $field:ident) => { 26 const_assert_eq!( 27 memoffset::offset_of!($struct, $field), 28 memoffset::offset_of!(c::$struct, $field) 29 ); 30 31 // This can't use `const_assert_eq` because `span_of` returns a 32 // `Range`, which can't be compared in const contexts. 33 assert_eq!( 34 memoffset::span_of!($struct, $field), 35 memoffset::span_of!(c::$struct, $field) 36 ); 37 }; 38 } 39 40 /// The same as `check_struct_field`, but for unions and anonymous structs 41 /// we've renamed to avoid having types like `bindgen_ty_1` in the API. 42 macro_rules! check_struct_renamed_field { 43 ($struct:ident, $to:ident, $from:ident) => { 44 const_assert_eq!( 45 memoffset::offset_of!($struct, $to), 46 memoffset::offset_of!(c::$struct, $from) 47 ); 48 49 // As above, this can't use `const_assert_eq`. 50 assert_eq!( 51 memoffset::span_of!($struct, $to), 52 memoffset::span_of!(c::$struct, $from) 53 ); 54 }; 55 } 56 57 /// The same as `check_struct_renamed_field`, but for when both the struct and 58 /// a field are renamed. 59 macro_rules! check_renamed_struct_renamed_field { 60 ($to_struct:ident, $from_struct:ident, $to:ident, $from:ident) => { 61 const_assert_eq!( 62 memoffset::offset_of!($to_struct, $to), 63 memoffset::offset_of!(c::$from_struct, $from) 64 ); 65 66 // As above, this can't use `const_assert_eq`. 67 assert_eq!( 68 memoffset::span_of!($to_struct, $to), 69 memoffset::span_of!(c::$from_struct, $from) 70 ); 71 }; 72 } 73 74 /// For the common case of no renaming, check all fields of a struct. 75 macro_rules! check_struct { 76 ($name:ident, $($field:ident),*) => { 77 // Check the size and alignment. 78 check_type!($name); 79 80 // Check that we have all the fields. 81 if false { 82 #[allow(unreachable_code)] 83 let _test = $name { 84 $($field: panic!()),* 85 }; 86 } 87 88 // Check that the fields have the right sizes and offsets. 89 $(check_struct_field!($name, $field));* 90 }; 91 } 92