mirror of
https://github.com/openharmony/third_party_rust_memoffset.git
synced 2026-07-19 14:33:32 -04:00
field_check macro; propagate parent type through span_of
This commit is contained in:
+13
-4
@@ -42,6 +42,18 @@ macro_rules! let_base_ptr {
|
||||
}
|
||||
}
|
||||
|
||||
/// Deref-coercion protection macro.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! field_check {
|
||||
($type:tt, $field:tt) => {
|
||||
// Make sure the field actually exists. This line ensures that a
|
||||
// compile-time error is generated if $field is accessed through a
|
||||
// Deref impl.
|
||||
let $type { $field: _, .. };
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculates the offset of the specified field from the start of the struct.
|
||||
/// This macro supports arbitrary amount of subscripts and recursive member-accesses.
|
||||
///
|
||||
@@ -67,10 +79,7 @@ macro_rules! let_base_ptr {
|
||||
#[macro_export]
|
||||
macro_rules! offset_of {
|
||||
($parent:tt, $field:tt) => {{
|
||||
// Make sure the field actually exists. This line ensures that a
|
||||
// compile-time error is generated if $field is accessed through a
|
||||
// Deref impl.
|
||||
let $parent { $field: _, .. };
|
||||
field_check!($parent, $field);
|
||||
|
||||
// Get a base pointer.
|
||||
$crate::let_base_ptr!(base_ptr, $parent);
|
||||
|
||||
+21
-21
@@ -89,46 +89,46 @@ macro_rules! span_of {
|
||||
};
|
||||
// Lots of UB due to taking references to uninitialized fields! But that can currently
|
||||
// not be avoided.
|
||||
(@helper $root:ident, [] ..= $($field:tt)+) => {
|
||||
(@helper $root:ident, $parent:tt, [] ..= $($field:tt)*) => {{
|
||||
($root as usize,
|
||||
&(*$root).$($field)* as *const _ as usize + $crate::mem::size_of_val(&(*$root).$($field)*))
|
||||
};
|
||||
(@helper $root:ident, [] .. $($field:tt)+) => {
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, [] .. $($field:tt)+) => {{
|
||||
($root as usize, &(*$root).$($field)* as *const _ as usize)
|
||||
};
|
||||
(@helper $root:ident, $(# $begin:tt)+ [] ..= $($end:tt)+) => {
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, $(# $begin:tt)+ [] ..= $($end:tt)+) => {{
|
||||
(&(*$root).$($begin)* as *const _ as usize,
|
||||
&(*$root).$($end)* as *const _ as usize + $crate::mem::size_of_val(&(*$root).$($end)*))
|
||||
};
|
||||
(@helper $root:ident, $(# $begin:tt)+ [] .. $($end:tt)+) => {
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, $(# $begin:tt)+ [] .. $($end:tt)+) => {{
|
||||
(&(*$root).$($begin)* as *const _ as usize,
|
||||
&(*$root).$($end)* as *const _ as usize)
|
||||
};
|
||||
(@helper $root:ident, $(# $begin:tt)+ [] ..) => {
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, $(# $begin:tt)+ [] ..) => {{
|
||||
(&(*$root).$($begin)* as *const _ as usize,
|
||||
$root as usize + $crate::mem::size_of_val(&*$root))
|
||||
};
|
||||
(@helper $root:ident, $(# $begin:tt)+ [] ..=) => {
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, $(# $begin:tt)+ [] ..=) => {{
|
||||
compile_error!(
|
||||
"Found inclusive range to the end of a struct. Did you mean '..' instead of '..='?")
|
||||
};
|
||||
(@helper $root:ident, $(# $begin:tt)+ []) => {
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, $(# $begin:tt)+ []) => {{
|
||||
(&(*$root).$($begin)* as *const _ as usize,
|
||||
&(*$root).$($begin)* as *const _ as usize + $crate::mem::size_of_val(&(*$root).$($begin)*))
|
||||
};
|
||||
(@helper $root:ident, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => {
|
||||
span_of!(@helper $root, $(#$begin)* #$tt [] $($rest)*)
|
||||
};
|
||||
(@helper $root:ident, [] $tt:tt $($rest:tt)*) => {
|
||||
span_of!(@helper $root, #$tt [] $($rest)*)
|
||||
};
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, $(# $begin:tt)+ [] $tt:tt $($rest:tt)*) => {{
|
||||
span_of!(@helper $root, $parent, $(#$begin)* #$tt [] $($rest)*)
|
||||
}};
|
||||
(@helper $root:ident, $parent:tt, [] $tt:tt $($rest:tt)*) => {{
|
||||
span_of!(@helper $root, $parent, #$tt [] $($rest)*)
|
||||
}};
|
||||
|
||||
($sty:tt, $($exp:tt)+) => ({
|
||||
unsafe {
|
||||
// Get a base pointer.
|
||||
$crate::let_base_ptr!(root, $sty);
|
||||
let base = root as usize;
|
||||
let (begin, end) = span_of!(@helper root, [] $($exp)*);
|
||||
let (begin, end) = span_of!(@helper root, $sty, [] $($exp)*);
|
||||
begin-base..end-base
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user