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 | |