diff --git a/CHANGES b/CHANGES index 0e0a7bba..557ec307 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +## 0.22.0 + + * Support rename rule for union body members (#751). + * constant: Add support for associated constant expressions (#752). + * Fix regression in CamelCase rename rule (should be lowerCamelCase) (#750). + * enumeration: simplify standard types in variants (#749). + * Avoid generating and writing bindings when called recursively (#747). + * Cython: Omit per-variant tags in unions generated for Rust enums (#748). + * Update various dependencies. + ## 0.21.0 * Update MSRV to 1.54.0 diff --git a/Cargo.lock b/Cargo.lock index 7a1f1b6d..2730392f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15,19 +15,19 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "cbindgen" -version = "0.21.0" +version = "0.22.0" dependencies = [ "clap", "heck", @@ -45,9 +45,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" @@ -65,30 +65,19 @@ dependencies = [ ] [[package]] -name = "cloudabi" -version = "0.0.3" +name = "fastrand" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ - "bitflags", -] - -[[package]] -name = "getrandom" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" -dependencies = [ - "cfg-if", - "libc", - "wasi", + "instant", ] [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "heck" @@ -98,28 +87,37 @@ checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" [[package]] name = "hermit-abi" -version = "0.1.16" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "indexmap" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2" +checksum = "282a6247722caba404c065016bbfa522806e51714c34f5dfc3e4a3a46fcb4223" dependencies = [ "autocfg", "hashbrown", ] +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + [[package]] name = "itoa" -version = "0.4.6" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" [[package]] name = "lazy_static" @@ -129,24 +127,24 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.77" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f96b10ec2560088a8e76961b00d47107b3a625fecb76dedb29ee7ccbf98235" +checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f" [[package]] name = "lock_api" -version = "0.3.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" +checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" dependencies = [ "scopeguard", ] [[package]] name = "log" -version = "0.4.11" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" dependencies = [ "cfg-if", ] @@ -168,99 +166,56 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.10.2" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ + "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.7.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d58c7c768d4ba344e3e8d72518ac13e259d7c7ade24167003b8488e10b6740a3" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ "cfg-if", - "cloudabi", + "instant", "libc", "redox_syscall", "smallvec", "winapi", ] -[[package]] -name = "ppv-lite86" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20" - [[package]] name = "proc-macro2" -version = "1.0.21" +version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" +checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.7" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" +checksum = "632d02bff7f874a36f33ea8bb416cd484b90cc66c1194b1a1110d067a7013f58" dependencies = [ "proc-macro2", ] [[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom", - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.2.0" +name = "redox_syscall" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +checksum = "8ae183fc1b06c149f0c1793e1eb447c8b04bfe46d48e9e48bfb8d2d7ed64ecf0" dependencies = [ - "rand_core", + "bitflags", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "remove_dir_all" version = "0.5.3" @@ -272,9 +227,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" [[package]] name = "scopeguard" @@ -284,18 +239,18 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.116" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fe57af81d28386a513cbc6858332abc6117cfdb5999647c6444b8f43a370a5" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.116" +version = "1.0.136" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f630a6370fd8e457873b4bd2ffdae75408bc291ba72be773772a4c2a065d9ae8" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" dependencies = [ "proc-macro2", "quote", @@ -304,9 +259,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.57" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" dependencies = [ "itoa", "ryu", @@ -315,9 +270,9 @@ dependencies = [ [[package]] name = "serial_test" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b15f74add9a9d4a3eb2bf739c9a427d266d3895b53d992c3a7c234fec2ff1f1" +checksum = "e0bccbcf40c8938196944a3da0e133e031a33f4d6b72db3bda3cc556e361905d" dependencies = [ "lazy_static", "parking_lot", @@ -326,9 +281,9 @@ dependencies = [ [[package]] name = "serial_test_derive" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65f59259be9fc1bf677d06cc1456e97756004a1a5a577480f71430bd7c17ba33" +checksum = "b2acd6defeddb41eb60bb468f8825d0cfd0c2a76bc03bfd235b6a1dc4f6a1ad5" dependencies = [ "proc-macro2", "quote", @@ -337,9 +292,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.4.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "strsim" @@ -349,9 +304,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.41" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" +checksum = "ea297be220d52398dcc07ce15a209fce436d361735ac1db700cab3b6cdfb9f54" dependencies = [ "proc-macro2", "quote", @@ -360,13 +315,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.1.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" dependencies = [ "cfg-if", + "fastrand", "libc", - "rand", "redox_syscall", "remove_dir_all", "winapi", @@ -389,24 +344,18 @@ checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" [[package]] name = "toml" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ "serde", ] [[package]] name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "winapi" diff --git a/Cargo.toml b/Cargo.toml index 49fb036b..4d8a7b11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cbindgen" -version = "0.21.0" +version = "0.22.0" authors = [ "Emilio Cobos Álvarez ", "Jeff Muizelaar ", diff --git a/src/bindgen/bindings.rs b/src/bindgen/bindings.rs index 7e6a2be0..da22992b 100644 --- a/src/bindgen/bindings.rs +++ b/src/bindgen/bindings.rs @@ -27,6 +27,9 @@ pub struct Bindings { constants: Vec, items: Vec, functions: Vec, + /// Bindings are generated by a recursive call to cbindgen + /// and shouldn't do anything when written anywhere. + noop: bool, } #[derive(PartialEq)] @@ -43,6 +46,7 @@ impl Bindings { globals: Vec, items: Vec, functions: Vec, + noop: bool, ) -> Bindings { Bindings { config, @@ -52,6 +56,7 @@ impl Bindings { constants, items, functions, + noop, } } @@ -93,6 +98,10 @@ impl Bindings { } pub fn write_to_file>(&self, path: P) -> bool { + if self.noop { + return false; + } + // Don't compare files if we've never written this file before if !path.as_ref().is_file() { if let Some(parent) = path::Path::new(path.as_ref()).parent() { @@ -121,6 +130,10 @@ impl Bindings { } pub fn write_headers(&self, out: &mut SourceWriter) { + if self.noop { + return; + } + if let Some(ref f) = self.config.header { out.new_line_if_not_start(); write!(out, "{}", f); @@ -273,6 +286,10 @@ impl Bindings { } pub fn write(&self, file: F) { + if self.noop { + return; + } + let mut out = SourceWriter::new(file, self); self.write_headers(&mut out); diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index 1a4fc5ab..cdcd787e 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -567,6 +567,10 @@ impl StructConfig { pub struct EnumConfig { /// The rename rule to apply to the name of enum variants pub rename_variants: RenameRule, + /// The rename rule to apply to the names of the union fields in C/C++ + /// generated from the Rust enum. Applied before rename_variants + /// rename rule. Defaults to SnakeCase. + pub rename_variant_name_fields: RenameRule, /// Whether to add a `Sentinel` value at the end of every enum /// This is useful in Gecko for IPC serialization pub add_sentinel: bool, @@ -608,6 +612,7 @@ impl Default for EnumConfig { fn default() -> EnumConfig { EnumConfig { rename_variants: RenameRule::None, + rename_variant_name_fields: RenameRule::SnakeCase, add_sentinel: false, prefix_with_name: false, derive_helper_methods: false, diff --git a/src/bindgen/ir/constant.rs b/src/bindgen/ir/constant.rs index 3ce2b417..6b765804 100644 --- a/src/bindgen/ir/constant.rs +++ b/src/bindgen/ir/constant.rs @@ -20,10 +20,70 @@ use crate::bindgen::library::Library; use crate::bindgen::writer::{Source, SourceWriter}; use crate::bindgen::Bindings; +fn member_to_ident(member: &syn::Member) -> String { + match member { + syn::Member::Named(ref name) => name.unraw().to_string(), + syn::Member::Unnamed(ref index) => format!("_{}", index.index), + } +} + +// 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), - Path(String), + Path { + associated_to: Option<(Path, String)>, + name: String, + }, PostfixUnaryOp { op: &'static str, value: Box, @@ -33,6 +93,10 @@ pub enum Literal { op: &'static str, right: Box, }, + FieldAccess { + base: Box, + field: String, + }, Struct { path: Path, export_name: String, @@ -58,6 +122,9 @@ impl Literal { left.replace_self_with(self_ty); right.replace_self_with(self_ty); } + Literal::FieldAccess { ref mut base, .. } => { + base.replace_self_with(self_ty); + } Literal::Struct { ref mut path, ref mut export_name, @@ -77,20 +144,40 @@ impl Literal { ty.replace_self_with(self_ty); value.replace_self_with(self_ty); } - Literal::Expr(..) | Literal::Path(..) => {} + Literal::Path { + ref mut associated_to, + .. + } => { + if let Some((ref mut path, ref mut export_name)) = *associated_to { + if path.replace_self_with(self_ty) { + *export_name = self_ty.name().to_owned(); + } + } + } + Literal::Expr(..) => {} } } fn is_valid(&self, bindings: &Bindings) -> bool { match *self { Literal::Expr(..) => true, - Literal::Path(..) => true, + Literal::Path { + ref associated_to, + ref name, + } => { + if let Some((ref path, _export_name)) = associated_to { + return bindings.struct_exists(path) + || to_known_assoc_constant(path, name).is_some(); + } + true + } Literal::PostfixUnaryOp { ref value, .. } => value.is_valid(bindings), Literal::BinOp { ref left, ref right, .. } => left.is_valid(bindings) && right.is_valid(bindings), + Literal::FieldAccess { ref base, .. } => base.is_valid(bindings), Literal::Struct { ref path, .. } => bindings.struct_exists(path), Literal::Cast { ref value, .. } => value.is_valid(bindings), } @@ -98,14 +185,14 @@ impl Literal { pub fn uses_only_primitive_types(&self) -> bool { match self { - Literal::Expr(..) => true, - Literal::Path(..) => true, + Literal::Expr(..) | Literal::Path { .. } => true, Literal::PostfixUnaryOp { ref value, .. } => value.uses_only_primitive_types(), Literal::BinOp { ref left, ref right, .. } => left.uses_only_primitive_types() & right.uses_only_primitive_types(), + Literal::FieldAccess { ref base, .. } => base.uses_only_primitive_types(), Literal::Struct { .. } => false, Literal::Cast { ref value, ref ty } => { value.uses_only_primitive_types() && ty.is_primitive_or_ptr_primitive() @@ -127,8 +214,18 @@ impl Literal { lit.rename_for_config(config); } } - Literal::Path(ref mut name) => { - config.export.rename(name); + Literal::FieldAccess { ref mut base, .. } => { + base.rename_for_config(config); + } + Literal::Path { + ref mut associated_to, + ref mut name, + } => { + if let Some((_path, ref mut export_name)) = associated_to { + config.export.rename(export_name); + } else { + config.export.rename(name); + } } Literal::PostfixUnaryOp { ref mut value, .. } => { value.rename_for_config(config); @@ -220,6 +317,39 @@ impl Literal { } } + syn::Expr::Field(syn::ExprField { + ref base, + ref member, + .. + }) => Ok(Literal::FieldAccess { + base: Box::new(Literal::load(base)?), + 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, @@ -228,13 +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 = match field.member { - syn::Member::Named(ref name) => name.unraw().to_string(), - syn::Member::Unnamed(ref index) => format!("_{}", index.index), - }; - 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()), @@ -257,16 +383,23 @@ impl Literal { }, // Match identifiers, like `5 << SHIFT` - syn::Expr::Path(syn::ExprPath { - path: syn::Path { ref segments, .. }, - .. - }) => { - // Handle only the simplest identifiers and error for anything else. - if segments.len() == 1 { - Ok(Literal::Path(format!("{}", segments.last().unwrap().ident))) - } else { - Err(format!("Unsupported path expression. {:?}", *segments)) - } + syn::Expr::Path(syn::ExprPath { ref path, .. }) => { + // Handle only the simplest identifiers and Associated::IDENT + // kind of syntax. + Ok(match path.segments.len() { + 1 => Literal::Path { + associated_to: None, + name: path.segments[0].ident.to_string(), + }, + 2 => { + let struct_name = path.segments[0].ident.to_string(); + Literal::Path { + associated_to: Some((Path::new(&struct_name), struct_name)), + name: path.segments[1].ident.to_string(), + } + } + _ => return Err(format!("Unsupported path expression. {:?}", path)), + }) } syn::Expr::Paren(syn::ExprParen { ref expr, .. }) => Self::load(expr), @@ -302,7 +435,36 @@ impl Literal { } (v, _) => write!(out, "{}", v), }, - Literal::Path(v) => write!(out, "{}", v), + Literal::Path { + ref associated_to, + ref name, + } => { + 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 | Language::Csharp => { + if config.structure.associated_constants_in_body { + "::" + } else { + "_" + } + } + }; + write!(out, "{}{}", export_name, path_separator) + } + write!(out, "{}", name) + } + Literal::FieldAccess { + ref base, + ref field, + } => { + write!(out, "("); + base.write(config, out); + write!(out, ").{}", field); + } Literal::PostfixUnaryOp { op, ref value } => { write!(out, "{}", op); value.write(config, out); diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index 2c1ca619..64a2e10e 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -149,11 +149,16 @@ impl EnumVariant { if let Some(b) = enum_annotations.bool("derive-ostream") { annotations.add_default("derive-ostream", AnnotationValue::Bool(b)); } + + let body_rule = enum_annotations + .parse_atom::("rename-variant-name-fields") + .unwrap_or(config.enumeration.rename_variant_name_fields); + let body = match variant.fields { syn::Fields::Unit => VariantBody::Empty(annotations), syn::Fields::Named(ref fields) => { let path = Path::new(format!("{}_Body", variant.ident)); - let name = RenameRule::SnakeCase + let name = body_rule .apply( &variant.ident.unraw().to_string(), IdentifierType::StructMember, @@ -179,7 +184,7 @@ impl EnumVariant { } syn::Fields::Unnamed(ref fields) => { let path = Path::new(format!("{}_Body", variant.ident)); - let name = RenameRule::SnakeCase + let name = body_rule .apply( &variant.ident.unraw().to_string(), IdentifierType::StructMember, @@ -240,6 +245,12 @@ impl EnumVariant { } } + fn simplify_standard_types(&mut self, config: &Config) { + if let VariantBody::Body { ref mut body, .. } = self.body { + body.simplify_standard_types(config); + } + } + fn add_dependencies(&self, library: &Library, out: &mut Dependencies) { if let VariantBody::Body { ref body, .. } = self.body { body.add_dependencies(library, out); @@ -710,7 +721,7 @@ impl Source for Enum { } // Emit fields for all variants with data. - self.write_variant_fields(config, out); + self.write_variant_fields(config, out, inline_tag_field); // Close union of all variants with data, only in the non-inline tag scenario. // See the comment about Cython on `open_brace`. @@ -959,7 +970,12 @@ impl Enum { } /// Emit fields for all variants with data. - fn write_variant_fields(&self, config: &Config, out: &mut SourceWriter) { + fn write_variant_fields( + &self, + config: &Config, + out: &mut SourceWriter, + inline_tag_field: bool, + ) { let mut first = true; for variant in &self.variants { if let VariantBody::Body { @@ -984,11 +1000,15 @@ impl Enum { // by the corresponding C code. So we can inline the unnamed struct and get the // same observable result. Moreother we have to do it because Cython doesn't // support unnamed structs. + // For the same reason with Cython we can omit per-variant tags (the first + // field) to avoid extra noise, the main `tag` is enough in this case. if config.language != Language::Cython { out.write("struct"); out.open_brace(); } - out.write_vertical_source_list(&body.fields, ListType::Cap(";")); + let start_field = + usize::from(inline_tag_field && config.language == Language::Cython); + out.write_vertical_source_list(&body.fields[start_field..], ListType::Cap(";")); if config.language != Language::Cython { out.close_brace(true); } @@ -1538,4 +1558,10 @@ impl Enum { } } } + + pub fn simplify_standard_types(&mut self, config: &Config) { + for variant in &mut self.variants { + variant.simplify_standard_types(config); + } + } } diff --git a/src/bindgen/library.rs b/src/bindgen/library.rs index b1f9eb45..e7a1891e 100644 --- a/src/bindgen/library.rs +++ b/src/bindgen/library.rs @@ -54,6 +54,23 @@ impl Library { } pub fn generate(mut self) -> Result { + // If macro expansion is enabled, then cbindgen will attempt to build the crate + // and will run its build script which may run cbindgen again. That second run may start + // infinite recursion, or overwrite previously written files with bindings. + // So if we are called recursively, we are skipping the whole generation + // and produce "noop" bindings that won't be able to overwrite anything. + if std::env::var("_CBINDGEN_IS_RUNNING").is_ok() { + return Ok(Bindings::new( + self.config, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + true, + )); + } + self.transfer_annotations(); self.simplify_standard_types(); @@ -134,6 +151,7 @@ impl Library { globals, items, functions, + false, )) } @@ -362,6 +380,9 @@ impl Library { self.structs.for_all_items_mut(|x| { x.simplify_standard_types(config); }); + self.enums.for_all_items_mut(|x| { + x.simplify_standard_types(config); + }); self.unions.for_all_items_mut(|x| { x.simplify_standard_types(config); }); diff --git a/src/bindgen/parser.rs b/src/bindgen/parser.rs index 0a610774..804ead03 100644 --- a/src/bindgen/parser.rs +++ b/src/bindgen/parser.rs @@ -187,13 +187,6 @@ impl<'a> Parser<'a> { fn parse_expand_crate(&mut self, pkg: &PackageRef) -> Result<(), Error> { assert!(self.lib.is_some()); - // If you want to expand the crate you run cbindgen on you might end up in an endless - // recursion if the cbindgen generation is triggered from build.rs. Hence don't run the - // expansion if the build was already triggered by cbindgen. - if std::env::var("_CBINDGEN_IS_RUNNING").is_ok() { - return Ok(()); - } - let mod_items = { if !self.cache_expanded_crate.contains_key(&pkg.name) { let s = self diff --git a/tests/expectations/annotation.pyx b/tests/expectations/annotation.pyx index c52d7233..8aa9b54a 100644 --- a/tests/expectations/annotation.pyx +++ b/tests/expectations/annotation.pyx @@ -31,7 +31,6 @@ cdef extern from *: ctypedef union F: F_Tag tag; - F_Tag foo_tag; int16_t foo; Bar_Body bar; diff --git a/tests/expectations/annotation.tag.pyx b/tests/expectations/annotation.tag.pyx index 61f0bf28..4f0b46ac 100644 --- a/tests/expectations/annotation.tag.pyx +++ b/tests/expectations/annotation.tag.pyx @@ -31,7 +31,6 @@ cdef extern from *: cdef union F: F_Tag tag; - F_Tag foo_tag; int16_t foo; Bar_Body bar; diff --git a/tests/expectations/asserted_cast.pyx b/tests/expectations/asserted_cast.pyx index e34f4011..126635c0 100644 --- a/tests/expectations/asserted_cast.pyx +++ b/tests/expectations/asserted_cast.pyx @@ -56,7 +56,6 @@ cdef extern from *: ctypedef union K: K_Tag tag; - K_Tag foo_tag; int16_t foo; K_Bar_Body bar; diff --git a/tests/expectations/asserted_cast.tag.pyx b/tests/expectations/asserted_cast.tag.pyx index 9dde4c7f..bf6dec5a 100644 --- a/tests/expectations/asserted_cast.tag.pyx +++ b/tests/expectations/asserted_cast.tag.pyx @@ -56,7 +56,6 @@ cdef extern from *: cdef union K: K_Tag tag; - K_Tag foo_tag; int16_t foo; K_Bar_Body bar; diff --git a/tests/expectations/associated_in_body.both.c b/tests/expectations/associated_in_body.both.c index 16035b18..c06a066a 100644 --- a/tests/expectations/associated_in_body.both.c +++ b/tests/expectations/associated_in_body.both.c @@ -27,9 +27,33 @@ typedef struct StyleAlignFlags { * 'end' */ #define StyleAlignFlags_END (StyleAlignFlags){ .bits = (uint8_t)(1 << 2) } +#define StyleAlignFlags_ALIAS (StyleAlignFlags){ .bits = (uint8_t)(StyleAlignFlags_END).bits } /** * 'flex-start' */ #define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = (uint8_t)(1 << 3) } +#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 ad4e8417..926d7d3e 100644 --- a/tests/expectations/associated_in_body.both.compat.c +++ b/tests/expectations/associated_in_body.both.compat.c @@ -27,16 +27,40 @@ typedef struct StyleAlignFlags { * 'end' */ #define StyleAlignFlags_END (StyleAlignFlags){ .bits = (uint8_t)(1 << 2) } +#define StyleAlignFlags_ALIAS (StyleAlignFlags){ .bits = (uint8_t)(StyleAlignFlags_END).bits } /** * 'flex-start' */ #define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = (uint8_t)(1 << 3) } +#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 20cf7aff..e41971a7 100644 --- a/tests/expectations/associated_in_body.c +++ b/tests/expectations/associated_in_body.c @@ -27,9 +27,33 @@ typedef struct { * 'end' */ #define StyleAlignFlags_END (StyleAlignFlags){ .bits = (uint8_t)(1 << 2) } +#define StyleAlignFlags_ALIAS (StyleAlignFlags){ .bits = (uint8_t)(StyleAlignFlags_END).bits } /** * 'flex-start' */ #define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = (uint8_t)(1 << 3) } +#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 2872416b..a7d61ab3 100644 --- a/tests/expectations/associated_in_body.compat.c +++ b/tests/expectations/associated_in_body.compat.c @@ -27,16 +27,40 @@ typedef struct { * 'end' */ #define StyleAlignFlags_END (StyleAlignFlags){ .bits = (uint8_t)(1 << 2) } +#define StyleAlignFlags_ALIAS (StyleAlignFlags){ .bits = (uint8_t)(StyleAlignFlags_END).bits } /** * 'flex-start' */ #define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = (uint8_t)(1 << 3) } +#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 9bbf210a..5ccf2810 100644 --- a/tests/expectations/associated_in_body.cpp +++ b/tests/expectations/associated_in_body.cpp @@ -41,7 +41,10 @@ struct StyleAlignFlags { static const StyleAlignFlags NORMAL; static const StyleAlignFlags START; static const StyleAlignFlags END; + static const StyleAlignFlags ALIAS; static const StyleAlignFlags FLEX_START; + static const StyleAlignFlags MIXED; + static const StyleAlignFlags MIXED_SELF; }; /// 'auto' inline const StyleAlignFlags StyleAlignFlags::AUTO = StyleAlignFlags{ /* .bits = */ (uint8_t)0 }; @@ -51,11 +54,31 @@ inline const StyleAlignFlags StyleAlignFlags::NORMAL = StyleAlignFlags{ /* .bits inline const StyleAlignFlags StyleAlignFlags::START = StyleAlignFlags{ /* .bits = */ (uint8_t)(1 << 1) }; /// 'end' inline const StyleAlignFlags StyleAlignFlags::END = StyleAlignFlags{ /* .bits = */ (uint8_t)(1 << 2) }; +inline const StyleAlignFlags StyleAlignFlags::ALIAS = StyleAlignFlags{ /* .bits = */ (uint8_t)(StyleAlignFlags::END).bits }; /// 'flex-start' inline const StyleAlignFlags StyleAlignFlags::FLEX_START = StyleAlignFlags{ /* .bits = */ (uint8_t)(1 << 3) }; +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 4444c8c5..f6b20bcd 100644 --- a/tests/expectations/associated_in_body.pyx +++ b/tests/expectations/associated_in_body.pyx @@ -19,7 +19,23 @@ cdef extern from *: const StyleAlignFlags StyleAlignFlags_START # = { (1 << 1) } # 'end' const StyleAlignFlags StyleAlignFlags_END # = { (1 << 2) } + const StyleAlignFlags StyleAlignFlags_ALIAS # = { (StyleAlignFlags_END).bits } # 'flex-start' const StyleAlignFlags StyleAlignFlags_FLEX_START # = { (1 << 3) } + 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 2ac53227..f0bc16f9 100644 --- a/tests/expectations/associated_in_body.tag.c +++ b/tests/expectations/associated_in_body.tag.c @@ -27,9 +27,33 @@ struct StyleAlignFlags { * 'end' */ #define StyleAlignFlags_END (StyleAlignFlags){ .bits = (uint8_t)(1 << 2) } +#define StyleAlignFlags_ALIAS (StyleAlignFlags){ .bits = (uint8_t)(StyleAlignFlags_END).bits } /** * 'flex-start' */ #define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = (uint8_t)(1 << 3) } +#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 056632f5..901dd6e4 100644 --- a/tests/expectations/associated_in_body.tag.compat.c +++ b/tests/expectations/associated_in_body.tag.compat.c @@ -27,16 +27,40 @@ struct StyleAlignFlags { * 'end' */ #define StyleAlignFlags_END (StyleAlignFlags){ .bits = (uint8_t)(1 << 2) } +#define StyleAlignFlags_ALIAS (StyleAlignFlags){ .bits = (uint8_t)(StyleAlignFlags_END).bits } /** * 'flex-start' */ #define StyleAlignFlags_FLEX_START (StyleAlignFlags){ .bits = (uint8_t)(1 << 3) } +#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 c02e58fc..86697bdf 100644 --- a/tests/expectations/associated_in_body.tag.pyx +++ b/tests/expectations/associated_in_body.tag.pyx @@ -19,7 +19,23 @@ cdef extern from *: const StyleAlignFlags StyleAlignFlags_START # = { (1 << 1) } # 'end' const StyleAlignFlags StyleAlignFlags_END # = { (1 << 2) } + const StyleAlignFlags StyleAlignFlags_ALIAS # = { (StyleAlignFlags_END).bits } # 'flex-start' const StyleAlignFlags StyleAlignFlags_FLEX_START # = { (1 << 3) } + 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/expectations/bitflags.both.c b/tests/expectations/bitflags.both.c index a4a86518..8428299a 100644 --- a/tests/expectations/bitflags.both.c +++ b/tests/expectations/bitflags.both.c @@ -27,10 +27,13 @@ typedef struct AlignFlags { * 'end' */ #define AlignFlags_END (AlignFlags){ .bits = (uint8_t)(1 << 2) } +#define AlignFlags_ALIAS (AlignFlags){ .bits = (uint8_t)(AlignFlags_END).bits } /** * 'flex-start' */ #define AlignFlags_FLEX_START (AlignFlags){ .bits = (uint8_t)(1 << 3) } +#define AlignFlags_MIXED (AlignFlags){ .bits = (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } +#define AlignFlags_MIXED_SELF (AlignFlags){ .bits = (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } typedef struct DebugFlags { uint32_t bits; diff --git a/tests/expectations/bitflags.both.compat.c b/tests/expectations/bitflags.both.compat.c index 82d308e8..23b6243c 100644 --- a/tests/expectations/bitflags.both.compat.c +++ b/tests/expectations/bitflags.both.compat.c @@ -27,10 +27,13 @@ typedef struct AlignFlags { * 'end' */ #define AlignFlags_END (AlignFlags){ .bits = (uint8_t)(1 << 2) } +#define AlignFlags_ALIAS (AlignFlags){ .bits = (uint8_t)(AlignFlags_END).bits } /** * 'flex-start' */ #define AlignFlags_FLEX_START (AlignFlags){ .bits = (uint8_t)(1 << 3) } +#define AlignFlags_MIXED (AlignFlags){ .bits = (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } +#define AlignFlags_MIXED_SELF (AlignFlags){ .bits = (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } typedef struct DebugFlags { uint32_t bits; diff --git a/tests/expectations/bitflags.c b/tests/expectations/bitflags.c index bf9e4655..073f10fb 100644 --- a/tests/expectations/bitflags.c +++ b/tests/expectations/bitflags.c @@ -27,10 +27,13 @@ typedef struct { * 'end' */ #define AlignFlags_END (AlignFlags){ .bits = (uint8_t)(1 << 2) } +#define AlignFlags_ALIAS (AlignFlags){ .bits = (uint8_t)(AlignFlags_END).bits } /** * 'flex-start' */ #define AlignFlags_FLEX_START (AlignFlags){ .bits = (uint8_t)(1 << 3) } +#define AlignFlags_MIXED (AlignFlags){ .bits = (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } +#define AlignFlags_MIXED_SELF (AlignFlags){ .bits = (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } typedef struct { uint32_t bits; diff --git a/tests/expectations/bitflags.compat.c b/tests/expectations/bitflags.compat.c index 672d9342..cbcf7c4a 100644 --- a/tests/expectations/bitflags.compat.c +++ b/tests/expectations/bitflags.compat.c @@ -27,10 +27,13 @@ typedef struct { * 'end' */ #define AlignFlags_END (AlignFlags){ .bits = (uint8_t)(1 << 2) } +#define AlignFlags_ALIAS (AlignFlags){ .bits = (uint8_t)(AlignFlags_END).bits } /** * 'flex-start' */ #define AlignFlags_FLEX_START (AlignFlags){ .bits = (uint8_t)(1 << 3) } +#define AlignFlags_MIXED (AlignFlags){ .bits = (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } +#define AlignFlags_MIXED_SELF (AlignFlags){ .bits = (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } typedef struct { uint32_t bits; diff --git a/tests/expectations/bitflags.cpp b/tests/expectations/bitflags.cpp index af131ae1..31cb6393 100644 --- a/tests/expectations/bitflags.cpp +++ b/tests/expectations/bitflags.cpp @@ -46,8 +46,11 @@ static const AlignFlags AlignFlags_NORMAL = AlignFlags{ /* .bits = */ (uint8_t)1 static const AlignFlags AlignFlags_START = AlignFlags{ /* .bits = */ (uint8_t)(1 << 1) }; /// 'end' static const AlignFlags AlignFlags_END = AlignFlags{ /* .bits = */ (uint8_t)(1 << 2) }; +static const AlignFlags AlignFlags_ALIAS = AlignFlags{ /* .bits = */ (uint8_t)(AlignFlags_END).bits }; /// 'flex-start' static const AlignFlags AlignFlags_FLEX_START = AlignFlags{ /* .bits = */ (uint8_t)(1 << 3) }; +static const AlignFlags AlignFlags_MIXED = AlignFlags{ /* .bits = */ (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) }; +static const AlignFlags AlignFlags_MIXED_SELF = AlignFlags{ /* .bits = */ (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) }; struct DebugFlags { uint32_t bits; diff --git a/tests/expectations/bitflags.pyx b/tests/expectations/bitflags.pyx index 138c99c5..fd33bdb6 100644 --- a/tests/expectations/bitflags.pyx +++ b/tests/expectations/bitflags.pyx @@ -19,8 +19,11 @@ cdef extern from *: const AlignFlags AlignFlags_START # = { (1 << 1) } # 'end' const AlignFlags AlignFlags_END # = { (1 << 2) } + const AlignFlags AlignFlags_ALIAS # = { (AlignFlags_END).bits } # 'flex-start' const AlignFlags AlignFlags_FLEX_START # = { (1 << 3) } + const AlignFlags AlignFlags_MIXED # = { (((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } + const AlignFlags AlignFlags_MIXED_SELF # = { (((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } ctypedef struct DebugFlags: uint32_t bits; diff --git a/tests/expectations/bitflags.tag.c b/tests/expectations/bitflags.tag.c index 1b796fae..13729091 100644 --- a/tests/expectations/bitflags.tag.c +++ b/tests/expectations/bitflags.tag.c @@ -27,10 +27,13 @@ struct AlignFlags { * 'end' */ #define AlignFlags_END (AlignFlags){ .bits = (uint8_t)(1 << 2) } +#define AlignFlags_ALIAS (AlignFlags){ .bits = (uint8_t)(AlignFlags_END).bits } /** * 'flex-start' */ #define AlignFlags_FLEX_START (AlignFlags){ .bits = (uint8_t)(1 << 3) } +#define AlignFlags_MIXED (AlignFlags){ .bits = (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } +#define AlignFlags_MIXED_SELF (AlignFlags){ .bits = (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } struct DebugFlags { uint32_t bits; diff --git a/tests/expectations/bitflags.tag.compat.c b/tests/expectations/bitflags.tag.compat.c index 1feb5c13..6b6e2b8b 100644 --- a/tests/expectations/bitflags.tag.compat.c +++ b/tests/expectations/bitflags.tag.compat.c @@ -27,10 +27,13 @@ struct AlignFlags { * 'end' */ #define AlignFlags_END (AlignFlags){ .bits = (uint8_t)(1 << 2) } +#define AlignFlags_ALIAS (AlignFlags){ .bits = (uint8_t)(AlignFlags_END).bits } /** * 'flex-start' */ #define AlignFlags_FLEX_START (AlignFlags){ .bits = (uint8_t)(1 << 3) } +#define AlignFlags_MIXED (AlignFlags){ .bits = (uint8_t)(((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } +#define AlignFlags_MIXED_SELF (AlignFlags){ .bits = (uint8_t)(((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } struct DebugFlags { uint32_t bits; diff --git a/tests/expectations/bitflags.tag.pyx b/tests/expectations/bitflags.tag.pyx index d9d205fd..272cddca 100644 --- a/tests/expectations/bitflags.tag.pyx +++ b/tests/expectations/bitflags.tag.pyx @@ -19,8 +19,11 @@ cdef extern from *: const AlignFlags AlignFlags_START # = { (1 << 1) } # 'end' const AlignFlags AlignFlags_END # = { (1 << 2) } + const AlignFlags AlignFlags_ALIAS # = { (AlignFlags_END).bits } # 'flex-start' const AlignFlags AlignFlags_FLEX_START # = { (1 << 3) } + const AlignFlags AlignFlags_MIXED # = { (((1 << 4) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } + const AlignFlags AlignFlags_MIXED_SELF # = { (((1 << 5) | (AlignFlags_FLEX_START).bits) | (AlignFlags_END).bits) } cdef struct DebugFlags: uint32_t bits; diff --git a/tests/expectations/derive_ostream.pyx b/tests/expectations/derive_ostream.pyx index 881c095a..2a416211 100644 --- a/tests/expectations/derive_ostream.pyx +++ b/tests/expectations/derive_ostream.pyx @@ -36,7 +36,6 @@ cdef extern from *: ctypedef union F: F_Tag tag; - F_Tag foo_tag; int16_t foo; Bar_Body bar; diff --git a/tests/expectations/derive_ostream.tag.pyx b/tests/expectations/derive_ostream.tag.pyx index 4f5b80de..5e288851 100644 --- a/tests/expectations/derive_ostream.tag.pyx +++ b/tests/expectations/derive_ostream.tag.pyx @@ -36,7 +36,6 @@ cdef extern from *: cdef union F: F_Tag tag; - F_Tag foo_tag; int16_t foo; Bar_Body bar; diff --git a/tests/expectations/destructor_and_copy_ctor.pyx b/tests/expectations/destructor_and_copy_ctor.pyx index 0bd7f8f2..745e04d4 100644 --- a/tests/expectations/destructor_and_copy_ctor.pyx +++ b/tests/expectations/destructor_and_copy_ctor.pyx @@ -81,11 +81,8 @@ cdef extern from *: ctypedef union Baz_i32: Baz_i32_Tag tag; - Baz_i32_Tag polygon21_tag; Polygon_i32 polygon21; - Baz_i32_Tag slice21_tag; OwnedSlice_i32 slice21; - Baz_i32_Tag slice22_tag; OwnedSlice_i32 slice22; Slice23_Body_i32 slice23; Slice24_Body_i32 slice24; @@ -98,9 +95,7 @@ cdef extern from *: ctypedef union Taz: Taz_Tag tag; - Taz_Tag taz1_tag; int32_t taz1; - Taz_Tag taz3_tag; OwnedSlice_i32 taz3; cdef enum: @@ -110,7 +105,6 @@ cdef extern from *: ctypedef union Tazz: Tazz_Tag tag; - Tazz_Tag taz2_tag; int32_t taz2; cdef enum: @@ -120,7 +114,6 @@ cdef extern from *: ctypedef union Tazzz: Tazzz_Tag tag; - Tazzz_Tag taz5_tag; int32_t taz5; cdef enum: @@ -130,9 +123,7 @@ cdef extern from *: ctypedef union Tazzzz: Tazzzz_Tag tag; - Tazzzz_Tag taz6_tag; int32_t taz6; - Tazzzz_Tag taz7_tag; uint32_t taz7; cdef enum: @@ -142,9 +133,7 @@ cdef extern from *: ctypedef union Qux: Qux_Tag tag; - Qux_Tag qux1_tag; int32_t qux1; - Qux_Tag qux2_tag; uint32_t qux2; void root(const Foo_u32 *a, diff --git a/tests/expectations/destructor_and_copy_ctor.tag.pyx b/tests/expectations/destructor_and_copy_ctor.tag.pyx index 7406dc88..49619ebf 100644 --- a/tests/expectations/destructor_and_copy_ctor.tag.pyx +++ b/tests/expectations/destructor_and_copy_ctor.tag.pyx @@ -81,11 +81,8 @@ cdef extern from *: cdef union Baz_i32: Baz_i32_Tag tag; - Baz_i32_Tag polygon21_tag; Polygon_i32 polygon21; - Baz_i32_Tag slice21_tag; OwnedSlice_i32 slice21; - Baz_i32_Tag slice22_tag; OwnedSlice_i32 slice22; Slice23_Body_i32 slice23; Slice24_Body_i32 slice24; @@ -98,9 +95,7 @@ cdef extern from *: cdef union Taz: Taz_Tag tag; - Taz_Tag taz1_tag; int32_t taz1; - Taz_Tag taz3_tag; OwnedSlice_i32 taz3; cdef enum: @@ -110,7 +105,6 @@ cdef extern from *: cdef union Tazz: Tazz_Tag tag; - Tazz_Tag taz2_tag; int32_t taz2; cdef enum: @@ -120,7 +114,6 @@ cdef extern from *: cdef union Tazzz: Tazzz_Tag tag; - Tazzz_Tag taz5_tag; int32_t taz5; cdef enum: @@ -130,9 +123,7 @@ cdef extern from *: cdef union Tazzzz: Tazzzz_Tag tag; - Tazzzz_Tag taz6_tag; int32_t taz6; - Tazzzz_Tag taz7_tag; uint32_t taz7; cdef enum: @@ -142,9 +133,7 @@ cdef extern from *: cdef union Qux: Qux_Tag tag; - Qux_Tag qux1_tag; int32_t qux1; - Qux_Tag qux2_tag; uint32_t qux2; void root(const Foo_u32 *a, diff --git a/tests/expectations/enum.both.c b/tests/expectations/enum.both.c index 724563e5..4e7d3c0b 100644 --- a/tests/expectations/enum.both.c +++ b/tests/expectations/enum.both.c @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -173,6 +187,44 @@ typedef struct P { }; } P; +typedef enum Q_Tag { + Ok, + Err, +} Q_Tag; + +typedef struct Q { + Q_Tag tag; + union { + struct { + uint32_t *ok; + }; + struct { + uint32_t err; + }; + }; +} Q; + +typedef enum R_Tag { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct IRBar_Body { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct R { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + void root(struct Opaque *opaque, A a, B b, @@ -189,7 +241,9 @@ void root(struct Opaque *opaque, M m, enum N n, O o, - struct P p); + struct P p, + struct Q q, + struct R r); #if __cplusplus #if FALSE diff --git a/tests/expectations/enum.both.compat.c b/tests/expectations/enum.both.compat.c index 9446cc05..aab6a2c4 100644 --- a/tests/expectations/enum.both.compat.c +++ b/tests/expectations/enum.both.compat.c @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -239,6 +253,44 @@ typedef struct P { }; } P; +typedef enum Q_Tag { + Ok, + Err, +} Q_Tag; + +typedef struct Q { + Q_Tag tag; + union { + struct { + uint32_t *ok; + }; + struct { + uint32_t err; + }; + }; +} Q; + +typedef enum R_Tag { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct IRBar_Body { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct R { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -259,7 +311,9 @@ void root(struct Opaque *opaque, M m, enum N n, O o, - struct P p); + struct P p, + struct Q q, + struct R r); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/enum.c b/tests/expectations/enum.c index b5ef6332..5b2cc7cf 100644 --- a/tests/expectations/enum.c +++ b/tests/expectations/enum.c @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -173,6 +187,44 @@ typedef struct { }; } P; +typedef enum { + Ok, + Err, +} Q_Tag; + +typedef struct { + Q_Tag tag; + union { + struct { + uint32_t *ok; + }; + struct { + uint32_t err; + }; + }; +} Q; + +typedef enum { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + void root(Opaque *opaque, A a, B b, @@ -189,7 +241,9 @@ void root(Opaque *opaque, M m, N n, O o, - P p); + P p, + Q q, + R r); #if __cplusplus #if FALSE diff --git a/tests/expectations/enum.compat.c b/tests/expectations/enum.compat.c index 09beb612..43dbfc31 100644 --- a/tests/expectations/enum.compat.c +++ b/tests/expectations/enum.compat.c @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -239,6 +253,44 @@ typedef struct { }; } P; +typedef enum { + Ok, + Err, +} Q_Tag; + +typedef struct { + Q_Tag tag; + union { + struct { + uint32_t *ok; + }; + struct { + uint32_t err; + }; + }; +} Q; + +typedef enum { + IRFoo, + IRBar, + IRBaz, +} R_Tag; + +typedef struct { + uint8_t x; + int16_t y; +} IRBar_Body; + +typedef struct { + R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + IRBar_Body IRBar; + }; +} R; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -259,7 +311,9 @@ void root(Opaque *opaque, M m, N n, O o, - P p); + P p, + Q q, + R r); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/enum.cpp b/tests/expectations/enum.cpp index c3e5b5e3..83e03da2 100644 --- a/tests/expectations/enum.cpp +++ b/tests/expectations/enum.cpp @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -173,6 +187,50 @@ struct P { }; }; +struct Q { + enum class Tag { + Ok, + Err, + }; + + struct Ok_Body { + Box _0; + }; + + struct Err_Body { + uint32_t _0; + }; + + Tag tag; + union { + Ok_Body ok; + Err_Body err; + }; +}; + +struct R { + enum class Tag { + IRFoo, + IRBar, + IRBaz, + }; + + struct IRFoo_Body { + int16_t _0; + }; + + struct IRBar_Body { + uint8_t x; + int16_t y; + }; + + Tag tag; + union { + IRFoo_Body IRFoo; + IRBar_Body IRBar; + }; +}; + extern "C" { void root(Opaque *opaque, @@ -191,7 +249,9 @@ void root(Opaque *opaque, M m, N n, O o, - P p); + P p, + Q q, + R r); } // extern "C" diff --git a/tests/expectations/enum.pyx b/tests/expectations/enum.pyx index 105b8a8c..76ea42b3 100644 --- a/tests/expectations/enum.pyx +++ b/tests/expectations/enum.pyx @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t cdef extern from *: @@ -95,7 +109,6 @@ cdef extern from *: ctypedef union G: G_Tag tag; - G_Tag foo_tag; int16_t foo; Bar_Body bar; @@ -143,6 +156,29 @@ cdef extern from *: uint8_t p0; P1_Body p1; + ctypedef enum Q_Tag: + Ok, + Err, + + ctypedef struct Q: + Q_Tag tag; + uint32_t *ok; + uint32_t err; + + ctypedef enum R_Tag: + IRFoo, + IRBar, + IRBaz, + + ctypedef struct IRBar_Body: + uint8_t x; + int16_t y; + + ctypedef struct R: + R_Tag tag; + int16_t IRFoo; + IRBar_Body IRBar; + void root(Opaque *opaque, A a, B b, @@ -159,7 +195,9 @@ cdef extern from *: M m, N n, O o, - P p); + P p, + Q q, + R r); #if __cplusplus #if FALSE diff --git a/tests/expectations/enum.tag.c b/tests/expectations/enum.tag.c index 1242fd32..59663137 100644 --- a/tests/expectations/enum.tag.c +++ b/tests/expectations/enum.tag.c @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -173,6 +187,44 @@ struct P { }; }; +enum Q_Tag { + Ok, + Err, +}; + +struct Q { + enum Q_Tag tag; + union { + struct { + uint32_t *ok; + }; + struct { + uint32_t err; + }; + }; +}; + +enum R_Tag { + IRFoo, + IRBar, + IRBaz, +}; + +struct IRBar_Body { + uint8_t x; + int16_t y; +}; + +struct R { + enum R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + struct IRBar_Body IRBar; + }; +}; + void root(struct Opaque *opaque, A a, B b, @@ -189,7 +241,9 @@ void root(struct Opaque *opaque, M m, enum N n, O o, - struct P p); + struct P p, + struct Q q, + struct R r); #if __cplusplus #if FALSE diff --git a/tests/expectations/enum.tag.compat.c b/tests/expectations/enum.tag.compat.c index b7251bb2..856cd8e3 100644 --- a/tests/expectations/enum.tag.compat.c +++ b/tests/expectations/enum.tag.compat.c @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + #include #include #include @@ -239,6 +253,44 @@ struct P { }; }; +enum Q_Tag { + Ok, + Err, +}; + +struct Q { + enum Q_Tag tag; + union { + struct { + uint32_t *ok; + }; + struct { + uint32_t err; + }; + }; +}; + +enum R_Tag { + IRFoo, + IRBar, + IRBaz, +}; + +struct IRBar_Body { + uint8_t x; + int16_t y; +}; + +struct R { + enum R_Tag tag; + union { + struct { + int16_t IRFoo; + }; + struct IRBar_Body IRBar; + }; +}; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -259,7 +311,9 @@ void root(struct Opaque *opaque, M m, enum N n, O o, - struct P p); + struct P p, + struct Q q, + struct R r); #ifdef __cplusplus } // extern "C" diff --git a/tests/expectations/enum.tag.pyx b/tests/expectations/enum.tag.pyx index 989ea8b5..844f40a6 100644 --- a/tests/expectations/enum.tag.pyx +++ b/tests/expectations/enum.tag.pyx @@ -1,3 +1,17 @@ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif + + from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t cdef extern from *: @@ -95,7 +109,6 @@ cdef extern from *: cdef union G: G_Tag tag; - G_Tag foo_tag; int16_t foo; Bar_Body bar; @@ -143,6 +156,29 @@ cdef extern from *: uint8_t p0; P1_Body p1; + cdef enum Q_Tag: + Ok, + Err, + + cdef struct Q: + Q_Tag tag; + uint32_t *ok; + uint32_t err; + + cdef enum R_Tag: + IRFoo, + IRBar, + IRBaz, + + cdef struct IRBar_Body: + uint8_t x; + int16_t y; + + cdef struct R: + R_Tag tag; + int16_t IRFoo; + IRBar_Body IRBar; + void root(Opaque *opaque, A a, B b, @@ -159,7 +195,9 @@ cdef extern from *: M m, N n, O o, - P p); + P p, + Q q, + R r); #if __cplusplus #if FALSE diff --git a/tests/expectations/enum_self.pyx b/tests/expectations/enum_self.pyx index dc23d526..556afb9d 100644 --- a/tests/expectations/enum_self.pyx +++ b/tests/expectations/enum_self.pyx @@ -17,9 +17,7 @@ cdef extern from *: ctypedef union Bar: Bar_Tag tag; - Bar_Tag min_tag; Foo_Bar min; - Bar_Tag max_tag; Foo_Bar max; void root(Bar b); diff --git a/tests/expectations/enum_self.tag.pyx b/tests/expectations/enum_self.tag.pyx index a39f4d67..5034b868 100644 --- a/tests/expectations/enum_self.tag.pyx +++ b/tests/expectations/enum_self.tag.pyx @@ -17,9 +17,7 @@ cdef extern from *: cdef union Bar: Bar_Tag tag; - Bar_Tag min_tag; Foo_Bar min; - Bar_Tag max_tag; Foo_Bar max; void root(Bar b); diff --git a/tests/expectations/prefix.pyx b/tests/expectations/prefix.pyx index 0a3ecf34..7d93ed4f 100644 --- a/tests/expectations/prefix.pyx +++ b/tests/expectations/prefix.pyx @@ -24,7 +24,6 @@ cdef extern from *: ctypedef union PREFIX_AbsoluteFontWeight: PREFIX_AbsoluteFontWeight_Tag tag; - PREFIX_AbsoluteFontWeight_Tag weight_tag; float weight; void root(PREFIX_NamedLenArray x, PREFIX_ValuedLenArray y, PREFIX_AbsoluteFontWeight z); diff --git a/tests/expectations/prefix.tag.pyx b/tests/expectations/prefix.tag.pyx index d4c51e48..32f38d98 100644 --- a/tests/expectations/prefix.tag.pyx +++ b/tests/expectations/prefix.tag.pyx @@ -24,7 +24,6 @@ cdef extern from *: cdef union PREFIX_AbsoluteFontWeight: PREFIX_AbsoluteFontWeight_Tag tag; - PREFIX_AbsoluteFontWeight_Tag weight_tag; float weight; void root(PREFIX_NamedLenArray x, PREFIX_ValuedLenArray y, PREFIX_AbsoluteFontWeight z); diff --git a/tests/expectations/rename_case.c b/tests/expectations/rename_case.c new file mode 100644 index 00000000..c5748231 --- /dev/null +++ b/tests/expectations/rename_case.c @@ -0,0 +1,14 @@ +#include +#include +#include +#include + +void test_camel_case(int32_t fooBar); + +void test_pascal_case(int32_t FooBar); + +void test_snake_case(int32_t foo_bar); + +void test_screaming_snake_case(int32_t FOO_BAR); + +void test_gecko_case(int32_t aFooBar); diff --git a/tests/expectations/rename_case.compat.c b/tests/expectations/rename_case.compat.c new file mode 100644 index 00000000..61e3310e --- /dev/null +++ b/tests/expectations/rename_case.compat.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void test_camel_case(int32_t fooBar); + +void test_pascal_case(int32_t FooBar); + +void test_snake_case(int32_t foo_bar); + +void test_screaming_snake_case(int32_t FOO_BAR); + +void test_gecko_case(int32_t aFooBar); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/rename_case.cpp b/tests/expectations/rename_case.cpp new file mode 100644 index 00000000..794fa0cf --- /dev/null +++ b/tests/expectations/rename_case.cpp @@ -0,0 +1,19 @@ +#include +#include +#include +#include +#include + +extern "C" { + +void test_camel_case(int32_t fooBar); + +void test_pascal_case(int32_t FooBar); + +void test_snake_case(int32_t foo_bar); + +void test_screaming_snake_case(int32_t FOO_BAR); + +void test_gecko_case(int32_t aFooBar); + +} // extern "C" diff --git a/tests/expectations/rename_case.pyx b/tests/expectations/rename_case.pyx new file mode 100644 index 00000000..5fd35fc4 --- /dev/null +++ b/tests/expectations/rename_case.pyx @@ -0,0 +1,17 @@ +from libc.stdint cimport int8_t, int16_t, int32_t, int64_t, intptr_t +from libc.stdint cimport uint8_t, uint16_t, uint32_t, uint64_t, uintptr_t +cdef extern from *: + ctypedef bint bool + ctypedef struct va_list + +cdef extern from *: + + void test_camel_case(int32_t fooBar); + + void test_pascal_case(int32_t FooBar); + + void test_snake_case(int32_t foo_bar); + + void test_screaming_snake_case(int32_t FOO_BAR); + + void test_gecko_case(int32_t aFooBar); diff --git a/tests/expectations/transform_op.pyx b/tests/expectations/transform_op.pyx index b53710a8..c35fb427 100644 --- a/tests/expectations/transform_op.pyx +++ b/tests/expectations/transform_op.pyx @@ -30,9 +30,7 @@ cdef extern from *: ctypedef union StyleFoo_i32: StyleFoo_i32_Tag tag; StyleFoo_Body_i32 foo; - StyleFoo_i32_Tag bar_tag; int32_t bar; - StyleFoo_i32_Tag baz_tag; StylePoint_i32 baz; ctypedef enum StyleBar_i32_Tag: @@ -83,9 +81,7 @@ cdef extern from *: ctypedef union StyleBaz: StyleBaz_Tag tag; - StyleBaz_Tag baz1_tag; StyleBar_u32 baz1; - StyleBaz_Tag baz2_tag; StylePoint_i32 baz2; cdef enum: diff --git a/tests/expectations/transform_op.tag.pyx b/tests/expectations/transform_op.tag.pyx index 58899e85..5831bdbd 100644 --- a/tests/expectations/transform_op.tag.pyx +++ b/tests/expectations/transform_op.tag.pyx @@ -30,9 +30,7 @@ cdef extern from *: cdef union StyleFoo_i32: StyleFoo_i32_Tag tag; StyleFoo_Body_i32 foo; - StyleFoo_i32_Tag bar_tag; int32_t bar; - StyleFoo_i32_Tag baz_tag; StylePoint_i32 baz; cdef enum StyleBar_i32_Tag: @@ -83,9 +81,7 @@ cdef extern from *: cdef union StyleBaz: StyleBaz_Tag tag; - StyleBaz_Tag baz1_tag; StyleBar_u32 baz1; - StyleBaz_Tag baz2_tag; StylePoint_i32 baz2; cdef enum: diff --git a/tests/rust/associated_in_body.rs b/tests/rust/associated_in_body.rs index 6c3fe4e2..8c76a13c 100644 --- a/tests/rust/associated_in_body.rs +++ b/tests/rust/associated_in_body.rs @@ -2,7 +2,7 @@ bitflags! { /// Constants shared by multiple CSS Box Alignment properties /// /// These constants match Gecko's `NS_STYLE_ALIGN_*` constants. - #[derive(MallocSizeOf, ToComputedValue)] + #[derive(MallocSizeOf)] #[repr(C)] pub struct AlignFlags: u8 { /// 'auto' @@ -13,10 +13,42 @@ bitflags! { const START = 1 << 1; /// 'end' const END = 1 << 2; + const ALIAS = Self::END.bits; /// 'flex-start' const FLEX_START = 1 << 3; + const MIXED = 1 << 4 | AlignFlags::FLEX_START.bits | AlignFlags::END.bits; + const MIXED_SELF = 1 << 5 | AlignFlags::FLEX_START.bits | AlignFlags::END.bits; } } +/// 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) {} diff --git a/tests/rust/bitflags.rs b/tests/rust/bitflags.rs index 017104a7..013e10b6 100644 --- a/tests/rust/bitflags.rs +++ b/tests/rust/bitflags.rs @@ -2,7 +2,7 @@ bitflags! { /// Constants shared by multiple CSS Box Alignment properties /// /// These constants match Gecko's `NS_STYLE_ALIGN_*` constants. - #[derive(MallocSizeOf, ToComputedValue)] + #[derive(MallocSizeOf)] #[repr(C)] pub struct AlignFlags: u8 { /// 'auto' @@ -13,8 +13,11 @@ bitflags! { const START = 1 << 1; /// 'end' const END = 1 << 2; + const ALIAS = Self::END.bits; /// 'flex-start' const FLEX_START = 1 << 3; + const MIXED = 1 << 4 | AlignFlags::FLEX_START.bits | AlignFlags::END.bits; + const MIXED_SELF = 1 << 5 | AlignFlags::FLEX_START.bits | AlignFlags::END.bits; } } diff --git a/tests/rust/enum.rs b/tests/rust/enum.rs index 562af880..19191ca7 100644 --- a/tests/rust/enum.rs +++ b/tests/rust/enum.rs @@ -127,6 +127,20 @@ enum P { P1(u8, u8, u8), } +#[repr(C)] +enum Q { + Ok(Box), + Err(u32), +} + +/// cbindgen:rename-variant-name-fields=None +#[repr(C)] +enum R { + IRFoo(i16), + IRBar { x: u8, y: i16 }, + IRBaz, +} + #[no_mangle] pub extern "C" fn root( opaque: *mut Opaque, @@ -146,5 +160,7 @@ pub extern "C" fn root( n: N, o: O, p: P, + q: Q, + r: R, ) { } diff --git a/tests/rust/enum.toml b/tests/rust/enum.toml index 5bd5ee19..bb28c590 100644 --- a/tests/rust/enum.toml +++ b/tests/rust/enum.toml @@ -1,3 +1,18 @@ +header = """ +#if 0 +''' ' +#endif + +#ifdef __cplusplus +template +using Box = T*; +#endif + +#if 0 +' ''' +#endif +""" + trailer = """ #if __cplusplus #if FALSE @@ -20,5 +35,10 @@ static_assert(sizeof(CBINDGEN_STRUCT(P)) == 4, "unexpected size for P"); [csharp] trailer = "" +[export] +exclude = [ + "Box", +] + [export.rename] "I" = "ExI" diff --git a/tests/rust/rename_case.rs b/tests/rust/rename_case.rs new file mode 100644 index 00000000..e83227d0 --- /dev/null +++ b/tests/rust/rename_case.rs @@ -0,0 +1,19 @@ +/// cbindgen:rename-all=CamelCase +#[no_mangle] +pub extern "C" fn test_camel_case(foo_bar: i32) {} + +/// cbindgen:rename-all=PascalCase +#[no_mangle] +pub extern "C" fn test_pascal_case(foo_bar: i32) {} + +/// cbindgen:rename-all=SnakeCase +#[no_mangle] +pub extern "C" fn test_snake_case(foo_bar: i32) {} + +/// cbindgen:rename-all=ScreamingSnakeCase +#[no_mangle] +pub extern "C" fn test_screaming_snake_case(foo_bar: i32) {} + +/// cbindgen:rename-all=GeckoCase +#[no_mangle] +pub extern "C" fn test_gecko_case(foo_bar: i32) {}