diff --git a/Cargo.lock b/Cargo.lock index 823050339acc..2c2b981f542d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -409,9 +409,16 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.63.0" +version = "0.63.999" +dependencies = [ + "bindgen 0.64.0", +] + +[[package]] +name = "bindgen" +version = "0.64.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" +checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4" dependencies = [ "bitflags", "cexpr", @@ -427,13 +434,6 @@ dependencies = [ "syn", ] -[[package]] -name = "bindgen" -version = "0.64.999" -dependencies = [ - "bindgen 0.63.0", -] - [[package]] name = "bit-set" version = "0.5.3" @@ -553,7 +553,7 @@ dependencies = [ name = "builtins-static" version = "0.1.0" dependencies = [ - "bindgen 0.63.0", + "bindgen 0.64.0", "nom", "pkcs11-bindings", "smallvec", @@ -858,7 +858,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f034b2258e6c4ade2f73bf87b21047567fb913ee9550837c2316d139b0262b24" dependencies = [ - "bindgen 0.64.999", + "bindgen 0.64.0", ] [[package]] @@ -1947,7 +1947,7 @@ name = "gecko-profiler" version = "0.1.0" dependencies = [ "bincode", - "bindgen 0.63.0", + "bindgen 0.64.0", "lazy_static", "mozbuild", "profiler-macros", @@ -2479,7 +2479,7 @@ name = "http3server" version = "0.1.1" dependencies = [ "base64", - "bindgen 0.63.0", + "bindgen 0.64.0", "cfg-if 1.0.0", "http", "hyper", @@ -3379,7 +3379,7 @@ dependencies = [ name = "mozilla-central-workspace-hack" version = "0.1.0" dependencies = [ - "bindgen 0.63.0", + "bindgen 0.64.0", "libc", "quote", "serde", @@ -3513,7 +3513,7 @@ name = "neqo-crypto" version = "0.6.4" source = "git+https://github.com/mozilla/neqo?tag=v0.6.4#80db3a01f3273c7e742ba560fa99246fc8b30c4f" dependencies = [ - "bindgen 0.63.0", + "bindgen 0.63.999", "log", "mozbuild", "neqo-common", @@ -3657,7 +3657,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a689b62ba71fda80458a77b6ace9371d6e6a5473300901383ebd101659b3352" dependencies = [ - "bindgen 0.64.999", + "bindgen 0.64.0", "mozbuild", "once_cell", "pkcs11-bindings", @@ -3780,7 +3780,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "850ce328ec7e4dc1a9446c56aef700d21d914268c8529b96017a2bf10f74b70f" dependencies = [ - "bindgen 0.63.0", + "bindgen 0.63.999", "byteorder", "hex", "lazy_static", @@ -4036,7 +4036,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0fabbdbe64b22820753da90995b3a73d02907eaeeac6f2414962a566aaa18ea" dependencies = [ - "bindgen 0.64.999", + "bindgen 0.64.0", ] [[package]] @@ -4953,7 +4953,7 @@ dependencies = [ "app_units", "arrayvec", "atomic_refcell", - "bindgen 0.63.0", + "bindgen 0.64.0", "bitflags", "byteorder", "cssparser", diff --git a/Cargo.toml b/Cargo.toml index dac9a756b153..8ed8aade13ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -118,7 +118,7 @@ tinyvec = { path = "build/rust/tinyvec" } # Patch wasi 0.10 to 0.11 wasi = { path = "build/rust/wasi" } -# Patch bindgen 0.64 to 0.63 +# Patch bindgen 0.63 to 0.64 bindgen = { path = "build/rust/bindgen" } # Patch memoffset 0.6 to 0.7 diff --git a/build/rust/bindgen/Cargo.toml b/build/rust/bindgen/Cargo.toml index af365b4a0505..b68e2eb6bba9 100644 --- a/build/rust/bindgen/Cargo.toml +++ b/build/rust/bindgen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "bindgen" -version = "0.64.999" +version = "0.63.999" edition = "2018" license = "BSD-3-Clause" @@ -8,7 +8,7 @@ license = "BSD-3-Clause" path = "lib.rs" [dependencies.bindgen] -version = "0.63.0" +version = "0.64.0" default-features = false [features] diff --git a/build/workspace-hack/Cargo.toml b/build/workspace-hack/Cargo.toml index d002114ec82c..fe68dc42e92f 100644 --- a/build/workspace-hack/Cargo.toml +++ b/build/workspace-hack/Cargo.toml @@ -33,7 +33,7 @@ serde = { features = ["default", "derive", "rc", "serde_derive", "std"], version serde_derive = { features = ["default", "deserialize_in_place"], version = "1.0.66" } quote = { features = ["default", "proc-macro"], version = "1.0" } libc = { features = ["default", "std", "use_std"], version = "0.2" } -bindgen = { default-features = false, features = ["runtime"], version = "0.63" } +bindgen = { default-features = false, features = ["runtime"], version = "0.64" } [target."cfg(windows)".dependencies.winapi] version = "0.3.6" diff --git a/netwerk/test/http3server/Cargo.toml b/netwerk/test/http3server/Cargo.toml index 683a9e1202d0..b6c2760a1933 100644 --- a/netwerk/test/http3server/Cargo.toml +++ b/netwerk/test/http3server/Cargo.toml @@ -27,7 +27,7 @@ features = ["gecko"] # Make sure to use bindgen's runtime-loading of libclang, as it allows for a wider range of clang versions to be used [build-dependencies] -bindgen = {version = "0.63", default-features = false, features = ["runtime"] } +bindgen = {version = "0.64", default-features = false, features = ["runtime"] } [[bin]] name = "http3server" diff --git a/security/manager/ssl/builtins/Cargo.toml b/security/manager/ssl/builtins/Cargo.toml index 47e88b68a990..df54db849119 100644 --- a/security/manager/ssl/builtins/Cargo.toml +++ b/security/manager/ssl/builtins/Cargo.toml @@ -10,7 +10,7 @@ pkcs11-bindings = "0.1.1" smallvec = { version = "1.9.0", features = ["const_new"] } [build-dependencies] -bindgen = { default-features = false, features = ["runtime"], version = "0.63" } +bindgen = { default-features = false, features = ["runtime"], version = "0.64" } nom = "7.1.1" [lib] diff --git a/servo/components/style/Cargo.toml b/servo/components/style/Cargo.toml index 8975054dd1bd..75f7c9f87710 100644 --- a/servo/components/style/Cargo.toml +++ b/servo/components/style/Cargo.toml @@ -82,7 +82,7 @@ gecko-profiler = { path = "../../../tools/profiler/rust-api" } [build-dependencies] lazy_static = "1" log = { version = "0.4", features = ["std"] } -bindgen = {version = "0.63", optional = true, default-features = false} +bindgen = {version = "0.64", optional = true, default-features = false} regex = {version = "1.0", optional = true, default-features = false, features = ["perf", "std"]} walkdir = "2.1.4" toml = {version = "0.5", optional = true, default-features = false} diff --git a/supply-chain/audits.toml b/supply-chain/audits.toml index 0510827882b8..b784aa9d3878 100644 --- a/supply-chain/audits.toml +++ b/supply-chain/audits.toml @@ -243,6 +243,11 @@ who = "Emilio Cobos Álvarez " criteria = "safe-to-deploy" delta = "0.59.2 -> 0.63.0" +[[audits.bindgen]] +who = "Mike Hommey " +criteria = "safe-to-deploy" +delta = "0.63.0 -> 0.64.0" + [[audits.bit-set]] who = "Aria Beingessner " criteria = "safe-to-deploy" diff --git a/third_party/rust/bindgen/.cargo-checksum.json b/third_party/rust/bindgen/.cargo-checksum.json index fbf4d072c9c1..2242180f9e86 100644 --- a/third_party/rust/bindgen/.cargo-checksum.json +++ b/third_party/rust/bindgen/.cargo-checksum.json @@ -1 +1 @@ -{"files":{"Cargo.toml":"973fd894e8985b9b1fda4bf34f0e71af54d69a61fe6d8b7f1bbe443eb5863bcc","LICENSE":"c23953d9deb0a3312dbeaf6c128a657f3591acee45067612fa68405eaa4525db","README.md":"cabc15d1a4d23868718052a4e5eaa1fd3f493ef6fb16c499210a48588651a805","build.rs":"4a9c4ac3759572e17de312a9d3f4ced3b6fd3c71811729e5a8d06bfbd1ac8f82","callbacks.rs":"aa3d8789241e965eb07a0103c5fd7b81091431458d83c2eaa9611c3d54e909f2","clang.rs":"a38d153516c6685b46723010793b2f4e8b16468f3cd3296781dea6e485cd66da","codegen/bitfield_unit.rs":"fddeaeab5859f4e82081865595b7705f5c0774d997df95fa5c655b81b9cae125","codegen/bitfield_unit_tests.rs":"9df86490de5e9d66ccea583dcb686dd440375dc1a3c3cf89a89d5de3883bf28a","codegen/dyngen.rs":"dd50fa3b4eaa5f4e479d4755cf109961e1fcd99fb32c93316da1f8eab80f37d9","codegen/error.rs":"5e308b8c54b68511fc8ea2ad15ddac510172c4ff460a80a265336440b0c9653d","codegen/helpers.rs":"5f24007a09e50db7bd2b49b07100cfed649c7b22232558e28c99c759d5d14152","codegen/impl_debug.rs":"71d8e28873ba2de466f2637a824746963702f0511728037d72ee5670c51194cb","codegen/impl_partialeq.rs":"f4599e32c66179ae515a6518a3e94b686689cf59f7dd9ab618c3fb69f17d2c77","codegen/mod.rs":"b35b9371266633e8d813aa8bc4c44ee49cacf1b6e740973db252481c0d3799c4","codegen/postprocessing/merge_extern_blocks.rs":"be5c5ff6d3d3d4e940814c4dc77f8d687aa6b053dcfbd2185c09616ba9022bf2","codegen/postprocessing/mod.rs":"d1e8c2864d5194a4cb2f6731c0ef582a55b363df9c4f888c26942ff37f728e1c","codegen/postprocessing/sort_semantically.rs":"3071dd509f2e5d3dfd99cafa6ee19bbacb9fec1c61a0b3f6e284a75c1f2c3db6","codegen/struct_layout.rs":"7dfc814d3c914a0c53d8ed031baf543dab1def5959e8ab85220cad69a506383a","deps.rs":"5ee2332fdb10325f3b0a0c6d9ba94e13eb631ef39e955fa958afc3625bdb5448","extra_assertions.rs":"494534bd4f18b80d89b180c8a93733e6617edcf7deac413e9a73fd6e7bc9ced7","features.rs":"af20bd617cce27f6716ab3d61a1c8ddfaa46227f4a0d435b08a19d5f277cf8ba","ir/analysis/derive.rs":"ec514585eb40f0e3306bf3302aec0152a2e95e8dce13a67c36b5f00c0cbb76ef","ir/analysis/has_destructor.rs":"7a82f01e7e0595a31b56f7c398fa3019b3fe9100a2a73b56768f7e6943dcc3ce","ir/analysis/has_float.rs":"58ea1e38a59ef208400fd65d426cb5b288949df2d383b3a194fa01b99d2a87fa","ir/analysis/has_type_param_in_array.rs":"d1b9eb119dc14f662eb9bd1394c859f485479e4912589709cdd33f6752094e22","ir/analysis/has_vtable.rs":"368cf30fbe3fab7190fab48718b948caac5da8c9e797b709488716b919315636","ir/analysis/mod.rs":"0c10d8eeb26d7e6f4ce18e9dfb74ea1f9deff5cd350298aca3dc1041b17c20c4","ir/analysis/sizedness.rs":"944443d6aab35d2dd80e4f5e59176ac1e1c463ba2f0eb25d33f1d95dfac1a6d0","ir/analysis/template_params.rs":"a2d2e247c2f51cd90e83f11bce0305c2e498232d015f88192b44e8522e7fd8b1","ir/annotations.rs":"f79de09803a3f3ccb33e366a10a707da98cd00a56ba18312ea927d6c977220a4","ir/comment.rs":"5dcfab0095d967daad9b2927093fce3786b1a2146171580afbf526ba56855e36","ir/comp.rs":"8a96d6760c988d35e07462d66975218fbf3121902d313d71c553f2b473d37bc8","ir/context.rs":"ee5606460afff17c2fcfbd72779edb6038b6ba390e8b7a5b2ccb694acb7036cb","ir/derive.rs":"e5581852eec87918901a129284b4965aefc8a19394187a8095779a084f28fabe","ir/dot.rs":"2d79d698e6ac59ce032840e62ff11103abed1d5e9e700cf383b492333eeebe1f","ir/enum_ty.rs":"13c1de2d0668f811ea1f3353c77c892e475b2e6f5935f6a0b7f711c0ffa64c21","ir/function.rs":"36d9967cf9cd28352b682747376c5e4ef5f679eff9907b670edd2c670058bbce","ir/int.rs":"68a86182743ec338d58e42203364dc7c8970cb7ec3550433ca92f0c9489b4442","ir/item.rs":"6098bceb8d98fe72e1442ea71d36a5eabfdb153aa767527d235b654f912a9333","ir/item_kind.rs":"7666a1ff1b8260978b790a08b4139ab56b5c65714a5652bbcec7faa7443adc36","ir/layout.rs":"61a0e4250ceab889606973f930f4d692837a13a69ae2579738ff09843fed3d65","ir/mod.rs":"713cd537434567003197a123cbae679602c715e976d22f7b23dafd0826ea4c70","ir/module.rs":"7cae5561bcf84a5c3b1ee8f1c3336a33b7f44f0d5ffe885fb108289983fe763e","ir/objc.rs":"dd394c1db6546cbe5111ce5cd2f211f9839aba81c5e7228c2a68fba386bc259f","ir/template.rs":"3bb3e7f6ec28eff73c2032922d30b93d70da117b848e9cb02bdf6c9a74294f7f","ir/traversal.rs":"0c37a0898801ad39bffc8dddd1ee8baa61bb7cf4f3fdc25c8fdd56b6c96ada65","ir/ty.rs":"d910af9f9cc67513914f71553ea2f493562ea8cc20117cb17b7658fe5d670caf","ir/var.rs":"f3ffbfc26de1dc6e23fa46a156f98aec1c6b339dbd7627934a4ec57332a25650","lib.rs":"0edba5c8926ff08c6ae8ca5c64cb6ed89acf0d358f3bb6fa0eb0fc4f0f055f01","log_stubs.rs":"9f974e041e35c8c7e29985d27ae5cd0858d68f8676d1dc005c6388d7d011707f","parse.rs":"4ffc54415eadb622ee488603862788c78361ef2c889de25259441a340c2a010f","regex_set.rs":"ead517110d8ef80e222326d000a4f02b9bd2ce99b58a514ee90b89f0042f6a81","time.rs":"8efe317e7c6b5ba8e0865ce7b49ca775ee8a02590f4241ef62f647fa3c22b68e"},"package":"36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"} \ No newline at end of file +{"files":{"Cargo.toml":"ae6de5b309f8bf07c259436b1113ccf405b2d7dd862e1b289bfef47a550956d1","LICENSE":"c23953d9deb0a3312dbeaf6c128a657f3591acee45067612fa68405eaa4525db","build.rs":"4a9c4ac3759572e17de312a9d3f4ced3b6fd3c71811729e5a8d06bfbd1ac8f82","callbacks.rs":"9cbda648159897f93a07dbe90a1ee9ba92e2b020a02bc9725b87db4d025df3b6","clang.rs":"a38d153516c6685b46723010793b2f4e8b16468f3cd3296781dea6e485cd66da","codegen/bitfield_unit.rs":"fddeaeab5859f4e82081865595b7705f5c0774d997df95fa5c655b81b9cae125","codegen/bitfield_unit_tests.rs":"9df86490de5e9d66ccea583dcb686dd440375dc1a3c3cf89a89d5de3883bf28a","codegen/dyngen.rs":"7d727a737c616f7f2d3a07d825be8baad9078b3f35ad96277904559b4534ffcc","codegen/error.rs":"5e308b8c54b68511fc8ea2ad15ddac510172c4ff460a80a265336440b0c9653d","codegen/helpers.rs":"5f24007a09e50db7bd2b49b07100cfed649c7b22232558e28c99c759d5d14152","codegen/impl_debug.rs":"71d8e28873ba2de466f2637a824746963702f0511728037d72ee5670c51194cb","codegen/impl_partialeq.rs":"f4599e32c66179ae515a6518a3e94b686689cf59f7dd9ab618c3fb69f17d2c77","codegen/mod.rs":"25ef86b9dd894b40724d78b99e2743654f09bb427a23ccf5940a620c6408688e","codegen/postprocessing/merge_extern_blocks.rs":"be5c5ff6d3d3d4e940814c4dc77f8d687aa6b053dcfbd2185c09616ba9022bf2","codegen/postprocessing/mod.rs":"d1e8c2864d5194a4cb2f6731c0ef582a55b363df9c4f888c26942ff37f728e1c","codegen/postprocessing/sort_semantically.rs":"3071dd509f2e5d3dfd99cafa6ee19bbacb9fec1c61a0b3f6e284a75c1f2c3db6","codegen/serialize.rs":"b1d8fff0bd9717ee7ca883fd3f376cf7b93adb65dc5bb89ede467b087e985a5f","codegen/struct_layout.rs":"7dfc814d3c914a0c53d8ed031baf543dab1def5959e8ab85220cad69a506383a","deps.rs":"5ee2332fdb10325f3b0a0c6d9ba94e13eb631ef39e955fa958afc3625bdb5448","extra_assertions.rs":"494534bd4f18b80d89b180c8a93733e6617edcf7deac413e9a73fd6e7bc9ced7","features.rs":"af20bd617cce27f6716ab3d61a1c8ddfaa46227f4a0d435b08a19d5f277cf8ba","ir/analysis/derive.rs":"ec514585eb40f0e3306bf3302aec0152a2e95e8dce13a67c36b5f00c0cbb76ef","ir/analysis/has_destructor.rs":"7a82f01e7e0595a31b56f7c398fa3019b3fe9100a2a73b56768f7e6943dcc3ce","ir/analysis/has_float.rs":"58ea1e38a59ef208400fd65d426cb5b288949df2d383b3a194fa01b99d2a87fa","ir/analysis/has_type_param_in_array.rs":"d1b9eb119dc14f662eb9bd1394c859f485479e4912589709cdd33f6752094e22","ir/analysis/has_vtable.rs":"368cf30fbe3fab7190fab48718b948caac5da8c9e797b709488716b919315636","ir/analysis/mod.rs":"0c10d8eeb26d7e6f4ce18e9dfb74ea1f9deff5cd350298aca3dc1041b17c20c4","ir/analysis/sizedness.rs":"944443d6aab35d2dd80e4f5e59176ac1e1c463ba2f0eb25d33f1d95dfac1a6d0","ir/analysis/template_params.rs":"d3cc41041b1c45e0b5be2c9f3f1cc0c2341481b9ff51589cba2428df4e6a1ea9","ir/annotations.rs":"f79de09803a3f3ccb33e366a10a707da98cd00a56ba18312ea927d6c977220a4","ir/comment.rs":"5dcfab0095d967daad9b2927093fce3786b1a2146171580afbf526ba56855e36","ir/comp.rs":"b7b28b96e4206b3215881d814661c63c5dd182f34b1163d54bcedbe85998cb06","ir/context.rs":"a7608f7d3dd607647f2af5f45fc7c09483d2a694f91265bba353a71652e2d419","ir/derive.rs":"e5581852eec87918901a129284b4965aefc8a19394187a8095779a084f28fabe","ir/dot.rs":"2d79d698e6ac59ce032840e62ff11103abed1d5e9e700cf383b492333eeebe1f","ir/enum_ty.rs":"0b612e0b57112068455eee519f894016d0a8f425d6a67b98c56b858f57d99f4a","ir/function.rs":"60407267473d785ea33ac854a70c8ca34749bc868024270992deca68a951f74c","ir/int.rs":"68a86182743ec338d58e42203364dc7c8970cb7ec3550433ca92f0c9489b4442","ir/item.rs":"880c982df0843cbdff38b9f9c3829a2d863a224e4de2260c41c3ac69e9148ad4","ir/item_kind.rs":"7666a1ff1b8260978b790a08b4139ab56b5c65714a5652bbcec7faa7443adc36","ir/layout.rs":"61a0e4250ceab889606973f930f4d692837a13a69ae2579738ff09843fed3d65","ir/mod.rs":"713cd537434567003197a123cbae679602c715e976d22f7b23dafd0826ea4c70","ir/module.rs":"7cae5561bcf84a5c3b1ee8f1c3336a33b7f44f0d5ffe885fb108289983fe763e","ir/objc.rs":"4eecdb754542d78acea27d2f547d18d49164047e6efaff8a8d283d6c2dc9875b","ir/template.rs":"4f0e3736558aa8ec359cd9749dc48f87bfff494dd195a67b39cfee7d8a7542ef","ir/traversal.rs":"0c37a0898801ad39bffc8dddd1ee8baa61bb7cf4f3fdc25c8fdd56b6c96ada65","ir/ty.rs":"ba0d7b16a1080caf4960cc7dea0d0800365da0dd5c6e735d508ec448e87b1d40","ir/var.rs":"ced3496cf0683fef91ce94aa09b0ee37255db8425ea8634d52bd73b1b5c160f6","lib.rs":"0bed6f10b2dd25753a40e6e7fa11239f08c05be414ad264c6d7e2f7a8b71f1b2","log_stubs.rs":"9f974e041e35c8c7e29985d27ae5cd0858d68f8676d1dc005c6388d7d011707f","parse.rs":"ccb2c506f08123708ae673b8216404fb22b4c951330662f9b7140b412b063260","regex_set.rs":"7dcc1ad52194f057ea00e8ebc9c23c465ffa6761eed6ba41560d2d02e03c43a6","time.rs":"8efe317e7c6b5ba8e0865ce7b49ca775ee8a02590f4241ef62f647fa3c22b68e"},"package":"c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"} \ No newline at end of file diff --git a/third_party/rust/bindgen/Cargo.toml b/third_party/rust/bindgen/Cargo.toml index 2fa903ab84d2..15868cd50ebc 100644 --- a/third_party/rust/bindgen/Cargo.toml +++ b/third_party/rust/bindgen/Cargo.toml @@ -11,9 +11,9 @@ [package] edition = "2018" -rust-version = "1.57.0" +rust-version = "1.60.0" name = "bindgen" -version = "0.63.0" +version = "0.64.0" authors = [ "Jyun-Yan You ", "Emilio Cobos Álvarez ", @@ -24,7 +24,7 @@ build = "build.rs" description = "Automatically generates Rust FFI bindings to C and C++ libraries." homepage = "https://rust-lang.github.io/rust-bindgen/" documentation = "https://docs.rs/bindgen" -readme = "README.md" +readme = "../README.md" keywords = [ "bindings", "ffi", @@ -100,11 +100,13 @@ optional = true default-features = false [features] +cli = [] default = [ "logging", "runtime", "which-rustfmt", ] +experimental = [] logging = ["log"] runtime = ["clang-sys/runtime"] static = ["clang-sys/static"] diff --git a/third_party/rust/bindgen/README.md b/third_party/rust/bindgen/README.md deleted file mode 100644 index c78f00dd4479..000000000000 --- a/third_party/rust/bindgen/README.md +++ /dev/null @@ -1,85 +0,0 @@ -[![crates.io](https://img.shields.io/crates/v/bindgen.svg)](https://crates.io/crates/bindgen) -[![docs.rs](https://docs.rs/bindgen/badge.svg)](https://docs.rs/bindgen/) - -# `bindgen` - -**`bindgen` automatically generates Rust FFI bindings to C (and some C++) libraries.** - -For example, given the C header `doggo.h`: - -```c -typedef struct Doggo { - int many; - char wow; -} Doggo; - -void eleven_out_of_ten_majestic_af(Doggo* pupper); -``` - -`bindgen` produces Rust FFI code allowing you to call into the `doggo` library's -functions and use its types: - -```rust -/* automatically generated by rust-bindgen 0.99.9 */ - -#[repr(C)] -pub struct Doggo { - pub many: ::std::os::raw::c_int, - pub wow: ::std::os::raw::c_char, -} - -extern "C" { - pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo); -} -``` - -## Users Guide - -[📚 Read the `bindgen` users guide here! 📚](https://rust-lang.github.io/rust-bindgen) - -## MSRV - -The minimum supported Rust version is **1.57.0**. - -No MSRV bump policy has been established yet, so MSRV may increase in any release. - -The MSRV is the minimum Rust version that can be used to *compile* `bindgen`. However, `bindgen` can generate bindings that are compatible with Rust versions below the current MSRV. - -## API Reference - -[API reference documentation is on docs.rs](https://docs.rs/bindgen) - -## Environment Variables - -In addition to the [library API](https://docs.rs/bindgen) and [executable command-line API][bindgen-cmdline], -`bindgen` can be controlled through environment variables. - -End-users should set these environment variables to modify `bindgen`'s behavior without modifying the source code of direct consumers of `bindgen`. - -- `BINDGEN_EXTRA_CLANG_ARGS`: extra arguments to pass to `clang` - - Arguments are whitespace-separated - - Use shell-style quoting to pass through whitespace - - Examples: - - Specify alternate sysroot: `--sysroot=/path/to/sysroot` - - Add include search path with spaces: `-I"/path/with spaces"` -- `BINDGEN_EXTRA_CLANG_ARGS_`: similar to `BINDGEN_EXTRA_CLANG_ARGS`, - but used to set per-target arguments to pass to clang. Useful to set system include - directories in a target-specific way in cross-compilation environments with multiple targets. - Has precedence over `BINDGEN_EXTRA_CLANG_ARGS`. - -Additionally, `bindgen` uses `libclang` to parse C and C++ header files. -To modify how `bindgen` searches for `libclang`, see the [`clang-sys` documentation][clang-sys-env]. -For more details on how `bindgen` uses `libclang`, see the [`bindgen` users guide][bindgen-book-clang]. - -## Releases - -We don't follow a specific release calendar, but if you need a release please -file an issue requesting that (ping `@emilio` for increased effectiveness). - -## Contributing - -[See `CONTRIBUTING.md` for hacking on `bindgen`!](./CONTRIBUTING.md) - -[bindgen-cmdline]: https://rust-lang.github.io/rust-bindgen/command-line-usage.html -[clang-sys-env]: https://github.com/KyleMayes/clang-sys#environment-variables -[bindgen-book-clang]: https://rust-lang.github.io/rust-bindgen/requirements.html#clang diff --git a/third_party/rust/bindgen/callbacks.rs b/third_party/rust/bindgen/callbacks.rs index 5e8ac78839e9..dc20e2581e15 100644 --- a/third_party/rust/bindgen/callbacks.rs +++ b/third_party/rust/bindgen/callbacks.rs @@ -25,14 +25,23 @@ impl Default for MacroParsingBehavior { /// A trait to allow configuring different kinds of types in different /// situations. pub trait ParseCallbacks: fmt::Debug { + #[cfg(feature = "cli")] + #[doc(hidden)] + fn cli_args(&self) -> Vec { + vec![] + } + /// This function will be run on every macro that is identified. fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { MacroParsingBehavior::Default } - /// This function will run for every function. The returned value determines the name visible - /// in the bindings. - fn generated_name_override(&self, _function_name: &str) -> Option { + /// This function will run for every extern variable and function. The returned value determines + /// the name visible in the bindings. + fn generated_name_override( + &self, + _item_info: ItemInfo<'_>, + ) -> Option { None } @@ -117,8 +126,40 @@ pub trait ParseCallbacks: fmt::Debug { /// Relevant information about a type to which new derive attributes will be added using /// [`ParseCallbacks::add_derives`]. +#[derive(Debug)] #[non_exhaustive] pub struct DeriveInfo<'a> { /// The name of the type. pub name: &'a str, + /// The kind of the type. + pub kind: TypeKind, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +/// The kind of the current type. +pub enum TypeKind { + /// The type is a Rust `struct`. + Struct, + /// The type is a Rust `enum`. + Enum, + /// The type is a Rust `union`. + Union, +} + +/// An struct providing information about the item being passed to `ParseCallbacks::generated_name_override`. +#[non_exhaustive] +pub struct ItemInfo<'a> { + /// The name of the item + pub name: &'a str, + /// The kind of item + pub kind: ItemKind, +} + +/// An enum indicating the kind of item for an ItemInfo. +#[non_exhaustive] +pub enum ItemKind { + /// A Function + Function, + /// A Variable + Var, } diff --git a/third_party/rust/bindgen/codegen/dyngen.rs b/third_party/rust/bindgen/codegen/dyngen.rs index 5e734ccd1590..d8ea81175e26 100644 --- a/third_party/rust/bindgen/codegen/dyngen.rs +++ b/third_party/rust/bindgen/codegen/dyngen.rs @@ -170,7 +170,7 @@ impl DynamicItems { if !is_variadic { self.struct_implementation.push(quote! { #(#attributes)* - pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { + pub unsafe fn #ident ( &self, #( #args ),* ) #ret_ty { #call_body } }); diff --git a/third_party/rust/bindgen/codegen/mod.rs b/third_party/rust/bindgen/codegen/mod.rs index e537242710b9..b6fb70eb01be 100644 --- a/third_party/rust/bindgen/codegen/mod.rs +++ b/third_party/rust/bindgen/codegen/mod.rs @@ -4,6 +4,7 @@ mod helpers; mod impl_debug; mod impl_partialeq; mod postprocessing; +mod serialize; pub mod struct_layout; #[cfg(test)] @@ -18,6 +19,7 @@ use self::struct_layout::StructLayoutTracker; use super::BindgenOptions; +use crate::callbacks::{DeriveInfo, TypeKind as DeriveTypeKind}; use crate::ir::analysis::{HasVtable, Sizedness}; use crate::ir::annotations::FieldAccessorKind; use crate::ir::comp::{ @@ -58,6 +60,29 @@ use std::iter; use std::ops; use std::str::FromStr; +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum CodegenError { + Serialize { msg: String, loc: String }, + Io(String), +} + +impl From for CodegenError { + fn from(err: std::io::Error) -> Self { + Self::Io(err.to_string()) + } +} + +impl std::fmt::Display for CodegenError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CodegenError::Serialize { msg, loc } => { + write!(f, "serialization error at {}: {}", loc, msg) + } + CodegenError::Io(err) => err.fmt(f), + } + } +} + // Name of type defined in constified enum module pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type"; @@ -240,6 +265,8 @@ struct CodegenResult<'a> { /// function name to the number of overloads we have already codegen'd for /// that name. This lets us give each overload a unique suffix. overload_counters: HashMap, + + items_to_serialize: Vec, } impl<'a> CodegenResult<'a> { @@ -257,6 +284,7 @@ impl<'a> CodegenResult<'a> { functions_seen: Default::default(), vars_seen: Default::default(), overload_counters: Default::default(), + items_to_serialize: Default::default(), } } @@ -434,10 +462,10 @@ trait CodeGenerator { /// Extra information returned to the caller. type Return; - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, extra: &Self::Extra, ) -> Self::Return; } @@ -477,10 +505,10 @@ impl CodeGenerator for Item { type Extra = (); type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, _extra: &(), ) { debug!("::codegen: self = {:?}", self); @@ -509,10 +537,10 @@ impl CodeGenerator for Module { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { debug!("::codegen: item = {:?}", item); @@ -601,10 +629,10 @@ impl CodeGenerator for Var { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { use crate::ir::var::VarType; @@ -748,10 +776,10 @@ impl CodeGenerator for Type { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { debug!("::codegen: item = {:?}", item); @@ -1069,10 +1097,10 @@ impl<'a> CodeGenerator for Vtable<'a> { type Extra = Item; type Return = (); - fn codegen<'b>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'b>, + result: &mut CodegenResult<'_>, item: &Item, ) { assert_eq!(item.id(), self.item_id); @@ -1168,10 +1196,10 @@ impl CodeGenerator for TemplateInstantiation { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { debug_assert!(item.is_enabled_for_codegen(ctx)); @@ -1796,10 +1824,10 @@ impl CodeGenerator for CompInfo { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { debug!("::codegen: item = {:?}", item); @@ -2100,11 +2128,18 @@ impl CodeGenerator for CompInfo { let mut derives: Vec<_> = derivable_traits.into(); derives.extend(item.annotations().derives().iter().map(String::as_str)); + let is_rust_union = is_union && struct_layout.is_rust_union(); + // The custom derives callback may return a list of derive attributes; // add them to the end of the list. let custom_derives = ctx.options().all_callbacks(|cb| { - cb.add_derives(&crate::callbacks::DeriveInfo { + cb.add_derives(&DeriveInfo { name: &canonical_name, + kind: if is_rust_union { + DeriveTypeKind::Union + } else { + DeriveTypeKind::Struct + }, }) }); // In most cases this will be a no-op, since custom_derives will be empty. @@ -2118,7 +2153,7 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::must_use()); } - let mut tokens = if is_union && struct_layout.is_rust_union() { + let mut tokens = if is_rust_union { quote! { #( #attributes )* pub union #canonical_ident @@ -2193,16 +2228,7 @@ impl CodeGenerator for CompInfo { }) }; - // FIXME when [issue #465](https://github.com/rust-lang/rust-bindgen/issues/465) ready - let too_many_base_vtables = self - .base_members() - .iter() - .filter(|base| base.ty.has_vtable(ctx)) - .count() > - 1; - - let should_skip_field_offset_checks = - is_opaque || too_many_base_vtables; + let should_skip_field_offset_checks = is_opaque; let check_field_offset = if should_skip_field_offset_checks { @@ -2406,24 +2432,13 @@ impl CodeGenerator for CompInfo { } } -trait MethodCodegen { - fn codegen_method<'a>( +impl Method { + fn codegen_method( &self, ctx: &BindgenContext, methods: &mut Vec, method_names: &mut HashSet, - result: &mut CodegenResult<'a>, - parent: &CompInfo, - ); -} - -impl MethodCodegen for Method { - fn codegen_method<'a>( - &self, - ctx: &BindgenContext, - methods: &mut Vec, - method_names: &mut HashSet, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, _parent: &CompInfo, ) { assert!({ @@ -2720,6 +2735,7 @@ impl<'a> EnumBuilder<'a> { mut attrs: Vec, repr: proc_macro2::TokenStream, enum_variation: EnumVariation, + has_typedef: bool, ) -> Self { let ident = Ident::new(name, Span::call_site()); @@ -2752,10 +2768,12 @@ impl<'a> EnumBuilder<'a> { EnumVariation::Consts => { let mut variants = Vec::new(); - variants.push(quote! { - #( #attrs )* - pub type #ident = #repr; - }); + if !has_typedef { + variants.push(quote! { + #( #attrs )* + pub type #ident = #repr; + }); + } EnumBuilder::Consts { variants } } @@ -2779,13 +2797,13 @@ impl<'a> EnumBuilder<'a> { } /// Add a variant to this enum. - fn with_variant<'b>( + fn with_variant( self, ctx: &BindgenContext, variant: &EnumVariant, mangling_prefix: Option<&str>, rust_ty: proc_macro2::TokenStream, - result: &mut CodegenResult<'b>, + result: &mut CodegenResult<'_>, is_ty_named: bool, ) -> Self { let variant_name = ctx.rust_mangle(variant.name()); @@ -2896,11 +2914,11 @@ impl<'a> EnumBuilder<'a> { } } - fn build<'b>( + fn build( self, ctx: &BindgenContext, rust_ty: proc_macro2::TokenStream, - result: &mut CodegenResult<'b>, + result: &mut CodegenResult<'_>, ) -> proc_macro2::TokenStream { match self { EnumBuilder::Rust { @@ -2999,10 +3017,10 @@ impl CodeGenerator for Enum { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { debug!("::codegen: item = {:?}", item); @@ -3129,7 +3147,10 @@ impl CodeGenerator for Enum { // The custom derives callback may return a list of derive attributes; // add them to the end of the list. let custom_derives = ctx.options().all_callbacks(|cb| { - cb.add_derives(&crate::callbacks::DeriveInfo { name: &name }) + cb.add_derives(&DeriveInfo { + name: &name, + kind: DeriveTypeKind::Enum, + }) }); // In most cases this will be a no-op, since custom_derives will be empty. derives.extend(custom_derives.iter().map(|s| s.as_str())); @@ -3137,7 +3158,7 @@ impl CodeGenerator for Enum { attrs.push(attributes::derives(&derives)); } - fn add_constant<'a>( + fn add_constant( ctx: &BindgenContext, enum_: &Type, // Only to avoid recomputing every time. @@ -3148,7 +3169,7 @@ impl CodeGenerator for Enum { variant_name: &Ident, referenced_name: &Ident, enum_rust_ty: proc_macro2::TokenStream, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, ) { let constant_name = if enum_.name().is_some() { if ctx.options().prepend_enum_name { @@ -3168,8 +3189,10 @@ impl CodeGenerator for Enum { } let repr = repr.to_rust_ty_or_opaque(ctx, item); + let has_typedef = ctx.is_enum_typedef_combo(item.id()); - let mut builder = EnumBuilder::new(&name, attrs, repr, variation); + let mut builder = + EnumBuilder::new(&name, attrs, repr, variation, has_typedef); // A map where we keep a value -> variant relation. let mut seen_values = HashMap::<_, Ident>::default(); @@ -3995,20 +4018,25 @@ impl CodeGenerator for Function { /// it. type Return = Option; - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) -> Self::Return { debug!("::codegen: item = {:?}", item); debug_assert!(item.is_enabled_for_codegen(ctx)); - // We can't currently do anything with Internal functions so just - // avoid generating anything for them. - match self.linkage() { - Linkage::Internal => return None, - Linkage::External => {} + let is_internal = matches!(self.linkage(), Linkage::Internal); + + if is_internal { + if ctx.options().wrap_static_fns { + result.items_to_serialize.push(item.id()); + } else { + // We can't do anything with Internal functions if we are not wrapping them so just + // avoid generating anything for them. + return None; + } } // Pure virtual methods have no actual symbol, so we can't generate @@ -4118,6 +4146,7 @@ impl CodeGenerator for Function { write!(&mut canonical_name, "{}", times_seen).unwrap(); } + let mut has_link_name_attr = false; let link_name = mangled_name.unwrap_or(name); if !is_dynamic_function && !utils::names_will_be_identical_after_mangling( @@ -4127,6 +4156,7 @@ impl CodeGenerator for Function { ) { attributes.push(attributes::link_name(link_name)); + has_link_name_attr = true; } // Unfortunately this can't piggyback on the `attributes` list because @@ -4137,6 +4167,11 @@ impl CodeGenerator for Function { quote! { #[link(wasm_import_module = #name)] } }); + if is_internal && ctx.options().wrap_static_fns && !has_link_name_attr { + let name = canonical_name.clone() + ctx.wrap_static_fns_suffix(); + attributes.push(attributes::link_name(&name)); + } + let ident = ctx.rust_ident(canonical_name); let tokens = quote! { #wasm_link_attribute @@ -4150,11 +4185,7 @@ impl CodeGenerator for Function { if is_dynamic_function { let args_identifiers = utils::fnsig_argument_identifiers(ctx, signature); - let return_item = ctx.resolve_item(signature.return_type()); - let ret_ty = match *return_item.kind().expect_type().kind() { - TypeKind::Void => quote! {()}, - _ => return_item.to_rust_ty_or_opaque(ctx, &()), - }; + let ret_ty = utils::fnsig_return_ty(ctx, signature); result.dynamic_items().push( ident, abi, @@ -4237,10 +4268,10 @@ impl CodeGenerator for ObjCInterface { type Extra = Item; type Return = (); - fn codegen<'a>( + fn codegen( &self, ctx: &BindgenContext, - result: &mut CodegenResult<'a>, + result: &mut CodegenResult<'_>, item: &Item, ) { debug_assert!(item.is_enabled_for_codegen(ctx)); @@ -4445,7 +4476,8 @@ impl CodeGenerator for ObjCInterface { pub(crate) fn codegen( context: BindgenContext, -) -> (proc_macro2::TokenStream, BindgenOptions, Vec) { +) -> Result<(proc_macro2::TokenStream, BindgenOptions, Vec), CodegenError> +{ context.gen(|context| { let _t = context.timer("codegen"); let counter = Cell::new(0); @@ -4495,21 +4527,73 @@ pub(crate) fn codegen( result.push(dynamic_items_tokens); } - postprocessing::postprocessing(result.items, context.options()) + utils::serialize_items(&result, context)?; + + Ok(postprocessing::postprocessing( + result.items, + context.options(), + )) }) } pub mod utils { - use super::{error, ToRustTyOrOpaque}; + use super::serialize::CSerialize; + use super::{error, CodegenError, CodegenResult, ToRustTyOrOpaque}; use crate::ir::context::BindgenContext; use crate::ir::function::{Abi, ClangAbi, FunctionSig}; use crate::ir::item::{Item, ItemCanonicalPath}; use crate::ir::ty::TypeKind; + use crate::{args_are_cpp, file_is_cpp}; use proc_macro2; use std::borrow::Cow; use std::mem; + use std::path::PathBuf; use std::str::FromStr; + pub(super) fn serialize_items( + result: &CodegenResult, + context: &BindgenContext, + ) -> Result<(), CodegenError> { + if result.items_to_serialize.is_empty() { + return Ok(()); + } + + let path = context + .options() + .wrap_static_fns_path + .as_ref() + .map(PathBuf::from) + .unwrap_or_else(|| { + std::env::temp_dir().join("bindgen").join("extern") + }); + + let dir = path.parent().unwrap(); + + if !dir.exists() { + std::fs::create_dir_all(&dir)?; + } + + let is_cpp = args_are_cpp(&context.options().clang_args) || + context + .options() + .input_headers + .iter() + .any(|h| file_is_cpp(h)); + + let source_path = path.with_extension(if is_cpp { "cpp" } else { "c" }); + + let mut code = Vec::new(); + + for &id in &result.items_to_serialize { + let item = context.resolve_item(id); + item.serialize(context, (), &mut vec![], &mut code)?; + } + + std::fs::write(source_path, code)?; + + Ok(()) + } + pub fn prepend_bitfield_unit_type( ctx: &BindgenContext, result: &mut Vec, @@ -4826,23 +4910,50 @@ pub mod utils { }) } + fn fnsig_return_ty_internal( + ctx: &BindgenContext, + sig: &FunctionSig, + include_arrow: bool, + ) -> proc_macro2::TokenStream { + if sig.is_divergent() { + return if include_arrow { + quote! { -> ! } + } else { + quote! { ! } + }; + } + + let canonical_type_kind = sig + .return_type() + .into_resolver() + .through_type_refs() + .through_type_aliases() + .resolve(ctx) + .kind() + .expect_type() + .kind(); + + if let TypeKind::Void = canonical_type_kind { + return if include_arrow { + quote! {} + } else { + quote! { () } + }; + } + + let ret_ty = sig.return_type().to_rust_ty_or_opaque(ctx, &()); + if include_arrow { + quote! { -> #ret_ty } + } else { + ret_ty + } + } + pub fn fnsig_return_ty( ctx: &BindgenContext, sig: &FunctionSig, ) -> proc_macro2::TokenStream { - if sig.is_divergent() { - return quote! { -> ! }; - } - - let return_item = ctx.resolve_item(sig.return_type()); - if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! {} - } else { - let ret_ty = return_item.to_rust_ty_or_opaque(ctx, &()); - quote! { - -> #ret_ty - } - } + fnsig_return_ty_internal(ctx, sig, /* include_arrow = */ true) } pub fn fnsig_arguments( @@ -4957,14 +5068,9 @@ pub mod utils { arg_item.to_rust_ty_or_opaque(ctx, &()) }); - let return_item = ctx.resolve_item(sig.return_type()); - let ret_ty = - if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! { () } - } else { - return_item.to_rust_ty_or_opaque(ctx, &()) - }; - + let ret_ty = fnsig_return_ty_internal( + ctx, sig, /* include_arrow = */ false, + ); quote! { *const ::block::Block<(#(#args,)*), #ret_ty> } diff --git a/third_party/rust/bindgen/codegen/serialize.rs b/third_party/rust/bindgen/codegen/serialize.rs new file mode 100644 index 000000000000..217098e5906b --- /dev/null +++ b/third_party/rust/bindgen/codegen/serialize.rs @@ -0,0 +1,356 @@ +use std::io::Write; + +use crate::callbacks::IntKind; + +use crate::ir::comp::CompKind; +use crate::ir::context::{BindgenContext, TypeId}; +use crate::ir::function::{Function, FunctionKind}; +use crate::ir::item::Item; +use crate::ir::item::ItemCanonicalName; +use crate::ir::item_kind::ItemKind; +use crate::ir::ty::{FloatKind, Type, TypeKind}; + +use super::CodegenError; + +fn get_loc(item: &Item) -> String { + item.location() + .map(|x| x.to_string()) + .unwrap_or_else(|| "unknown".to_owned()) +} + +pub(crate) trait CSerialize<'a> { + type Extra; + + fn serialize( + &self, + ctx: &BindgenContext, + extra: Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError>; +} + +impl<'a> CSerialize<'a> for Item { + type Extra = (); + + fn serialize( + &self, + ctx: &BindgenContext, + (): Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + match self.kind() { + ItemKind::Function(func) => { + func.serialize(ctx, self, stack, writer) + } + kind => { + return Err(CodegenError::Serialize { + msg: format!("Cannot serialize item kind {:?}", kind), + loc: get_loc(self), + }); + } + } + } +} + +impl<'a> CSerialize<'a> for Function { + type Extra = &'a Item; + + fn serialize( + &self, + ctx: &BindgenContext, + item: Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + if self.kind() != FunctionKind::Function { + return Err(CodegenError::Serialize { + msg: format!( + "Cannot serialize function kind {:?}", + self.kind(), + ), + loc: get_loc(item), + }); + } + + let signature = match ctx.resolve_type(self.signature()).kind() { + TypeKind::Function(signature) => signature, + _ => unreachable!(), + }; + + let name = self.name(); + + // Function argoments stored as `(name, type_id)` tuples. + let args = { + let mut count = 0; + + signature + .argument_types() + .iter() + .cloned() + .map(|(opt_name, type_id)| { + ( + opt_name.unwrap_or_else(|| { + let name = format!("arg_{}", count); + count += 1; + name + }), + type_id, + ) + }) + .collect::>() + }; + + // The name used for the wrapper self. + let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix()); + // The function's return type + let ret_ty = signature.return_type(); + + // Write `ret_ty wrap_name(args) asm("wrap_name");` + ret_ty.serialize(ctx, (), stack, writer)?; + write!(writer, " {}(", wrap_name)?; + if args.is_empty() { + write!(writer, "void")?; + } else { + serialize_sep( + ", ", + args.iter(), + ctx, + writer, + |(name, type_id), ctx, buf| { + type_id.serialize(ctx, (), &mut vec![name.clone()], buf) + }, + )?; + } + writeln!(writer, ") asm(\"{}\");", wrap_name)?; + + // Write `ret_ty wrap_name(args) { return name(arg_names)' }` + ret_ty.serialize(ctx, (), stack, writer)?; + write!(writer, " {}(", wrap_name)?; + serialize_sep( + ", ", + args.iter(), + ctx, + writer, + |(name, type_id), _, buf| { + type_id.serialize(ctx, (), &mut vec![name.clone()], buf) + }, + )?; + write!(writer, ") {{ return {}(", name)?; + serialize_sep(", ", args.iter(), ctx, writer, |(name, _), _, buf| { + write!(buf, "{}", name).map_err(From::from) + })?; + writeln!(writer, "); }}")?; + + Ok(()) + } +} + +impl<'a> CSerialize<'a> for TypeId { + type Extra = (); + + fn serialize( + &self, + ctx: &BindgenContext, + (): Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + let item = ctx.resolve_item(*self); + item.expect_type().serialize(ctx, item, stack, writer) + } +} + +impl<'a> CSerialize<'a> for Type { + type Extra = &'a Item; + + fn serialize( + &self, + ctx: &BindgenContext, + item: Self::Extra, + stack: &mut Vec, + writer: &mut W, + ) -> Result<(), CodegenError> { + match self.kind() { + TypeKind::Void => { + if self.is_const() { + write!(writer, "const ")?; + } + write!(writer, "void")? + } + TypeKind::NullPtr => { + if self.is_const() { + write!(writer, "const ")?; + } + write!(writer, "nullptr_t")? + } + TypeKind::Int(int_kind) => { + if self.is_const() { + write!(writer, "const ")?; + } + match int_kind { + IntKind::Bool => write!(writer, "bool")?, + IntKind::SChar => write!(writer, "signed char")?, + IntKind::UChar => write!(writer, "unsigned char")?, + IntKind::WChar => write!(writer, "wchar_t")?, + IntKind::Short => write!(writer, "short")?, + IntKind::UShort => write!(writer, "unsigned short")?, + IntKind::Int => write!(writer, "int")?, + IntKind::UInt => write!(writer, "unsigned int")?, + IntKind::Long => write!(writer, "long")?, + IntKind::ULong => write!(writer, "unsigned long")?, + IntKind::LongLong => write!(writer, "long long")?, + IntKind::ULongLong => write!(writer, "unsigned long long")?, + IntKind::Char { .. } => write!(writer, "char")?, + int_kind => { + return Err(CodegenError::Serialize { + msg: format!( + "Cannot serialize integer kind {:?}", + int_kind + ), + loc: get_loc(item), + }) + } + } + } + TypeKind::Float(float_kind) => { + if self.is_const() { + write!(writer, "const ")?; + } + match float_kind { + FloatKind::Float => write!(writer, "float")?, + FloatKind::Double => write!(writer, "double")?, + FloatKind::LongDouble => write!(writer, "long double")?, + FloatKind::Float128 => write!(writer, "__float128")?, + } + } + TypeKind::Complex(float_kind) => { + if self.is_const() { + write!(writer, "const ")?; + } + match float_kind { + FloatKind::Float => write!(writer, "float complex")?, + FloatKind::Double => write!(writer, "double complex")?, + FloatKind::LongDouble => { + write!(writer, "long double complex")? + } + FloatKind::Float128 => write!(writer, "__complex128")?, + } + } + TypeKind::Alias(type_id) => { + if let Some(name) = self.name() { + if self.is_const() { + write!(writer, "const {}", name)?; + } else { + write!(writer, "{}", name)?; + } + } else { + type_id.serialize(ctx, (), stack, writer)?; + } + } + TypeKind::Array(type_id, length) => { + type_id.serialize(ctx, (), stack, writer)?; + write!(writer, " [{}]", length)? + } + TypeKind::Function(signature) => { + if self.is_const() { + stack.push("const ".to_string()); + } + + signature.return_type().serialize( + ctx, + (), + &mut vec![], + writer, + )?; + + write!(writer, " (")?; + while let Some(item) = stack.pop() { + write!(writer, "{}", item)?; + } + write!(writer, ")")?; + + write!(writer, " (")?; + serialize_sep( + ", ", + signature.argument_types().iter(), + ctx, + writer, + |(name, type_id), ctx, buf| { + let mut stack = vec![]; + if let Some(name) = name { + stack.push(name.clone()); + } + type_id.serialize(ctx, (), &mut stack, buf) + }, + )?; + write!(writer, ")")? + } + TypeKind::ResolvedTypeRef(type_id) => { + if self.is_const() { + write!(writer, "const ")?; + } + type_id.serialize(ctx, (), stack, writer)? + } + TypeKind::Pointer(type_id) => { + if self.is_const() { + stack.push("*const ".to_owned()); + } else { + stack.push("*".to_owned()); + } + type_id.serialize(ctx, (), stack, writer)? + } + TypeKind::Comp(comp_info) => { + if self.is_const() { + write!(writer, "const ")?; + } + + let name = item.canonical_name(ctx); + + match comp_info.kind() { + CompKind::Struct => write!(writer, "struct {}", name)?, + CompKind::Union => write!(writer, "union {}", name)?, + }; + } + ty => { + return Err(CodegenError::Serialize { + msg: format!("Cannot serialize type kind {:?}", ty), + loc: get_loc(item), + }) + } + }; + + if !stack.is_empty() { + write!(writer, " ")?; + while let Some(item) = stack.pop() { + write!(writer, "{}", item)?; + } + } + + Ok(()) + } +} + +fn serialize_sep< + W: Write, + F: FnMut(I::Item, &BindgenContext, &mut W) -> Result<(), CodegenError>, + I: Iterator, +>( + sep: &str, + mut iter: I, + ctx: &BindgenContext, + buf: &mut W, + mut f: F, +) -> Result<(), CodegenError> { + if let Some(item) = iter.next() { + f(item, ctx, buf)?; + let sep = sep.as_bytes(); + for item in iter { + buf.write_all(sep)?; + f(item, ctx, buf)?; + } + } + + Ok(()) +} diff --git a/third_party/rust/bindgen/ir/analysis/template_params.rs b/third_party/rust/bindgen/ir/analysis/template_params.rs index e88b774deec5..f4f0c59d71df 100644 --- a/third_party/rust/bindgen/ir/analysis/template_params.rs +++ b/third_party/rust/bindgen/ir/analysis/template_params.rs @@ -424,8 +424,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // generic template parameters are used. let item_kind = ctx.resolve_item(item).as_type().map(|ty| ty.kind()); - if let Some(&TypeKind::TemplateInstantiation(ref inst)) = item_kind - { + if let Some(TypeKind::TemplateInstantiation(inst)) = item_kind { let decl = ctx.resolve_type(inst.template_definition()); let args = inst.template_arguments(); @@ -540,7 +539,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { } // Template instantiations only use their template arguments if the // template definition uses the corresponding template parameter. - Some(&TypeKind::TemplateInstantiation(ref inst)) => { + Some(TypeKind::TemplateInstantiation(inst)) => { if self .allowlisted_items .contains(&inst.template_definition().into()) diff --git a/third_party/rust/bindgen/ir/comp.rs b/third_party/rust/bindgen/ir/comp.rs index 039742a48dba..18a4291cf9db 100644 --- a/third_party/rust/bindgen/ir/comp.rs +++ b/third_party/rust/bindgen/ir/comp.rs @@ -12,7 +12,7 @@ use super::ty::RUST_DERIVE_IN_ARRAY_LIMIT; use crate::clang; use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2}; use crate::ir::derive::CanDeriveCopy; -use crate::parse::{ClangItemParser, ParseError}; +use crate::parse::ParseError; use crate::HashMap; use crate::NonCopyUnionStyle; use peeking_take_while::PeekableExt; diff --git a/third_party/rust/bindgen/ir/context.rs b/third_party/rust/bindgen/ir/context.rs index 4623b2534426..b693a7047e01 100644 --- a/third_party/rust/bindgen/ir/context.rs +++ b/third_party/rust/bindgen/ir/context.rs @@ -20,7 +20,7 @@ use super::template::{TemplateInstantiation, TemplateParameters}; use super::traversal::{self, Edge, ItemTraversal}; use super::ty::{FloatKind, Type, TypeKind}; use crate::clang::{self, Cursor}; -use crate::parse::ClangItemParser; +use crate::codegen::CodegenError; use crate::BindgenOptions; use crate::{Entry, HashMap, HashSet}; use cexpr; @@ -399,6 +399,22 @@ pub struct BindgenContext { /// bitfield allocation units computed. Drained in `compute_bitfield_units`. need_bitfield_allocation: Vec, + /// The set of enums that are defined by a pair of `enum` and `typedef`, + /// which is legal in C (but not C++). + /// + /// ```c++ + /// // in either order + /// enum Enum { Variants... }; + /// typedef int16_t Enum; + /// ``` + /// + /// The stored `ItemId` is that of the `TypeKind::Enum`, not of the + /// `TypeKind::Alias`. + /// + /// This is populated when we enter codegen by `compute_enum_typedef_combos` + /// and is always `None` before that and `Some` after. + enum_typedef_combos: Option>, + /// The set of (`ItemId`s of) types that can't derive debug. /// /// This is populated when we enter codegen by `compute_cannot_derive_debug` @@ -566,6 +582,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" codegen_items: None, used_template_parameters: None, need_bitfield_allocation: Default::default(), + enum_typedef_combos: None, cannot_derive_debug: None, cannot_derive_default: None, cannot_derive_copy: None, @@ -1130,9 +1147,9 @@ If you encounter an error missing from this list, please file an issue or a PR!" pub(crate) fn gen( mut self, cb: F, - ) -> (Out, BindgenOptions, Vec) + ) -> Result<(Out, BindgenOptions, Vec), CodegenError> where - F: FnOnce(&Self) -> Out, + F: FnOnce(&Self) -> Result, { self.in_codegen = true; @@ -1158,6 +1175,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.compute_sizedness(); self.compute_has_destructor(); self.find_used_template_parameters(); + self.compute_enum_typedef_combos(); self.compute_cannot_derive_debug(); self.compute_cannot_derive_default(); self.compute_cannot_derive_copy(); @@ -1166,8 +1184,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.compute_cannot_derive_hash(); self.compute_cannot_derive_partialord_partialeq_or_eq(); - let ret = cb(&self); - (ret, self.options, self.warnings) + let ret = cb(&self)?; + Ok((ret, self.options, self.warnings)) } /// When the `testing_only_extra_assertions` feature is enabled, this @@ -2477,6 +2495,70 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.generated_bindgen_complex.get() } + /// Compute which `enum`s have an associated `typedef` definition. + fn compute_enum_typedef_combos(&mut self) { + let _t = self.timer("compute_enum_typedef_combos"); + assert!(self.enum_typedef_combos.is_none()); + + let mut enum_typedef_combos = HashSet::default(); + for item in &self.items { + if let Some(ItemKind::Module(module)) = + item.as_ref().map(Item::kind) + { + // Find typedefs in this module, and build set of their names. + let mut names_of_typedefs = HashSet::default(); + for child_id in module.children() { + if let Some(ItemKind::Type(ty)) = + self.items[child_id.0].as_ref().map(Item::kind) + { + if let (Some(name), TypeKind::Alias(type_id)) = + (ty.name(), ty.kind()) + { + // We disregard aliases that refer to the enum + // itself, such as in `typedef enum { ... } Enum;`. + if type_id + .into_resolver() + .through_type_refs() + .through_type_aliases() + .resolve(self) + .expect_type() + .is_int() + { + names_of_typedefs.insert(name); + } + } + } + } + + // Find enums in this module, and record the id of each one that + // has a typedef. + for child_id in module.children() { + if let Some(ItemKind::Type(ty)) = + self.items[child_id.0].as_ref().map(Item::kind) + { + if let (Some(name), true) = (ty.name(), ty.is_enum()) { + if names_of_typedefs.contains(name) { + enum_typedef_combos.insert(*child_id); + } + } + } + } + } + } + + self.enum_typedef_combos = Some(enum_typedef_combos); + } + + /// Look up whether `id` refers to an `enum` whose underlying type is + /// defined by a `typedef`. + pub fn is_enum_typedef_combo(&self, id: ItemId) -> bool { + assert!( + self.in_codegen_phase(), + "We only compute enum_typedef_combos when we enter codegen", + ); + self.enum_typedef_combos.as_ref().unwrap().contains(&id) + } + /// Compute whether we can derive debug. fn compute_cannot_derive_debug(&mut self) { let _t = self.timer("compute_cannot_derive_debug"); @@ -2711,6 +2793,13 @@ If you encounter an error missing from this list, please file an issue or a PR!" tokens.into_token_stream() } } + + pub(crate) fn wrap_static_fns_suffix(&self) -> &str { + self.options() + .wrap_static_fns_suffix + .as_deref() + .unwrap_or(crate::DEFAULT_NON_EXTERN_FNS_SUFFIX) + } } /// A builder struct for configuring item resolution options. diff --git a/third_party/rust/bindgen/ir/enum_ty.rs b/third_party/rust/bindgen/ir/enum_ty.rs index 39677e93fd30..63871fd46569 100644 --- a/third_party/rust/bindgen/ir/enum_ty.rs +++ b/third_party/rust/bindgen/ir/enum_ty.rs @@ -6,7 +6,7 @@ use super::item::Item; use super::ty::{Type, TypeKind}; use crate::clang; use crate::ir::annotations::Annotations; -use crate::parse::{ClangItemParser, ParseError}; +use crate::parse::ParseError; use crate::regex_set::RegexSet; /// An enum representing custom handling that can be given to a variant. diff --git a/third_party/rust/bindgen/ir/function.rs b/third_party/rust/bindgen/ir/function.rs index 7dbbb8f84928..baa2c36ca424 100644 --- a/third_party/rust/bindgen/ir/function.rs +++ b/third_party/rust/bindgen/ir/function.rs @@ -6,10 +6,9 @@ use super::dot::DotAttributes; use super::item::Item; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::TypeKind; +use crate::callbacks::{ItemInfo, ItemKind}; use crate::clang::{self, Attribute}; -use crate::parse::{ - ClangItemParser, ClangSubItemParser, ParseError, ParseResult, -}; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; use clang_sys::{self, CXCallingConv}; use proc_macro2; use quote; @@ -665,7 +664,6 @@ impl ClangSubItemParser for Function { }; debug!("Function::parse({:?}, {:?})", cursor, cursor.cur_type()); - let visibility = cursor.visibility(); if visibility != CXVisibility_Default { return Err(ParseError::Continue); @@ -675,19 +673,6 @@ impl ClangSubItemParser for Function { return Err(ParseError::Continue); } - if cursor.is_inlined_function() || - cursor - .definition() - .map_or(false, |x| x.is_inlined_function()) - { - if !context.options().generate_inline_functions { - return Err(ParseError::Continue); - } - if cursor.is_deleted_function() { - return Err(ParseError::Continue); - } - } - let linkage = cursor.linkage(); let linkage = match linkage { CXLinkage_External | CXLinkage_UniqueExternal => Linkage::External, @@ -695,6 +680,30 @@ impl ClangSubItemParser for Function { _ => return Err(ParseError::Continue), }; + if cursor.is_inlined_function() || + cursor + .definition() + .map_or(false, |x| x.is_inlined_function()) + { + if !context.options().generate_inline_functions && + !context.options().wrap_static_fns + { + return Err(ParseError::Continue); + } + + if cursor.is_deleted_function() { + return Err(ParseError::Continue); + } + + // We cannot handle `inline` functions that are not `static`. + if context.options().wrap_static_fns && + cursor.is_inlined_function() && + matches!(linkage, Linkage::External) + { + return Err(ParseError::Continue); + } + } + // Grab the signature using Item::from_ty. let sig = Item::from_ty(&cursor.cur_type(), cursor, None, context)?; @@ -714,10 +723,12 @@ impl ClangSubItemParser for Function { // but seems easy enough to handle it here. name.push_str("_destructor"); } - if let Some(nm) = context - .options() - .last_callback(|callbacks| callbacks.generated_name_override(&name)) - { + if let Some(nm) = context.options().last_callback(|callbacks| { + callbacks.generated_name_override(ItemInfo { + name: name.as_str(), + kind: ItemKind::Function, + }) + }) { name = nm; } assert!(!name.is_empty(), "Empty function name."); @@ -726,7 +737,8 @@ impl ClangSubItemParser for Function { let comment = cursor.raw_comment(); let function = - Self::new(name, mangled_name, sig, comment, kind, linkage); + Self::new(name.clone(), mangled_name, sig, comment, kind, linkage); + Ok(ParseResult::New(function, Some(cursor))) } } diff --git a/third_party/rust/bindgen/ir/item.rs b/third_party/rust/bindgen/ir/item.rs index 5e9aff910211..40f6f7d927c5 100644 --- a/third_party/rust/bindgen/ir/item.rs +++ b/third_party/rust/bindgen/ir/item.rs @@ -18,9 +18,7 @@ use super::template::{AsTemplateParam, TemplateParameters}; use super::traversal::{EdgeKind, Trace, Tracer}; use super::ty::{Type, TypeKind}; use crate::clang; -use crate::parse::{ - ClangItemParser, ClangSubItemParser, ParseError, ParseResult, -}; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; use clang_sys; use lazycell::LazyCell; use regex; @@ -1307,8 +1305,8 @@ fn visit_child( } } -impl ClangItemParser for Item { - fn builtin_type( +impl Item { + pub(crate) fn builtin_type( kind: TypeKind, is_const: bool, ctx: &mut BindgenContext, @@ -1333,7 +1331,7 @@ impl ClangItemParser for Item { id.as_type_id_unchecked() } - fn parse( + pub(crate) fn parse( cursor: clang::Cursor, parent_id: Option, ctx: &mut BindgenContext, @@ -1479,7 +1477,7 @@ impl ClangItemParser for Item { } } - fn from_ty_or_ref( + pub(crate) fn from_ty_or_ref( ty: clang::Type, location: clang::Cursor, parent_id: Option, @@ -1499,7 +1497,7 @@ impl ClangItemParser for Item { /// /// Typerefs are resolved once parsing is completely done, see /// `BindgenContext::resolve_typerefs`. - fn from_ty_or_ref_with_id( + pub(crate) fn from_ty_or_ref_with_id( potential_id: ItemId, ty: clang::Type, location: clang::Cursor, @@ -1554,7 +1552,7 @@ impl ClangItemParser for Item { potential_id.as_type_id_unchecked() } - fn from_ty( + pub(crate) fn from_ty( ty: &clang::Type, location: clang::Cursor, parent_id: Option, @@ -1572,7 +1570,7 @@ impl ClangItemParser for Item { /// critical some times to obtain information, an optional parent item id, /// that will, if it's `None`, become the current module id, and the /// context. - fn from_ty_with_id( + pub(crate) fn from_ty_with_id( id: ItemId, ty: &clang::Type, location: clang::Cursor, @@ -1742,7 +1740,7 @@ impl ClangItemParser for Item { /// A named type is a template parameter, e.g., the "T" in Foo. They're /// always local so it's the only exception when there's no declaration for /// a type. - fn type_param( + pub(crate) fn type_param( with_id: Option, location: clang::Cursor, ctx: &mut BindgenContext, diff --git a/third_party/rust/bindgen/ir/objc.rs b/third_party/rust/bindgen/ir/objc.rs index 0845ad0fde62..4f340f6f7a7a 100644 --- a/third_party/rust/bindgen/ir/objc.rs +++ b/third_party/rust/bindgen/ir/objc.rs @@ -6,7 +6,6 @@ use super::item::Item; use super::traversal::{Trace, Tracer}; use super::ty::TypeKind; use crate::clang; -use crate::parse::ClangItemParser; use clang_sys::CXChildVisit_Continue; use clang_sys::CXCursor_ObjCCategoryDecl; use clang_sys::CXCursor_ObjCClassMethodDecl; @@ -261,7 +260,17 @@ impl ObjCMethod { if name.is_empty() { None } else { - Some(Ident::new(name, Span::call_site())) + // Try to parse the current name as an identifier. This might fail if the + // name is a keyword so we try to prepend "r#" to it and parse again. If + // this also fails, we panic with the first error. + Some( + syn::parse_str::(name) + .or_else(|err| { + syn::parse_str::(&format!("r#{}", name)) + .map_err(|_| err) + }) + .expect("Invalid identifier"), + ) } }) .collect(); diff --git a/third_party/rust/bindgen/ir/template.rs b/third_party/rust/bindgen/ir/template.rs index 8b06748e2c53..e3ef6a9c9661 100644 --- a/third_party/rust/bindgen/ir/template.rs +++ b/third_party/rust/bindgen/ir/template.rs @@ -31,7 +31,6 @@ use super::context::{BindgenContext, ItemId, TypeId}; use super::item::{IsOpaque, Item, ItemAncestors}; use super::traversal::{EdgeKind, Trace, Tracer}; use crate::clang; -use crate::parse::ClangItemParser; /// Template declaration (and such declaration's template parameters) related /// methods. diff --git a/third_party/rust/bindgen/ir/ty.rs b/third_party/rust/bindgen/ir/ty.rs index fd6108f774b9..fef340dee9b1 100644 --- a/third_party/rust/bindgen/ir/ty.rs +++ b/third_party/rust/bindgen/ir/ty.rs @@ -14,7 +14,7 @@ use super::template::{ }; use super::traversal::{EdgeKind, Trace, Tracer}; use crate::clang::{self, Cursor}; -use crate::parse::{ClangItemParser, ParseError, ParseResult}; +use crate::parse::{ParseError, ParseResult}; use std::borrow::Cow; use std::io; @@ -95,6 +95,11 @@ impl Type { matches!(self.kind, TypeKind::BlockPointer(..)) } + /// Is this an integer type, including `bool` or `char`? + pub fn is_int(&self) -> bool { + matches!(self.kind, TypeKind::Int(_)) + } + /// Is this a compound type? pub fn is_comp(&self) -> bool { matches!(self.kind, TypeKind::Comp(..)) diff --git a/third_party/rust/bindgen/ir/var.rs b/third_party/rust/bindgen/ir/var.rs index c86742ff699b..903e1ff549df 100644 --- a/third_party/rust/bindgen/ir/var.rs +++ b/third_party/rust/bindgen/ir/var.rs @@ -7,12 +7,10 @@ use super::function::cursor_mangling; use super::int::IntKind; use super::item::Item; use super::ty::{FloatKind, TypeKind}; -use crate::callbacks::MacroParsingBehavior; +use crate::callbacks::{ItemInfo, ItemKind, MacroParsingBehavior}; use crate::clang; use crate::clang::ClangToken; -use crate::parse::{ - ClangItemParser, ClangSubItemParser, ParseError, ParseResult, -}; +use crate::parse::{ClangSubItemParser, ParseError, ParseResult}; use cexpr; use std::io; use std::num::Wrapping; @@ -274,7 +272,20 @@ impl ClangSubItemParser for Var { )) } CXCursor_VarDecl => { - let name = cursor.spelling(); + let mut name = cursor.spelling(); + if cursor.linkage() == CXLinkage_External { + if let Some(nm) = ctx.options().last_callback(|callbacks| { + callbacks.generated_name_override(ItemInfo { + name: name.as_str(), + kind: ItemKind::Var, + }) + }) { + name = nm; + } + } + // No more changes to name + let name = name; + if name.is_empty() { warn!("Empty constant name?"); return Err(ParseError::Continue); diff --git a/third_party/rust/bindgen/lib.rs b/third_party/rust/bindgen/lib.rs index 4b71fb97ce46..537474201684 100644 --- a/third_party/rust/bindgen/lib.rs +++ b/third_party/rust/bindgen/lib.rs @@ -65,7 +65,7 @@ mod clang; mod codegen; mod deps; mod features; -mod ir; +pub mod ir; mod parse; mod regex_set; mod time; @@ -78,6 +78,7 @@ doc_mod!(ir, ir_docs); doc_mod!(parse, parse_docs); doc_mod!(regex_set, regex_set_docs); +use codegen::CodegenError; use ir::comment; pub use crate::codegen::{ @@ -90,8 +91,8 @@ pub use crate::features::{ use crate::ir::context::{BindgenContext, ItemId}; pub use crate::ir::function::Abi; use crate::ir::item::Item; -use crate::parse::{ClangItemParser, ParseError}; -use crate::regex_set::RegexSet; +use crate::parse::ParseError; +pub use crate::regex_set::RegexSet; use std::borrow::Cow; use std::env; @@ -108,6 +109,7 @@ pub(crate) use std::collections::hash_map::Entry; /// Default prefix for the anon fields. pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_"; +const DEFAULT_NON_EXTERN_FNS_SUFFIX: &str = "__extern"; fn file_is_cpp(name_file: &str) -> bool { name_file.ends_with(".hpp") || @@ -244,6 +246,10 @@ impl Default for CodegenConfig { /// regular expressions as arguments. These regular expressions will be parenthesized and wrapped /// in `^` and `$`. So if `` is passed as argument, the regular expression to be stored will /// be `^()$`. +/// +/// Releases of `bindgen` with a version lesser or equal to `0.62.0` used to accept the wildcard +/// pattern `*` as a valid regular expression. This behavior has been deprecated and the `.*` +/// pattern must be used instead. #[derive(Debug, Default, Clone)] pub struct Builder { options: BindgenOptions, @@ -649,6 +655,28 @@ impl Builder { output_vector.push("--wrap-unsafe-ops".into()); } + #[cfg(feature = "cli")] + for callbacks in &self.options.parse_callbacks { + output_vector.extend(callbacks.cli_args()); + } + if self.options.wrap_static_fns { + output_vector.push("--wrap-static-fns".into()) + } + + if let Some(ref path) = self.options.wrap_static_fns_path { + output_vector.push("--wrap-static-fns-path".into()); + output_vector.push(path.display().to_string()); + } + + if let Some(ref suffix) = self.options.wrap_static_fns_suffix { + output_vector.push("--wrap-static-fns-suffix".into()); + output_vector.push(suffix.clone()); + } + + if cfg!(feature = "experimental") { + output_vector.push("--experimental".into()); + } + // Add clang arguments output_vector.push("--".into()); @@ -1544,33 +1572,25 @@ impl Builder { } /// Generate the Rust bindings using the options built up thus far. - pub fn generate(self) -> Result { - let mut options = self.options.clone(); + pub fn generate(mut self) -> Result { // Add any extra arguments from the environment to the clang command line. - options.clang_args.extend(get_extra_clang_args()); + self.options.clang_args.extend(get_extra_clang_args()); // Transform input headers to arguments on the clang command line. - options.clang_args.extend( - options.input_headers - [..options.input_headers.len().saturating_sub(1)] + self.options.clang_args.extend( + self.options.input_headers + [..self.options.input_headers.len().saturating_sub(1)] .iter() .flat_map(|header| ["-include".into(), header.to_string()]), ); let input_unsaved_files = - std::mem::take(&mut options.input_header_contents) + std::mem::take(&mut self.options.input_header_contents) .into_iter() .map(|(name, contents)| clang::UnsavedFile::new(name, contents)) .collect::>(); - match Bindings::generate(options, input_unsaved_files) { - GenerateResult::Ok(bindings) => Ok(bindings), - GenerateResult::ShouldRestart { header } => self - .header(header) - .generate_inline_functions(false) - .generate(), - GenerateResult::Err(err) => Err(err), - } + Bindings::generate(self.options, input_unsaved_files) } /// Preprocess and dump the input header files to disk. @@ -1605,7 +1625,7 @@ impl Builder { // For each input header content, add a prefix line of `#line 0 "$name"` // followed by the contents. - for &(ref name, ref contents) in &self.options.input_header_contents { + for (name, contents) in &self.options.input_header_contents { is_cpp |= file_is_cpp(name); wrapper_contents.push_str("#line 0 \""); @@ -1787,6 +1807,32 @@ impl Builder { self.options.wrap_unsafe_ops = doit; self } + + #[cfg(feature = "experimental")] + /// Whether to generate extern wrappers for `static` and `static inline` functions. Defaults to + /// false. + pub fn wrap_static_fns(mut self, doit: bool) -> Self { + self.options.wrap_static_fns = doit; + self + } + + #[cfg(feature = "experimental")] + /// Set the path for the source code file that would be created if any wrapper functions must + /// be generated due to the presence of static functions. + /// + /// Bindgen will automatically add the right extension to the header and source code files. + pub fn wrap_static_fns_path>(mut self, path: T) -> Self { + self.options.wrap_static_fns_path = Some(path.as_ref().to_owned()); + self + } + + #[cfg(feature = "experimental")] + /// Set the suffix added to the extern wrapper functions generated for `static` and `static + /// inline` functions. + pub fn wrap_static_fns_suffix>(mut self, suffix: T) -> Self { + self.options.wrap_static_fns_suffix = Some(suffix.as_ref().to_owned()); + self + } } /// Configuration options for generated bindings. @@ -2127,6 +2173,12 @@ struct BindgenOptions { /// Whether to wrap unsafe operations in unsafe blocks or not. wrap_unsafe_ops: bool, + + wrap_static_fns: bool, + + wrap_static_fns_suffix: Option, + + wrap_static_fns_path: Option, } impl BindgenOptions { @@ -2319,6 +2371,9 @@ impl Default for BindgenOptions { merge_extern_blocks, abi_overrides, wrap_unsafe_ops, + wrap_static_fns, + wrap_static_fns_suffix, + wrap_static_fns_path, } } } @@ -2349,18 +2404,6 @@ fn ensure_libclang_is_loaded() { #[cfg(not(feature = "runtime"))] fn ensure_libclang_is_loaded() {} -#[derive(Debug)] -enum GenerateResult { - Ok(Bindings), - /// Error variant raised when bindgen requires to run again with a newly generated header - /// input. - #[allow(dead_code)] - ShouldRestart { - header: String, - }, - Err(BindgenError), -} - /// Error type for rust-bindgen. #[derive(Debug, Clone, PartialEq, Eq, Hash)] #[non_exhaustive] @@ -2373,6 +2416,8 @@ pub enum BindgenError { NotExist(PathBuf), /// Clang diagnosed an error. ClangDiagnostic(String), + /// Code generation reported an error. + Codegen(CodegenError), } impl std::fmt::Display for BindgenError { @@ -2390,6 +2435,9 @@ impl std::fmt::Display for BindgenError { BindgenError::ClangDiagnostic(message) => { write!(f, "clang diagnosed error: {}", message) } + BindgenError::Codegen(err) => { + write!(f, "codegen error: {}", err) + } } } } @@ -2419,6 +2467,15 @@ fn rust_to_clang_target(rust_target: &str) -> String { let mut clang_target = "riscv64-".to_owned(); clang_target.push_str(rust_target.strip_prefix("riscv64gc-").unwrap()); return clang_target; + } else if rust_target.ends_with("-espidf") { + let mut clang_target = + rust_target.strip_suffix("-espidf").unwrap().to_owned(); + clang_target.push_str("-elf"); + if clang_target.starts_with("riscv32imc-") { + clang_target = "riscv32-".to_owned() + + clang_target.strip_prefix("riscv32imc-").unwrap(); + } + return clang_target; } rust_target.to_owned() } @@ -2454,7 +2511,7 @@ impl Bindings { pub(crate) fn generate( mut options: BindgenOptions, input_unsaved_files: Vec, - ) -> GenerateResult { + ) -> Result { ensure_libclang_is_loaded(); #[cfg(feature = "runtime")] @@ -2575,21 +2632,17 @@ impl Bindings { let path = Path::new(h); if let Ok(md) = std::fs::metadata(path) { if md.is_dir() { - return GenerateResult::Err(BindgenError::FolderAsHeader( - path.into(), - )); + return Err(BindgenError::FolderAsHeader(path.into())); } if !can_read(&md.permissions()) { - return GenerateResult::Err( - BindgenError::InsufficientPermissions(path.into()), - ); + return Err(BindgenError::InsufficientPermissions( + path.into(), + )); } let h = h.clone(); options.clang_args.push(h); } else { - return GenerateResult::Err(BindgenError::NotExist( - path.into(), - )); + return Err(BindgenError::NotExist(path.into())); } } @@ -2617,14 +2670,13 @@ impl Bindings { { let _t = time::Timer::new("parse").with_output(time_phases); - if let Err(err) = parse(&mut context) { - return GenerateResult::Err(err); - } + parse(&mut context)?; } - let (module, options, warnings) = codegen::codegen(context); + let (module, options, warnings) = + codegen::codegen(context).map_err(BindgenError::Codegen)?; - GenerateResult::Ok(Bindings { + Ok(Bindings { options, warnings, module, @@ -3002,3 +3054,15 @@ fn test_rust_to_clang_target_riscv() { "riscv64-unknown-linux-gnu" ) } + +#[test] +fn test_rust_to_clang_target_espidf() { + assert_eq!( + rust_to_clang_target("riscv32imc-esp-espidf"), + "riscv32-esp-elf" + ); + assert_eq!( + rust_to_clang_target("xtensa-esp32-espidf"), + "xtensa-esp32-elf" + ); +} diff --git a/third_party/rust/bindgen/parse.rs b/third_party/rust/bindgen/parse.rs index f60de4317780..1fd83cddda17 100644 --- a/third_party/rust/bindgen/parse.rs +++ b/third_party/rust/bindgen/parse.rs @@ -1,8 +1,7 @@ //! Common traits and types related to parsing our IR from Clang cursors. use crate::clang; -use crate::ir::context::{BindgenContext, ItemId, TypeId}; -use crate::ir::ty::TypeKind; +use crate::ir::context::{BindgenContext, ItemId}; /// Not so much an error in the traditional sense, but a control flow message /// when walking over Clang's AST with a cursor. @@ -39,64 +38,3 @@ pub trait ClangSubItemParser: Sized { context: &mut BindgenContext, ) -> Result, ParseError>; } - -/// An intermediate representation item that can be parsed from a Clang cursor. -pub trait ClangItemParser: Sized { - /// Parse this item from the given Clang cursor. - fn parse( - cursor: clang::Cursor, - parent: Option, - context: &mut BindgenContext, - ) -> Result; - - /// Parse this item from the given Clang type. - fn from_ty( - ty: &clang::Type, - location: clang::Cursor, - parent: Option, - ctx: &mut BindgenContext, - ) -> Result; - - /// Identical to `from_ty`, but use the given `id` as the `ItemId` for the - /// newly parsed item. - fn from_ty_with_id( - id: ItemId, - ty: &clang::Type, - location: clang::Cursor, - parent: Option, - ctx: &mut BindgenContext, - ) -> Result; - - /// Parse this item from the given Clang type, or if we haven't resolved all - /// the other items this one depends on, an unresolved reference. - fn from_ty_or_ref( - ty: clang::Type, - location: clang::Cursor, - parent_id: Option, - context: &mut BindgenContext, - ) -> TypeId; - - /// Identical to `from_ty_or_ref`, but use the given `potential_id` as the - /// `ItemId` for the newly parsed item. - fn from_ty_or_ref_with_id( - potential_id: ItemId, - ty: clang::Type, - location: clang::Cursor, - parent_id: Option, - context: &mut BindgenContext, - ) -> TypeId; - - /// Create a named template type. - fn type_param( - with_id: Option, - location: clang::Cursor, - ctx: &mut BindgenContext, - ) -> Option; - - /// Create a builtin type. - fn builtin_type( - kind: TypeKind, - is_const: bool, - context: &mut BindgenContext, - ) -> TypeId; -} diff --git a/third_party/rust/bindgen/regex_set.rs b/third_party/rust/bindgen/regex_set.rs index 9f1e2251cd08..6246dd255b91 100644 --- a/third_party/rust/bindgen/regex_set.rs +++ b/third_party/rust/bindgen/regex_set.rs @@ -16,6 +16,13 @@ pub struct RegexSet { } impl RegexSet { + /// Create a new RegexSet + pub fn new() -> RegexSet { + RegexSet { + ..Default::default() + } + } + /// Is this set empty? pub fn is_empty(&self) -> bool { self.items.is_empty() diff --git a/tools/profiler/rust-api/Cargo.toml b/tools/profiler/rust-api/Cargo.toml index 20e8f3bdec83..93800051e4fc 100644 --- a/tools/profiler/rust-api/Cargo.toml +++ b/tools/profiler/rust-api/Cargo.toml @@ -14,7 +14,7 @@ mozbuild = "0.1" [build-dependencies] lazy_static = "1" -bindgen = {version = "0.63", default-features = false} +bindgen = {version = "0.64", default-features = false} mozbuild = "0.1" [features]