blob: 0140b6d73a65f3c9be9c3fb29ce20a6a8f27a380 [file] [log] [blame]
//! Macros for checking that types have the same layout as other types.
#![allow(unused_macros)]
/// Check that the size and alignment of a type match the `sys` bindings.
macro_rules! check_type {
($struct:ident) => {
assert_eq_size!($struct, c::$struct);
assert_eq_align!($struct, c::$struct);
};
}
/// The same as `check_type`, but for unions and anonymous structs we've
/// renamed to avoid having types like `bindgen_ty_1` in the API.
macro_rules! check_renamed_type {
($to:ident, $from:ident) => {
assert_eq_size!($to, c::$from);
assert_eq_align!($to, c::$from);
};
}
/// Check that the field of a struct has the same offset as the corresponding
/// field in the `sys` bindings.
macro_rules! check_struct_field {
($struct:ident, $field:ident) => {
const_assert_eq!(
memoffset::offset_of!($struct, $field),
memoffset::offset_of!(c::$struct, $field)
);
// This can't use `const_assert_eq` because `span_of` returns a
// `Range`, which can't be compared in const contexts.
assert_eq!(
memoffset::span_of!($struct, $field),
memoffset::span_of!(c::$struct, $field)
);
};
}
/// The same as `check_struct_field`, but for unions and anonymous structs
/// we've renamed to avoid having types like `bindgen_ty_1` in the API.
macro_rules! check_struct_renamed_field {
($struct:ident, $to:ident, $from:ident) => {
const_assert_eq!(
memoffset::offset_of!($struct, $to),
memoffset::offset_of!(c::$struct, $from)
);
// As above, this can't use `const_assert_eq`.
assert_eq!(
memoffset::span_of!($struct, $to),
memoffset::span_of!(c::$struct, $from)
);
};
}
/// The same as `check_struct_renamed_field`, but for when both the struct and
/// a field are renamed.
macro_rules! check_renamed_struct_renamed_field {
($to_struct:ident, $from_struct:ident, $to:ident, $from:ident) => {
const_assert_eq!(
memoffset::offset_of!($to_struct, $to),
memoffset::offset_of!(c::$from_struct, $from)
);
// As above, this can't use `const_assert_eq`.
assert_eq!(
memoffset::span_of!($to_struct, $to),
memoffset::span_of!(c::$from_struct, $from)
);
};
}
/// For the common case of no renaming, check all fields of a struct.
macro_rules! check_struct {
($name:ident, $($field:ident),*) => {
// Check the size and alignment.
check_type!($name);
// Check that we have all the fields.
if false {
#[allow(unreachable_code)]
let _test = $name {
$($field: panic!()),*
};
}
// Check that the fields have the right sizes and offsets.
$(check_struct_field!($name, $field));*
};
}