diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index cca937f7f..c10887081 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -27,6 +27,56 @@ fn member_to_ident(member: &syn::Member) -> String { } } +// TODO: Maybe add support to more std associated constants. +fn to_known_assoc_constant(associated_to: &Path, name: &str) -> Option { + use crate::bindgen::ir::{IntKind, PrimitiveType}; + + if name != "MAX" && name != "MIN" { + return None; + } + + let prim = PrimitiveType::maybe(associated_to.name())?; + let prefix = match prim { + PrimitiveType::Integer { + kind, + signed, + zeroable: _, + } => match kind { + IntKind::B8 => { + if signed { + "INT8" + } else { + "UINT8" + } + } + IntKind::B16 => { + if signed { + "INT16" + } else { + "UINT16" + } + } + IntKind::B32 => { + if signed { + "INT32" + } else { + "UINT32" + } + } + IntKind::B64 => { + if signed { + "INT64" + } else { + "UINT64" + } + } + _ => return None, + }, + _ => return None, + }; + Some(format!("{}_{}", prefix, name)) +} + #[derive(Debug, Clone)] pub enum Literal { Expr(String), @@ -112,10 +162,12 @@ impl Literal { match *self { Literal::Expr(..) => true, Literal::Path { - ref associated_to, .. + ref associated_to, + ref name, } => { if let Some((ref path, _export_name)) = associated_to { - return bindings.struct_exists(path); + return bindings.struct_exists(path) + || to_known_assoc_constant(path, name).is_some(); } true } @@ -274,6 +326,30 @@ impl Literal { field: member_to_ident(member), }), + syn::Expr::Call(syn::ExprCall { + ref func, ref args, .. + }) => { + let struct_name = match Literal::load(func)? { + Literal::Path { + associated_to: None, + name, + } => name, + _ => return Err(format!("Unsupported call expression. {:?}", *expr)), + }; + let mut fields = HashMap::::default(); + for (index, arg) in args.iter().enumerate() { + let ident = + member_to_ident(&syn::Member::Unnamed(syn::Index::from(index))).to_string(); + let value = Literal::load(arg)?; + fields.insert(ident, value); + } + Ok(Literal::Struct { + path: Path::new(struct_name.clone()), + export_name: struct_name, + fields, + }) + } + syn::Expr::Struct(syn::ExprStruct { ref path, ref fields, @@ -282,10 +358,9 @@ impl Literal { let struct_name = path.segments[0].ident.unraw().to_string(); let mut field_map = HashMap::::default(); for field in fields { - let ident = member_to_ident(&field.member); - let key = ident.to_string(); + let ident = member_to_ident(&field.member).to_string(); let value = Literal::load(&field.expr)?; - field_map.insert(key, value); + field_map.insert(ident, value); } Ok(Literal::Struct { path: Path::new(struct_name.clone()), @@ -357,7 +432,10 @@ impl Literal { ref associated_to, ref name, } => { - if let Some((_, ref export_name)) = associated_to { + if let Some((ref path, ref export_name)) = associated_to { + if let Some(known) = to_known_assoc_constant(path, name) { + return write!(out, "{}", known); + } let path_separator = match config.language { Language::Cython | Language::C => "_", Language::Cxx => { diff --git a/tests/expectations/associated_in_body.both.c b/tests/expectations/associated_in_body.both.c index 977ab8bce..c06a066a6 100644 --- a/tests/expectations/associated_in_body.both.c +++ b/tests/expectations/associated_in_body.both.c @@ -35,4 +35,25 @@ typedef struct StyleAlignFlags { #define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } #define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } -void root(struct StyleAlignFlags flags); +/** + * An arbitrary identifier for a native (OS compositor) surface + */ +typedef struct StyleNativeSurfaceId { + uint64_t _0; +} StyleNativeSurfaceId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX } + +typedef struct StyleNativeTileId { + struct StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; +} StyleNativeTileId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 } + +void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile); diff --git a/tests/expectations/associated_in_body.both.compat.c b/tests/expectations/associated_in_body.both.compat.c index 910c9797c..926d7d3e4 100644 --- a/tests/expectations/associated_in_body.both.compat.c +++ b/tests/expectations/associated_in_body.both.compat.c @@ -35,11 +35,32 @@ typedef struct StyleAlignFlags { #define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } #define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } +/** + * An arbitrary identifier for a native (OS compositor) surface + */ +typedef struct StyleNativeSurfaceId { + uint64_t _0; +} StyleNativeSurfaceId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX } + +typedef struct StyleNativeTileId { + struct StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; +} StyleNativeTileId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 } + #ifdef __cplusplus extern "C" { #endif // __cplusplus -void root(struct StyleAlignFlags flags); +void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/associated_in_body.c b/tests/expectations/associated_in_body.c index a0192dfc6..e41971a77 100644 --- a/tests/expectations/associated_in_body.c +++ b/tests/expectations/associated_in_body.c @@ -35,4 +35,25 @@ typedef struct { #define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } #define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } -void root(StyleAlignFlags flags); +/** + * An arbitrary identifier for a native (OS compositor) surface + */ +typedef struct { + uint64_t _0; +} StyleNativeSurfaceId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX } + +typedef struct { + StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; +} StyleNativeTileId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 } + +void root(StyleAlignFlags flags, StyleNativeTileId tile); diff --git a/tests/expectations/associated_in_body.compat.c b/tests/expectations/associated_in_body.compat.c index a7c3e4b27..a7d61ab36 100644 --- a/tests/expectations/associated_in_body.compat.c +++ b/tests/expectations/associated_in_body.compat.c @@ -35,11 +35,32 @@ typedef struct { #define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } #define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } +/** + * An arbitrary identifier for a native (OS compositor) surface + */ +typedef struct { + uint64_t _0; +} StyleNativeSurfaceId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX } + +typedef struct { + StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; +} StyleNativeTileId; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 } + #ifdef __cplusplus extern "C" { #endif // __cplusplus -void root(StyleAlignFlags flags); +void root(StyleAlignFlags flags, StyleNativeTileId tile); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/associated_in_body.cpp b/tests/expectations/associated_in_body.cpp index 8db4148a0..5ccf28103 100644 --- a/tests/expectations/associated_in_body.cpp +++ b/tests/expectations/associated_in_body.cpp @@ -60,8 +60,25 @@ inline const StyleAlignFlags StyleAlignFlags::FLEX_START = StyleAlignFlags{ /* . inline const StyleAlignFlags StyleAlignFlags::MIXED = StyleAlignFlags{ /* .bits = */ (uint8_t)(((1 << 4) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits) }; inline const StyleAlignFlags StyleAlignFlags::MIXED_SELF = StyleAlignFlags{ /* .bits = */ (uint8_t)(((1 << 5) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits) }; +/// An arbitrary identifier for a native (OS compositor) surface +struct StyleNativeSurfaceId { + uint64_t _0; + static const StyleNativeSurfaceId DEBUG_OVERLAY; +}; +/// A special id for the native surface that is used for debug / profiler overlays. +inline const StyleNativeSurfaceId StyleNativeSurfaceId::DEBUG_OVERLAY = StyleNativeSurfaceId{ /* ._0 = */ UINT64_MAX }; + +struct StyleNativeTileId { + StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; + static const StyleNativeTileId DEBUG_OVERLAY; +}; +/// A special id for the native surface that is used for debug / profiler overlays. +inline const StyleNativeTileId StyleNativeTileId::DEBUG_OVERLAY = StyleNativeTileId{ /* .surface_id = */ StyleNativeSurfaceId::DEBUG_OVERLAY, /* .x = */ 0, /* .y = */ 0 }; + extern "C" { -void root(StyleAlignFlags flags); +void root(StyleAlignFlags flags, StyleNativeTileId tile); } // extern "C" diff --git a/tests/expectations/associated_in_body.pyx b/tests/expectations/associated_in_body.pyx index 54f69e3b7..f6b20bcd7 100644 --- a/tests/expectations/associated_in_body.pyx +++ b/tests/expectations/associated_in_body.pyx @@ -25,4 +25,17 @@ cdef extern from *: const StyleAlignFlags StyleAlignFlags_MIXED # = { (((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } const StyleAlignFlags StyleAlignFlags_MIXED_SELF # = { (((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } - void root(StyleAlignFlags flags); + # An arbitrary identifier for a native (OS compositor) surface + ctypedef struct StyleNativeSurfaceId: + uint64_t _0; + # A special id for the native surface that is used for debug / profiler overlays. + const StyleNativeSurfaceId StyleNativeSurfaceId_DEBUG_OVERLAY # = { UINT64_MAX } + + ctypedef struct StyleNativeTileId: + StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; + # A special id for the native surface that is used for debug / profiler overlays. + const StyleNativeTileId StyleNativeTileId_DEBUG_OVERLAY # = { StyleNativeSurfaceId_DEBUG_OVERLAY, 0, 0 } + + void root(StyleAlignFlags flags, StyleNativeTileId tile); diff --git a/tests/expectations/associated_in_body.tag.c b/tests/expectations/associated_in_body.tag.c index a55c1f83f..f0bc16f95 100644 --- a/tests/expectations/associated_in_body.tag.c +++ b/tests/expectations/associated_in_body.tag.c @@ -35,4 +35,25 @@ struct StyleAlignFlags { #define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } #define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } -void root(struct StyleAlignFlags flags); +/** + * An arbitrary identifier for a native (OS compositor) surface + */ +struct StyleNativeSurfaceId { + uint64_t _0; +}; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX } + +struct StyleNativeTileId { + struct StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; +}; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 } + +void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile); diff --git a/tests/expectations/associated_in_body.tag.compat.c b/tests/expectations/associated_in_body.tag.compat.c index 5ce56b79c..901dd6e46 100644 --- a/tests/expectations/associated_in_body.tag.compat.c +++ b/tests/expectations/associated_in_body.tag.compat.c @@ -35,11 +35,32 @@ struct StyleAlignFlags { #define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } #define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } +/** + * An arbitrary identifier for a native (OS compositor) surface + */ +struct StyleNativeSurfaceId { + uint64_t _0; +}; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX } + +struct StyleNativeTileId { + struct StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; +}; +/** + * A special id for the native surface that is used for debug / profiler overlays. + */ +#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 } + #ifdef __cplusplus extern "C" { #endif // __cplusplus -void root(struct StyleAlignFlags flags); +void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/associated_in_body.tag.pyx b/tests/expectations/associated_in_body.tag.pyx index a489a2871..86697bdf8 100644 --- a/tests/expectations/associated_in_body.tag.pyx +++ b/tests/expectations/associated_in_body.tag.pyx @@ -25,4 +25,17 @@ cdef extern from *: const StyleAlignFlags StyleAlignFlags_MIXED # = { (((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } const StyleAlignFlags StyleAlignFlags_MIXED_SELF # = { (((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) } - void root(StyleAlignFlags flags); + # An arbitrary identifier for a native (OS compositor) surface + cdef struct StyleNativeSurfaceId: + uint64_t _0; + # A special id for the native surface that is used for debug / profiler overlays. + const StyleNativeSurfaceId StyleNativeSurfaceId_DEBUG_OVERLAY # = { UINT64_MAX } + + cdef struct StyleNativeTileId: + StyleNativeSurfaceId surface_id; + int32_t x; + int32_t y; + # A special id for the native surface that is used for debug / profiler overlays. + const StyleNativeTileId StyleNativeTileId_DEBUG_OVERLAY # = { StyleNativeSurfaceId_DEBUG_OVERLAY, 0, 0 } + + void root(StyleAlignFlags flags, StyleNativeTileId tile); diff --git a/tests/rust/associated_in_body.rs b/tests/rust/associated_in_body.rs index 0f0768196..8c76a13ce 100644 --- a/tests/rust/associated_in_body.rs +++ b/tests/rust/associated_in_body.rs @@ -21,5 +21,34 @@ bitflags! { } } +/// An arbitrary identifier for a native (OS compositor) surface +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +pub struct NativeSurfaceId(pub u64); + +impl NativeSurfaceId { + /// A special id for the native surface that is used for debug / profiler overlays. + pub const DEBUG_OVERLAY: NativeSurfaceId = NativeSurfaceId(u64::MAX); +} + +#[repr(C)] +#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "capture", derive(Serialize))] +#[cfg_attr(feature = "replay", derive(Deserialize))] +pub struct NativeTileId { + pub surface_id: NativeSurfaceId, + pub x: i32, + pub y: i32, +} + +impl NativeTileId { + /// A special id for the native surface that is used for debug / profiler overlays. + pub const DEBUG_OVERLAY: NativeTileId = NativeTileId { + surface_id: NativeSurfaceId::DEBUG_OVERLAY, + x: 0, + y: 0, + }; +} + #[no_mangle] -pub extern "C" fn root(flags: AlignFlags) {} +pub extern "C" fn root(flags: AlignFlags, tile: NativeTileId) {}