diff options
43 files changed, 823 insertions, 1322 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index f1c8552..2263767 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "89032649044d875983a851fff6fbde2d4e2ceaeb" + "sha1": "696455d1c15e682b2b89f81f409315ea4964aef3" } } @@ -1,4 +1,4 @@ -// This file is generated by cargo2android.py --config cargo2android.json. +// This file is generated by cargo2android.py --run --dependencies --features=clap,runtime,which-rustfmt --host-first-multilib --copy-out. // Do not modify this file as changes will be overridden on upgrade. package { @@ -43,10 +43,7 @@ genrule { rust_binary_host { name: "bindgen", - // has rustc warnings crate_name: "bindgen", - cargo_env_compat: true, - cargo_pkg_version: "0.59.2", srcs: [ "src/main.rs", ":copy_bindgen_build_out", @@ -79,10 +76,7 @@ rust_binary_host { rust_library_host { name: "libbindgen", - // has rustc warnings crate_name: "bindgen", - cargo_env_compat: true, - cargo_pkg_version: "0.59.2", srcs: [ "src/lib.rs", ":copy_bindgen_build_out", @@ -111,3 +105,33 @@ rust_library_host { ], compile_multilib: "first", } + +// dependent_library ["feature_list"] +// ansi_term-0.11.0 +// atty-0.2.14 +// bitflags-1.2.1 "default" +// cexpr-0.4.0 +// cfg-if-1.0.0 +// clang-sys-1.2.0 "clang_3_5,clang_3_6,clang_3_7,clang_3_8,clang_3_9,clang_4_0,clang_5_0,clang_6_0,libloading,runtime" +// clap-2.33.3 "ansi_term,atty,color,default,strsim,suggestions,vec_map" +// glob-0.3.0 +// lazy_static-1.4.0 +// lazycell-1.3.0 +// libc-0.2.93 "default,std" +// libloading-0.7.0 +// memchr-2.3.4 "std,use_std" +// nom-5.1.2 "alloc,std" +// peeking_take_while-0.1.2 +// proc-macro2-1.0.26 +// quote-1.0.9 +// regex-1.4.5 "std,unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment" +// regex-syntax-0.6.23 "unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment" +// rustc-hash-1.1.0 "default,std" +// shlex-1.0.0 +// strsim-0.8.0 +// textwrap-0.11.0 +// unicode-width-0.1.8 "default" +// unicode-xid-0.2.1 "default" +// vec_map-0.8.2 +// version_check-0.9.3 +// which-3.1.1 @@ -33,7 +33,7 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.59.2" +version = "0.58.1" dependencies = [ "bitflags", "cexpr", @@ -50,7 +50,6 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "tempfile", "which", ] @@ -62,24 +61,30 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] name = "cexpr" -version = "0.6.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" dependencies = [ "nom", ] [[package]] name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clang-sys" -version = "1.2.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c" +checksum = "0659001ab56b791be01d4b729c44376edc6718cf389a502e579b77b758f3296c" dependencies = [ "glob", "libc", @@ -108,16 +113,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" [[package]] -name = "either" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" - -[[package]] name = "env_logger" -version = "0.9.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" +checksum = "54532e3223c5af90a6a757c90b5c5521564b07e5e7a958681bcd2afad421cdcd" dependencies = [ "atty", "humantime", @@ -127,17 +126,6 @@ dependencies = [ ] [[package]] -name = "getrandom" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -145,18 +133,18 @@ checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" [[package]] name = "hermit-abi" -version = "0.1.19" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "5aca5565f760fb5b220e499d72710ed156fdb74e631659e99377d9ebfbd13ae8" dependencies = [ "libc", ] [[package]] name = "humantime" -version = "2.1.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "3c1ad908cc71012b7bea4d0c53ba96a8cba9962f048fa68d143376143d863b7a" [[package]] name = "lazy_static" @@ -172,27 +160,27 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.98" +version = "0.2.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614" [[package]] name = "libloading" -version = "0.7.0" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +checksum = "1090080fe06ec2648d0da3881d9453d97e71a45f00eb179af7fdd7e3f686fdb0" dependencies = [ - "cfg-if", + "cfg-if 1.0.0", "winapi", ] [[package]] name = "log" -version = "0.4.14" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" dependencies = [ - "cfg-if", + "cfg-if 0.1.10", ] [[package]] @@ -202,19 +190,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] -name = "minimal-lexical" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" - -[[package]] name = "nom" -version = "7.0.0" +version = "5.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" dependencies = [ "memchr", - "minimal-lexical", "version_check", ] @@ -225,103 +206,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] name = "proc-macro2" -version = "1.0.28" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" dependencies = [ "unicode-xid", ] [[package]] name = "quote" -version = "1.0.9" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" dependencies = [ "proc-macro2", ] [[package]] -name = "rand" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] - -[[package]] -name = "redox_syscall" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee" -dependencies = [ - "bitflags", -] - -[[package]] name = "regex" -version = "1.4.6" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" +checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" dependencies = [ "aho-corasick", "memchr", "regex-syntax", + "thread_local", ] [[package]] name = "regex-syntax" -version = "0.6.25" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" [[package]] name = "rustc-hash" @@ -342,24 +260,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] -name = "tempfile" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" -dependencies = [ - "cfg-if", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", -] - -[[package]] name = "termcolor" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" dependencies = [ "winapi-util", ] @@ -374,6 +278,15 @@ dependencies = [ ] [[package]] +name = "thread_local" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" +dependencies = [ + "lazy_static", +] + +[[package]] name = "unicode-width" version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -381,9 +294,9 @@ checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" [[package]] name = "unicode-xid" -version = "0.2.2" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" [[package]] name = "vec_map" @@ -393,24 +306,16 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] name = "which" -version = "4.2.1" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc009ab82a2afc94b9e467ab4214aee9cad1356cd9191264203d7d72006e00d" +checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724" dependencies = [ - "either", - "lazy_static", "libc", ] @@ -3,16 +3,17 @@ # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies. +# to registry (e.g., crates.io) dependencies # -# If you are reading this file be aware that the original Cargo.toml -# will likely look very different (and much more reasonable). -# See Cargo.toml.orig for the original contents. +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) [package] edition = "2018" name = "bindgen" -version = "0.59.2" +version = "0.58.1" authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"] build = "build.rs" include = ["LICENSE", "README.md", "Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"] @@ -37,7 +38,7 @@ required-features = ["clap"] version = "1.0.3" [dependencies.cexpr] -version = "0.6" +version = "0.4" [dependencies.clang-sys] version = "1" @@ -48,7 +49,7 @@ version = "2" optional = true [dependencies.env_logger] -version = "0.9.0" +version = "0.8" optional = true [dependencies.lazy_static] @@ -84,7 +85,7 @@ version = "1.0.1" version = "1" [dependencies.which] -version = "4.2.1" +version = "3.0" optional = true default-features = false [dev-dependencies.clap] @@ -96,9 +97,6 @@ version = "0.1" [dev-dependencies.shlex] version = "1" -[dev-dependencies.tempfile] -version = "3" - [features] default = ["logging", "clap", "runtime", "which-rustfmt"] logging = ["env_logger", "log"] diff --git a/Cargo.toml.orig b/Cargo.toml.orig index ba41a22..dd30f09 100644 --- a/Cargo.toml.orig +++ b/Cargo.toml.orig @@ -14,7 +14,7 @@ readme = "README.md" repository = "https://github.com/rust-lang/rust-bindgen" documentation = "https://docs.rs/bindgen" homepage = "https://rust-lang.github.io/rust-bindgen/" -version = "0.59.2" +version = "0.58.1" edition = "2018" build = "build.rs" @@ -43,11 +43,10 @@ required-features = ["clap"] diff = "0.1" clap = "2" shlex = "1" -tempfile = "3" [dependencies] bitflags = "1.0.3" -cexpr = "0.6" +cexpr = "0.4" # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 clap = { version = "2", optional = true } clang-sys = { version = "1", features = ["clang_6_0"] } @@ -56,14 +55,16 @@ lazy_static = "1" peeking_take_while = "0.1.2" quote = { version = "1", default-features = false } regex = { version = "1.0", default-features = false , features = [ "std", "unicode"]} -which = { version = "4.2.1", optional = true, default-features = false } +which = { version = "3.0", optional = true, default-features = false } shlex = "1" rustc-hash = "1.0.1" +# New validation in 0.3.6 breaks bindgen-integration: +# https://github.com/alexcrichton/proc-macro2/commit/489c642. proc-macro2 = { version = "1", default-features = false } [dependencies.env_logger] optional = true -version = "0.9.0" +version = "0.8" [dependencies.log] optional = true @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/bindgen/bindgen-0.59.2.crate" + value: "https://static.crates.io/crates/bindgen/bindgen-0.58.1.crate" } - version: "0.59.2" + version: "0.58.1" license_type: NOTICE last_upgrade_date { - year: 2022 - month: 3 - day: 1 + year: 2021 + month: 4 + day: 16 } } @@ -39,7 +39,7 @@ extern "C" { ## MSRV -The minimum supported Rust version is **1.46**. +The minimum supported Rust version is **1.40**. No MSRV bump policy has been established yet, so MSRV may increase in any release. @@ -60,10 +60,6 @@ End-users should set these environment variables to modify `bindgen`'s behavior - Examples: - Specify alternate sysroot: `--sysroot=/path/to/sysroot` - Add include search path with spaces: `-I"/path/with spaces"` -- `BINDGEN_EXTRA_CLANG_ARGS_<TARGET>`: 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]. diff --git a/TEST_MAPPING b/TEST_MAPPING index e4ec3b3..a731acb 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,24 +1,14 @@ // Generated by update_crate_tests.py for tests that depend on this crate. { - "imports": [ - { - "path": "external/rust/crates/libsqlite3-sys" - } - ], "presubmit": [ { "name": "keystore2_test" }, { - "name": "legacykeystore_test" - } - ], - "presubmit-rust": [ - { - "name": "keystore2_test" + "name": "libsqlite3-sys_device_test_src_lib" }, { - "name": "legacykeystore_test" + "name": "vpnprofilestore_test" } ] } @@ -79,12 +79,4 @@ fn main() { println!("cargo:rerun-if-env-changed=LIBCLANG_PATH"); println!("cargo:rerun-if-env-changed=LIBCLANG_STATIC_PATH"); println!("cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS"); - println!( - "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", - std::env::var("TARGET").unwrap() - ); - println!( - "cargo:rerun-if-env-changed=BINDGEN_EXTRA_CLANG_ARGS_{}", - std::env::var("TARGET").unwrap().replace("-", "_") - ); } diff --git a/cargo2android.json b/cargo2android.json deleted file mode 100644 index 9e5e68b..0000000 --- a/cargo2android.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "copy-out": true, - "features": "clap,runtime,which-rustfmt", - "host-first-multilib": true, - "run": true -}
\ No newline at end of file diff --git a/src/callbacks.rs b/src/callbacks.rs index 9b34544..e288af4 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -95,12 +95,4 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { ) -> Option<ImplementsTrait> { None } - - /// Provide a list of custom derive attributes. - /// - /// If no additional attributes are wanted, this function should return an - /// empty `Vec`. - fn add_derives(&self, _name: &str) -> Vec<String> { - vec![] - } } diff --git a/src/clang.rs b/src/clang.rs index 074d459..6612508 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -4,7 +4,9 @@ #![allow(non_upper_case_globals, dead_code)] use crate::ir::context::BindgenContext; +use cexpr; use clang_sys::*; +use regex; use std::ffi::{CStr, CString}; use std::fmt; use std::hash::Hash; @@ -83,7 +85,7 @@ impl Cursor { let mut result = Vec::with_capacity(count); for i in 0..count { - let string_ptr = (*manglings).Strings.add(i); + let string_ptr = (*manglings).Strings.offset(i as isize); result.push(cxstring_to_string_leaky(*string_ptr)); } clang_disposeStringSet(manglings); @@ -221,12 +223,12 @@ impl Cursor { /// not tracking the type declaration but the location of the cursor, given /// clang doesn't expose a proper declaration for these types. pub fn is_template_like(&self) -> bool { - matches!( - self.kind(), + match self.kind() { CXCursor_ClassTemplate | - CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl - ) + CXCursor_ClassTemplatePartialSpecialization | + CXCursor_TypeAliasTemplateDecl => true, + _ => false, + } } /// Is this Cursor pointing to a function-like macro definition? @@ -239,7 +241,7 @@ impl Cursor { self.x.kind } - /// Returns true if the cursor is a definition + /// Returns true is the cursor is a definition pub fn is_definition(&self) -> bool { unsafe { clang_isCursorDefinition(self.x) != 0 } } @@ -273,7 +275,7 @@ impl Cursor { return parent.is_in_non_fully_specialized_template(); } - true + return true; } /// Is this cursor pointing a valid referent? @@ -400,9 +402,12 @@ impl Cursor { where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - let data = &mut visitor as *mut Visitor; unsafe { - clang_visitChildren(self.x, visit_children::<Visitor>, data.cast()); + clang_visitChildren( + self.x, + visit_children::<Visitor>, + mem::transmute(&mut visitor), + ); } } @@ -464,27 +469,6 @@ impl Cursor { unsafe { clang_Cursor_isFunctionInlined(self.x) != 0 } } - /// Is the referent a defaulted function? - pub fn is_defaulted_function(&self) -> bool { - unsafe { clang_CXXMethod_isDefaulted(self.x) != 0 } - } - - /// Is the referent a deleted function? - pub fn is_deleted_function(&self) -> bool { - // Unfortunately, libclang doesn't yet have an API for checking if a - // member function is deleted, but the following should be a good - // enough approximation. - // Deleted functions are implicitly inline according to paragraph 4 of - // [dcl.fct.def.delete] in the C++ standard. Normal inline functions - // have a definition in the same translation unit, so if this is an - // inline function without a definition, and it's not a defaulted - // function, we can reasonably safely conclude that it's a deleted - // function. - self.is_inlined_function() && - self.definition().is_none() && - !self.is_defaulted_function() - } - /// Get the width of this cursor's referent bit field, or `None` if the /// referent is not a bit field. pub fn bit_width(&self) -> Option<u32> { @@ -895,7 +879,7 @@ extern "C" fn visit_children<Visitor>( where Visitor: FnMut(Cursor) -> CXChildVisitResult, { - let func: &mut Visitor = unsafe { &mut *(data as *mut Visitor) }; + let func: &mut Visitor = unsafe { mem::transmute(data) }; let child = Cursor { x: cur }; (*func)(child) @@ -1022,7 +1006,7 @@ impl Type { let s = unsafe { cxstring_into_string(clang_getTypeSpelling(self.x)) }; // Clang 5.0 introduced changes in the spelling API so it returned the // full qualified name. Let's undo that here. - if s.split("::").all(is_valid_identifier) { + if s.split("::").all(|s| is_valid_identifier(s)) { if let Some(s) = s.split("::").last() { return s.to_owned(); } @@ -1050,7 +1034,7 @@ impl Type { ctx.target_pointer_size() as c_longlong } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 - CXType_Auto if self.is_non_deductible_auto_type() => -6, + CXType_Auto if self.is_non_deductible_auto_type() => return -6, _ => unsafe { clang_Type_getSizeOf(self.x) }, } } @@ -1063,7 +1047,7 @@ impl Type { ctx.target_pointer_size() as c_longlong } // Work-around https://bugs.llvm.org/show_bug.cgi?id=40813 - CXType_Auto if self.is_non_deductible_auto_type() => -6, + CXType_Auto if self.is_non_deductible_auto_type() => return -6, _ => unsafe { clang_Type_getAlignOf(self.x) }, } } @@ -1281,12 +1265,12 @@ impl Type { // nasty... But can happen in <type_traits>. Unfortunately I couldn't // reduce it enough :( self.template_args().map_or(false, |args| args.len() > 0) && - !matches!( - self.declaration().kind(), + match self.declaration().kind() { CXCursor_ClassTemplatePartialSpecialization | - CXCursor_TypeAliasTemplateDecl | - CXCursor_TemplateTemplateParameter - ) + CXCursor_TypeAliasTemplateDecl | + CXCursor_TemplateTemplateParameter => false, + _ => true, + } } /// Is this type an associated template type? Eg `T::Associated` in @@ -1401,12 +1385,6 @@ impl fmt::Display for SourceLocation { } } -impl fmt::Debug for SourceLocation { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", self) - } -} - /// A comment in the source text. /// /// Comments are sort of parsed by Clang, and have a tree structure. @@ -1705,7 +1683,11 @@ impl UnsavedFile { Contents: contents.as_ptr(), Length: contents.as_bytes().len() as c_ulong, }; - UnsavedFile { x, name, contents } + UnsavedFile { + x: x, + name: name, + contents: contents, + } } } @@ -1816,7 +1798,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { if let Some(refd) = c.referenced() { if refd != *c { - println!(); + println!(""); print_cursor( depth, String::from(prefix) + "referenced.", @@ -1827,7 +1809,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let canonical = c.canonical(); if canonical != *c { - println!(); + println!(""); print_cursor( depth, String::from(prefix) + "canonical.", @@ -1837,7 +1819,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { if let Some(specialized) = c.specialized() { if specialized != *c { - println!(); + println!(""); print_cursor( depth, String::from(prefix) + "specialized.", @@ -1847,7 +1829,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { } if let Some(parent) = c.fallible_semantic_parent() { - println!(); + println!(""); print_cursor( depth, String::from(prefix) + "semantic-parent.", @@ -1895,34 +1877,34 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let canonical = ty.canonical_type(); if canonical != *ty { - println!(); + println!(""); print_type(depth, String::from(prefix) + "canonical.", &canonical); } if let Some(pointee) = ty.pointee_type() { if pointee != *ty { - println!(); + println!(""); print_type(depth, String::from(prefix) + "pointee.", &pointee); } } if let Some(elem) = ty.elem_type() { if elem != *ty { - println!(); + println!(""); print_type(depth, String::from(prefix) + "elements.", &elem); } } if let Some(ret) = ty.ret_type() { if ret != *ty { - println!(); + println!(""); print_type(depth, String::from(prefix) + "return.", &ret); } } let named = ty.named(); if named != *ty && named.is_valid() { - println!(); + println!(""); print_type(depth, String::from(prefix) + "named.", &named); } } @@ -1930,13 +1912,13 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { print_indent(depth, "("); print_cursor(depth, "", c); - println!(); + println!(""); let ty = c.cur_type(); print_type(depth, "type.", &ty); let declaration = ty.declaration(); if declaration != *c && declaration.kind() != CXCursor_NoDeclFound { - println!(); + println!(""); print_cursor(depth, "type.declaration.", &declaration); } @@ -1944,7 +1926,7 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult { let mut found_children = false; c.visit(|s| { if !found_children { - println!(); + println!(""); found_children = true; } ast_dump(&s, depth + 1) diff --git a/src/codegen/helpers.rs b/src/codegen/helpers.rs index 2ce6894..205995b 100644 --- a/src/codegen/helpers.rs +++ b/src/codegen/helpers.rs @@ -230,14 +230,14 @@ pub mod ast_ty { } pub fn byte_array_expr(bytes: &[u8]) -> TokenStream { - let mut bytes: Vec<_> = bytes.to_vec(); + let mut bytes: Vec<_> = bytes.iter().cloned().collect(); bytes.push(0); quote! { [ #(#bytes),* ] } } pub fn cstr_expr(mut string: String) -> TokenStream { string.push('\0'); - let b = proc_macro2::Literal::byte_string(string.as_bytes()); + let b = proc_macro2::Literal::byte_string(&string.as_bytes()); quote! { #b } @@ -271,7 +271,7 @@ pub mod ast_ty { } warn!("Unknown non-finite float number: {:?}", f); - Err(()) + return Err(()); } pub fn arguments_from_signature( diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index 0e2cd33..b8fdd0d 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -2,6 +2,7 @@ use crate::ir::comp::{BitfieldUnit, CompKind, Field, FieldData, FieldMethods}; use crate::ir::context::BindgenContext; use crate::ir::item::{HasTypeParamInArray, IsOpaque, Item, ItemCanonicalName}; use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; +use proc_macro2; pub fn gen_debug_impl( ctx: &BindgenContext, @@ -22,8 +23,8 @@ pub fn gen_debug_impl( } CompKind::Struct => { let processed_fields = fields.iter().filter_map(|f| match f { - Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), - Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), + &Field::DataMember(ref fd) => fd.impl_debug(ctx, ()), + &Field::Bitfields(ref bu) => bu.impl_debug(ctx, ()), }); for (i, (fstring, toks)) in processed_fields.enumerate() { @@ -180,27 +181,27 @@ impl<'a> ImplDebug<'a> for Item { format!("{}: Array with length {}", name, len), vec![], )) - } else if len < RUST_DERIVE_IN_ARRAY_LIMIT || - ctx.options().rust_features().larger_arrays - { + } else if len < RUST_DERIVE_IN_ARRAY_LIMIT { // The simple case debug_print(name, quote! { #name_ident }) - } else if ctx.options().use_core { - // There is no String in core; reducing field visibility to avoid breaking - // no_std setups. - Some((format!("{}: [...]", name), vec![])) } else { - // Let's implement our own print function - Some(( - format!("{}: [{{}}]", name), - vec![quote! { - self.#name_ident - .iter() - .enumerate() - .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) - .collect::<String>() - }], - )) + if ctx.options().use_core { + // There is no String in core; reducing field visibility to avoid breaking + // no_std setups. + Some((format!("{}: [...]", name), vec![])) + } else { + // Let's implement our own print function + Some(( + format!("{}: [{{}}]", name), + vec![quote! { + self.#name_ident + .iter() + .enumerate() + .map(|(i, v)| format!("{}{:?}", if i > 0 { ", " } else { "" }, v)) + .collect::<String>() + }], + )) + } } } TypeKind::Vector(_, len) => { diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs index 960306f..5f2600e 100644 --- a/src/codegen/impl_partialeq.rs +++ b/src/codegen/impl_partialeq.rs @@ -2,6 +2,7 @@ use crate::ir::comp::{CompInfo, CompKind, Field, FieldMethods}; use crate::ir::context::BindgenContext; use crate::ir::item::{IsOpaque, Item}; use crate::ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT}; +use proc_macro2; /// Generate a manual implementation of `PartialEq` trait for the /// specified compound type. @@ -50,7 +51,7 @@ pub fn gen_partialeq_impl( } Field::Bitfields(ref bu) => { for bitfield in bu.bitfields() { - if bitfield.name().is_some() { + if let Some(_) = bitfield.name() { let getter_name = bitfield.getter_name(); let name_ident = ctx.rust_ident_raw(getter_name); tokens.push(quote! { @@ -103,7 +104,7 @@ fn gen_field( TypeKind::Opaque => quote_equals(name_ident), TypeKind::TemplateInstantiation(ref inst) => { - if inst.is_opaque(ctx, ty_item) { + if inst.is_opaque(ctx, &ty_item) { quote! { &self. #name_ident [..] == &other. #name_ident [..] } @@ -113,9 +114,7 @@ fn gen_field( } TypeKind::Array(_, len) => { - if len <= RUST_DERIVE_IN_ARRAY_LIMIT || - ctx.options().rust_features().larger_arrays - { + if len <= RUST_DERIVE_IN_ARRAY_LIMIT { quote_equals(name_ident) } else { quote! { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 19886e3..e62b1a8 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -48,6 +48,7 @@ use proc_macro2::{self, Ident, Span}; use quote::TokenStreamExt; use crate::{Entry, HashMap, HashSet}; +use std; use std::borrow::Cow; use std::cell::Cell; use std::collections::VecDeque; @@ -57,7 +58,7 @@ use std::ops; use std::str::FromStr; // Name of type defined in constified enum module -pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &str = "Type"; +pub static CONSTIFIED_ENUM_MODULE_REPR_NAME: &'static str = "Type"; fn top_level_path( ctx: &BindgenContext, @@ -617,18 +618,12 @@ impl CodeGenerator for Var { return; } - let mut attrs = vec![]; - if let Some(comment) = item.comment(ctx) { - attrs.push(attributes::doc(comment)); - } - let ty = self.ty().to_rust_ty_or_opaque(ctx, &()); if let Some(val) = self.val() { match *val { VarType::Bool(val) => { result.push(quote! { - #(#attrs)* pub const #canonical_ident : #ty = #val ; }); } @@ -648,7 +643,6 @@ impl CodeGenerator for Var { helpers::ast_ty::uint_expr(val as _) }; result.push(quote! { - #(#attrs)* pub const #canonical_ident : #ty = #val ; }); } @@ -665,49 +659,37 @@ impl CodeGenerator for Var { match String::from_utf8(bytes.clone()) { Ok(string) => { let cstr = helpers::ast_ty::cstr_expr(string); - if ctx - .options() - .rust_features - .static_lifetime_elision - { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : &#ty = #cstr ; - }); - } else { - result.push(quote! { - #(#attrs)* - pub const #canonical_ident : &'static #ty = #cstr ; - }); - } + result.push(quote! { + pub const #canonical_ident : &'static #ty = #cstr ; + }); } Err(..) => { let bytes = helpers::ast_ty::byte_array_expr(bytes); result.push(quote! { - #(#attrs)* pub const #canonical_ident : #ty = #bytes ; }); } } } VarType::Float(f) => { - if let Ok(expr) = helpers::ast_ty::float_expr(ctx, f) { - result.push(quote! { - #(#attrs)* + match helpers::ast_ty::float_expr(ctx, f) { + Ok(expr) => result.push(quote! { pub const #canonical_ident : #ty = #expr ; - }); + }), + Err(..) => return, } } VarType::Char(c) => { result.push(quote! { - #(#attrs)* pub const #canonical_ident : #ty = #c ; }); } } } else { + let mut attrs = vec![]; + // If necessary, apply a `#[link_name]` attribute - let link_name = self.mangled_name().unwrap_or_else(|| self.name()); + let link_name = self.mangled_name().unwrap_or(self.name()); if !utils::names_will_be_identical_after_mangling( &canonical_name, link_name, @@ -765,6 +747,7 @@ impl CodeGenerator for Type { // converted to rust types in fields, arguments, and such. // NOTE(emilio): If you add to this list, make sure to also add // it to BindgenContext::compute_allowlisted_and_codegen_items. + return; } TypeKind::TemplateInstantiation(ref inst) => { inst.codegen(ctx, result, item) @@ -894,9 +877,12 @@ impl CodeGenerator for Type { // We prefer using `pub use` over `pub type` because of: // https://github.com/rust-lang/rust/issues/26264 - // These are the only characters allowed in simple - // paths, eg `good::dogs::Bront`. - if inner_rust_type.to_string().chars().all(|c| matches!(c, 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ')) && outer_params.is_empty() && + if inner_rust_type.to_string().chars().all(|c| match c { + // These are the only characters allowed in simple + // paths, eg `good::dogs::Bront`. + 'A'..='Z' | 'a'..='z' | '0'..='9' | ':' | '_' | ' ' => true, + _ => false, + }) && outer_params.is_empty() && !is_opaque && alias_style == AliasVariation::TypeAlias && inner_item.expect_type().canonical_type(ctx).is_enum() @@ -1507,10 +1493,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { let mut ctor_impl = quote! {}; // We cannot generate any constructor if the underlying storage can't - // implement AsRef<[u8]> / AsMut<[u8]> / etc, or can't derive Default. - // - // We don't check `larger_arrays` here because Default does still have - // the 32 items limitation. + // implement AsRef<[u8]> / AsMut<[u8]> / etc. let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT; let mut access_spec = !fields_should_be_private; @@ -1520,9 +1503,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { continue; } - if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT && - !ctx.options().rust_features().larger_arrays - { + if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT { continue; } @@ -1772,7 +1753,7 @@ impl CodeGenerator for CompInfo { let inner_item = ctx.resolve_item(base.ty); let mut inner = inner_item.to_rust_ty_or_opaque(ctx, &()); - inner.append_implicit_template_params(ctx, inner_item); + inner.append_implicit_template_params(ctx, &inner_item); let field_name = ctx.rust_ident(&base.field_name); struct_layout.saw_base(inner_item.expect_type()); @@ -1807,14 +1788,6 @@ impl CodeGenerator for CompInfo { (), ); } - // Check whether an explicit padding field is needed - // at the end. - if let Some(comp_layout) = layout { - fields.extend( - struct_layout - .add_tail_padding(&canonical_name, comp_layout), - ); - } } if is_opaque { @@ -2015,24 +1988,10 @@ impl CodeGenerator for CompInfo { let mut derives: Vec<_> = derivable_traits.into(); derives.extend(item.annotations().derives().iter().map(String::as_str)); - // The custom derives callback may return a list of derive attributes; - // add them to the end of the list. - let custom_derives; - if let Some(cb) = &ctx.options().parse_callbacks { - custom_derives = cb.add_derives(&canonical_name); - // 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())); - }; - if !derives.is_empty() { attributes.push(attributes::derives(&derives)) } - if item.annotations().must_use_type() || ctx.must_use_type_by_name(item) - { - attributes.push(attributes::must_use()); - } - let mut tokens = if is_union && struct_layout.is_rust_union() { quote! { #( #attributes )* @@ -2131,11 +2090,11 @@ impl CodeGenerator for CompInfo { }) .flat_map(|field| { let name = field.name().unwrap(); - field.offset().map(|offset| { + field.offset().and_then(|offset| { let field_offset = offset / 8; let field_name = ctx.rust_ident(name); - quote! { + Some(quote! { assert_eq!( unsafe { &(*(::#prefix::ptr::null::<#canonical_ident>())).#field_name as *const _ as usize @@ -2143,7 +2102,7 @@ impl CodeGenerator for CompInfo { #field_offset, concat!("Offset of field: ", stringify!(#canonical_ident), "::", stringify!(#field_name)) ); - } + }) }) }) .collect::<Vec<proc_macro2::TokenStream>>(); @@ -2228,32 +2187,9 @@ impl CodeGenerator for CompInfo { if needs_default_impl { let prefix = ctx.trait_prefix(); - let body = if ctx.options().rust_features().maybe_uninit { - quote! { - let mut s = ::#prefix::mem::MaybeUninit::<Self>::uninit(); - unsafe { - ::#prefix::ptr::write_bytes(s.as_mut_ptr(), 0, 1); - s.assume_init() - } - } - } else { - quote! { - unsafe { - let mut s: Self = ::#prefix::mem::uninitialized(); - ::#prefix::ptr::write_bytes(&mut s, 0, 1); - s - } - } - }; - // Note we use `ptr::write_bytes()` instead of `mem::zeroed()` because the latter does - // not necessarily ensure padding bytes are zeroed. Some C libraries are sensitive to - // non-zero padding bytes, especially when forwards/backwards compatability is - // involved. result.push(quote! { impl #generics Default for #ty_for_impl { - fn default() -> Self { - #body - } + fn default() -> Self { unsafe { ::#prefix::mem::zeroed() } } } }); } @@ -2353,7 +2289,7 @@ impl MethodCodegen for Method { return; } let function = function_item.expect_function(); - let times_seen = function.codegen(ctx, result, function_item); + let times_seen = function.codegen(ctx, result, &function_item); let times_seen = match times_seen { Some(seen) => seen, None => return, @@ -2419,7 +2355,7 @@ impl MethodCodegen for Method { } let mut exprs = - helpers::ast_ty::arguments_from_signature(signature, ctx); + helpers::ast_ty::arguments_from_signature(&signature, ctx); let mut stmts = vec![]; @@ -2476,7 +2412,8 @@ impl MethodCodegen for Method { #( #stmts );* }; - let mut attrs = vec![attributes::inline()]; + let mut attrs = vec![]; + attrs.push(attributes::inline()); if signature.must_use() && ctx.options().rust_features().must_use_function @@ -2517,13 +2454,19 @@ pub enum EnumVariation { impl EnumVariation { fn is_rust(&self) -> bool { - matches!(*self, EnumVariation::Rust { .. }) + match *self { + EnumVariation::Rust { .. } => true, + _ => false, + } } /// Both the `Const` and `ModuleConsts` variants will cause this to return /// true. fn is_const(&self) -> bool { - matches!(*self, EnumVariation::Consts | EnumVariation::ModuleConsts) + match *self { + EnumVariation::Consts | EnumVariation::ModuleConsts => true, + _ => false, + } } } @@ -2601,7 +2544,10 @@ impl<'a> EnumBuilder<'a> { /// Returns true if the builder is for a rustified enum. fn is_rust_enum(&self) -> bool { - matches!(*self, EnumBuilder::Rust { .. }) + match *self { + EnumBuilder::Rust { .. } => true, + _ => false, + } } /// Create a new enum given an item builder, a canonical name, a name for @@ -2998,43 +2944,18 @@ impl CodeGenerator for Enum { attrs.push(attributes::doc(comment)); } - if item.annotations().must_use_type() || ctx.must_use_type_by_name(item) - { - attrs.push(attributes::must_use()); - } - if !variation.is_const() { let mut derives = derives_of_item(item, ctx); - // For backwards compat, enums always derive Debug/Clone/Eq/PartialEq/Hash, even + // For backwards compat, enums always derive Clone/Eq/PartialEq/Hash, even // if we don't generate those by default. - if !item.annotations().disallow_debug() { - derives.insert(DerivableTraits::DEBUG); - } - if !item.annotations().disallow_copy() { - derives.insert(DerivableTraits::COPY); - } derives.insert( DerivableTraits::CLONE | + DerivableTraits::COPY | DerivableTraits::HASH | DerivableTraits::PARTIAL_EQ | DerivableTraits::EQ, ); - let mut derives: Vec<_> = derives.into(); - for derive in item.annotations().derives().iter() { - if !derives.contains(&derive.as_str()) { - derives.push(derive); - } - } - - // The custom derives callback may return a list of derive attributes; - // add them to the end of the list. - let custom_derives; - if let Some(cb) = &ctx.options().parse_callbacks { - custom_derives = cb.add_derives(&name); - // 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())); - }; - + let derives: Vec<_> = derives.into(); attrs.push(attributes::derives(&derives)); } @@ -3092,7 +3013,7 @@ impl CodeGenerator for Enum { let constant_mangling_prefix = if ctx.options().prepend_enum_name { if enum_ty.name().is_none() { - parent_canonical_name.as_deref() + parent_canonical_name.as_ref().map(|n| &**n) } else { Some(&*name) } @@ -3651,12 +3572,13 @@ impl TryToRustTy for Type { let void = c_void(ctx); return Ok(void.to_ptr(/* is_const = */ false)); } + let template_params = item + .used_template_params(ctx) + .into_iter() + .filter(|param| param.is_template_param(ctx, &())) + .collect::<Vec<_>>(); - if item.is_opaque(ctx, &()) && - item.used_template_params(ctx) - .into_iter() - .any(|param| param.is_template_param(ctx, &())) - { + if item.is_opaque(ctx, &()) && !template_params.is_empty() { self.try_to_opaque(ctx, item) } else if let Some(ty) = self .name() @@ -3685,8 +3607,10 @@ impl TryToRustTy for Type { inner.into_resolver().through_type_refs().resolve(ctx); let inner_ty = inner.expect_type(); - let is_objc_pointer = - matches!(inner_ty.kind(), TypeKind::ObjCInterface(..)); + let is_objc_pointer = match inner_ty.kind() { + TypeKind::ObjCInterface(..) => true, + _ => false, + }; // Regardless if we can properly represent the inner type, we // should always generate a proper pointer here, so use @@ -3819,8 +3743,8 @@ impl TryToRustTy for FunctionSig { _: &(), ) -> error::Result<proc_macro2::TokenStream> { // TODO: we might want to consider ignoring the reference return value. - let ret = utils::fnsig_return_ty(ctx, self); - let arguments = utils::fnsig_arguments(ctx, self); + let ret = utils::fnsig_return_ty(ctx, &self); + let arguments = utils::fnsig_arguments(ctx, &self); let abi = self.abi(); match abi { @@ -4062,12 +3986,12 @@ impl CodeGenerator for ObjCInterface { impl_items.push(impl_item); } + let instance_method_names: Vec<_> = + self.methods().iter().map(|m| m.rust_name()).collect(); + for class_method in self.class_methods() { - let ambiquity = self - .methods() - .iter() - .map(|m| m.rust_name()) - .any(|x| x == class_method.rust_name()); + let ambiquity = + instance_method_names.contains(&class_method.rust_name()); let prefix = if ambiquity { "class_" } else { "" }; let impl_item = objc_method_codegen( ctx, @@ -4274,16 +4198,6 @@ pub(crate) fn codegen( } } - if let Some(spec) = context.options().depfile.as_ref() { - match spec.write(context.deps()) { - Ok(()) => info!( - "Your depfile was generated successfully into: {}", - spec.depfile_path.display() - ), - Err(e) => warn!("{}", e), - } - } - context.resolve_item(context.root_module()).codegen( context, &mut result, @@ -4659,7 +4573,7 @@ pub mod utils { TypeKind::Array(t, _) => { let stream = if ctx.options().array_pointers_in_arguments { - arg_ty.to_rust_ty_or_opaque(ctx, arg_item) + arg_ty.to_rust_ty_or_opaque(ctx, &arg_item) } else { t.to_rust_ty_or_opaque(ctx, &()) }; diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 657be0b..2e4b973 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -217,11 +217,8 @@ impl<'a> StructLayoutTracker<'a> { let padding_layout = if self.is_packed || is_union { None } else { - let force_padding = self.ctx.options().force_explicit_padding; - // Otherwise the padding is useless. - let need_padding = force_padding || - padding_bytes >= field_layout.align || + let need_padding = padding_bytes >= field_layout.align || field_layout.align > MAX_GUARANTEED_ALIGN; debug!( @@ -239,14 +236,11 @@ impl<'a> StructLayoutTracker<'a> { field_layout ); - let padding_align = if force_padding { - 1 - } else { - cmp::min(field_layout.align, MAX_GUARANTEED_ALIGN) - }; - if need_padding && padding_bytes != 0 { - Some(Layout::new(padding_bytes, padding_align)) + Some(Layout::new( + padding_bytes, + cmp::min(field_layout.align, MAX_GUARANTEED_ALIGN), + )) } else { None } @@ -268,37 +262,6 @@ impl<'a> StructLayoutTracker<'a> { padding_layout.map(|layout| self.padding_field(layout)) } - pub fn add_tail_padding( - &mut self, - comp_name: &str, - comp_layout: Layout, - ) -> Option<proc_macro2::TokenStream> { - // Only emit an padding field at the end of a struct if the - // user configures explicit padding. - if !self.ctx.options().force_explicit_padding { - return None; - } - - // Padding doesn't make sense for rust unions. - if self.is_rust_union { - return None; - } - - if self.latest_offset == comp_layout.size { - // This struct does not contain tail padding. - return None; - } - - trace!( - "need a tail padding field for {}: offset {} -> size {}", - comp_name, - self.latest_offset, - comp_layout.size - ); - let size = comp_layout.size - self.latest_offset; - Some(self.padding_field(Layout::new(size, 0))) - } - pub fn pad_struct( &mut self, layout: Layout, @@ -433,6 +396,6 @@ impl<'a> StructLayoutTracker<'a> { // Else, just align the obvious way. self.latest_offset += self.padding_bytes(layout); - false + return false; } } diff --git a/src/deps.rs b/src/deps.rs deleted file mode 100644 index 479c396..0000000 --- a/src/deps.rs +++ /dev/null @@ -1,20 +0,0 @@ -/// Generating build depfiles from parsed bindings. -use std::{collections::BTreeSet, path::PathBuf}; - -#[derive(Debug)] -pub(crate) struct DepfileSpec { - pub output_module: String, - pub depfile_path: PathBuf, -} - -impl DepfileSpec { - pub fn write(&self, deps: &BTreeSet<String>) -> std::io::Result<()> { - let mut buf = format!("{}:", self.output_module); - - for file in deps { - buf = format!("{} {}", buf, file); - } - - std::fs::write(&self.depfile_path, &buf) - } -} diff --git a/src/features.rs b/src/features.rs index a786f07..4ec9dee 100644 --- a/src/features.rs +++ b/src/features.rs @@ -87,9 +87,8 @@ macro_rules! rust_target_base { $x_macro!( /// Rust stable 1.0 => Stable_1_0 => 1.0; - /// Rust stable 1.17 - /// * Static lifetime elision ([RFC 1623](https://github.com/rust-lang/rfcs/blob/master/text/1623-static.md)) - => Stable_1_17 => 1.17; + /// Rust stable 1.1 + => Stable_1_1 => 1.1; /// Rust stable 1.19 /// * Untagged unions ([RFC 1444](https://github.com/rust-lang/rfcs/blob/master/text/1444-union.md)) => Stable_1_19 => 1.19; @@ -124,9 +123,6 @@ macro_rules! rust_target_base { /// Rust stable 1.40 /// * `non_exhaustive` enums/structs ([Tracking issue](https://github.com/rust-lang/rust/issues/44109)) => Stable_1_40 => 1.40; - /// Rust stable 1.47 - /// * `larger_arrays` ([Tracking issue](https://github.com/rust-lang/rust/pull/74060)) - => Stable_1_47 => 1.47; /// Nightly rust /// * `thiscall` calling convention ([Tracking issue](https://github.com/rust-lang/rust/issues/42202)) => Nightly => nightly; @@ -138,7 +134,7 @@ rust_target_base!(rust_target_def); rust_target_base!(rust_target_values_def); /// Latest stable release of Rust -pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_47; +pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_40; /// Create RustFeatures struct definition, new(), and a getter for each field macro_rules! rust_feature_def { @@ -192,9 +188,6 @@ macro_rules! rust_feature_def { // documentation for the relevant variant in the rust_target_base macro // definition. rust_feature_def!( - Stable_1_17 { - => static_lifetime_elision; - } Stable_1_19 { => untagged_union; } @@ -229,9 +222,6 @@ rust_feature_def!( Stable_1_40 { => non_exhaustive; } - Stable_1_47 { - => larger_arrays; - } Nightly { => thiscall_abi; } @@ -253,8 +243,7 @@ mod test { fn target_features() { let f_1_0 = RustFeatures::from(RustTarget::Stable_1_0); assert!( - !f_1_0.static_lifetime_elision && - !f_1_0.core_ffi_c_void && + !f_1_0.core_ffi_c_void && !f_1_0.untagged_union && !f_1_0.associated_const && !f_1_0.builtin_clone_impls && @@ -263,8 +252,7 @@ mod test { ); let f_1_21 = RustFeatures::from(RustTarget::Stable_1_21); assert!( - f_1_21.static_lifetime_elision && - !f_1_21.core_ffi_c_void && + !f_1_21.core_ffi_c_void && f_1_21.untagged_union && f_1_21.associated_const && f_1_21.builtin_clone_impls && @@ -273,8 +261,7 @@ mod test { ); let f_nightly = RustFeatures::from(RustTarget::Nightly); assert!( - f_nightly.static_lifetime_elision && - f_nightly.core_ffi_c_void && + f_nightly.core_ffi_c_void && f_nightly.untagged_union && f_nightly.associated_const && f_nightly.builtin_clone_impls && @@ -293,7 +280,6 @@ mod test { #[test] fn str_to_target() { test_target("1.0", RustTarget::Stable_1_0); - test_target("1.17", RustTarget::Stable_1_17); test_target("1.19", RustTarget::Stable_1_19); test_target("1.21", RustTarget::Stable_1_21); test_target("1.25", RustTarget::Stable_1_25); diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs index f63458e..be62666 100644 --- a/src/ir/analysis/derive.rs +++ b/src/ir/analysis/derive.rs @@ -9,7 +9,6 @@ use crate::ir::context::{BindgenContext, ItemId}; use crate::ir::derive::CanDerive; use crate::ir::function::FunctionSig; use crate::ir::item::{IsOpaque, Item}; -use crate::ir::layout::Layout; use crate::ir::template::TemplateParameters; use crate::ir::traversal::{EdgeKind, Trace}; use crate::ir::ty::RUST_DERIVE_IN_ARRAY_LIMIT; @@ -160,7 +159,7 @@ impl<'ctx> CannotDerive<'ctx> { return can_derive; } - if self.derive_trait.not_by_name(self.ctx, item) { + if self.derive_trait.not_by_name(self.ctx, &item) { trace!( " cannot derive {} for explicitly excluded type", self.derive_trait @@ -224,13 +223,13 @@ impl<'ctx> CannotDerive<'ctx> { let inner_type = self.ctx.resolve_type(inner).canonical_type(self.ctx); if let TypeKind::Function(ref sig) = *inner_type.kind() { - self.derive_trait.can_derive_fnptr(sig) + return self.derive_trait.can_derive_fnptr(sig); } else { - self.derive_trait.can_derive_pointer() + return self.derive_trait.can_derive_pointer(); } } TypeKind::Function(ref sig) => { - self.derive_trait.can_derive_fnptr(sig) + return self.derive_trait.can_derive_fnptr(sig) } // Complex cases need more information @@ -256,7 +255,7 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } - if self.derive_trait.can_derive_large_array(self.ctx) { + if self.derive_trait.can_derive_large_array() { trace!(" array can derive {}", self.derive_trait); return CanDerive::Yes; } @@ -271,7 +270,7 @@ impl<'ctx> CannotDerive<'ctx> { " array is small enough to derive {}", self.derive_trait ); - CanDerive::Yes + return CanDerive::Yes; } TypeKind::Vector(t, len) => { let inner_type = @@ -286,7 +285,7 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } assert_ne!(len, 0, "vectors cannot have zero length"); - self.derive_trait.can_derive_vector() + return self.derive_trait.can_derive_vector(); } TypeKind::Comp(ref info) => { @@ -378,7 +377,7 @@ impl<'ctx> CannotDerive<'ctx> { // Bitfield units are always represented as arrays of u8, but // they're not traced as arrays, so we need to check here // instead. - if !self.derive_trait.can_derive_large_array(self.ctx) && + if !self.derive_trait.can_derive_large_array() && info.has_too_large_bitfield_unit() && !item.is_opaque(self.ctx, &()) { @@ -390,7 +389,7 @@ impl<'ctx> CannotDerive<'ctx> { } let pred = self.derive_trait.consider_edge_comp(); - self.constrain_join(item, pred) + return self.constrain_join(item, pred); } TypeKind::ResolvedTypeRef(..) | @@ -398,12 +397,12 @@ impl<'ctx> CannotDerive<'ctx> { TypeKind::Alias(..) | TypeKind::BlockPointer(..) => { let pred = self.derive_trait.consider_edge_typeref(); - self.constrain_join(item, pred) + return self.constrain_join(item, pred); } TypeKind::TemplateInstantiation(..) => { let pred = self.derive_trait.consider_edge_tmpl_inst(); - self.constrain_join(item, pred) + return self.constrain_join(item, pred); } TypeKind::Opaque => unreachable!( @@ -471,7 +470,10 @@ impl DeriveTrait { fn consider_edge_comp(&self) -> EdgePredicate { match self { DeriveTrait::PartialEqOrPartialOrd => consider_edge_default, - _ => |kind| matches!(kind, EdgeKind::BaseMember | EdgeKind::Field), + _ => |kind| match kind { + EdgeKind::BaseMember | EdgeKind::Field => true, + _ => false, + }, } } @@ -494,37 +496,48 @@ impl DeriveTrait { } } - fn can_derive_large_array(&self, ctx: &BindgenContext) -> bool { - if ctx.options().rust_features().larger_arrays { - !matches!(self, DeriveTrait::Default) - } else { - matches!(self, DeriveTrait::Copy) + fn can_derive_large_array(&self) -> bool { + match self { + DeriveTrait::Copy => true, + _ => false, } } fn can_derive_union(&self) -> bool { - matches!(self, DeriveTrait::Copy) + match self { + DeriveTrait::Copy => true, + _ => false, + } } fn can_derive_compound_with_destructor(&self) -> bool { - !matches!(self, DeriveTrait::Copy) + match self { + DeriveTrait::Copy => false, + _ => true, + } } fn can_derive_compound_with_vtable(&self) -> bool { - !matches!(self, DeriveTrait::Default) + match self { + DeriveTrait::Default => false, + _ => true, + } } fn can_derive_compound_forward_decl(&self) -> bool { - matches!(self, DeriveTrait::Copy | DeriveTrait::Debug) + match self { + DeriveTrait::Copy | DeriveTrait::Debug => true, + _ => false, + } } fn can_derive_incomplete_array(&self) -> bool { - !matches!( - self, + match self { DeriveTrait::Copy | - DeriveTrait::Hash | - DeriveTrait::PartialEqOrPartialOrd - ) + DeriveTrait::Hash | + DeriveTrait::PartialEqOrPartialOrd => false, + _ => true, + } } fn can_derive_fnptr(&self, f: &FunctionSig) -> CanDerive { @@ -673,10 +686,10 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { Some(ty) => { let mut can_derive = self.constrain_type(item, ty); if let CanDerive::Yes = can_derive { - let is_reached_limit = - |l: Layout| l.align > RUST_DERIVE_IN_ARRAY_LIMIT; - if !self.derive_trait.can_derive_large_array(self.ctx) && - ty.layout(self.ctx).map_or(false, is_reached_limit) + if !self.derive_trait.can_derive_large_array() && + ty.layout(self.ctx).map_or(false, |l| { + l.align > RUST_DERIVE_IN_ARRAY_LIMIT + }) { // We have to be conservative: the struct *could* have enough // padding that we emit an array that is longer than diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs index 74fd73d..5fa22e3 100644 --- a/src/ir/analysis/has_destructor.rs +++ b/src/ir/analysis/has_destructor.rs @@ -41,16 +41,16 @@ pub struct HasDestructorAnalysis<'ctx> { impl<'ctx> HasDestructorAnalysis<'ctx> { fn consider_edge(kind: EdgeKind) -> bool { - // These are the only edges that can affect whether a type has a - // destructor or not. - matches!( - kind, + match kind { + // These are the only edges that can affect whether a type has a + // destructor or not. EdgeKind::TypeReference | - EdgeKind::BaseMember | - EdgeKind::Field | - EdgeKind::TemplateArgument | - EdgeKind::TemplateDeclaration - ) + EdgeKind::BaseMember | + EdgeKind::Field | + EdgeKind::TemplateArgument | + EdgeKind::TemplateDeclaration => true, + _ => false, + } } fn insert<Id: Into<ItemId>>(&mut self, id: Id) -> ConstrainResult { diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs index 8ac47a6..7f5f911 100644 --- a/src/ir/analysis/has_vtable.rs +++ b/src/ir/analysis/has_vtable.rs @@ -79,14 +79,14 @@ pub struct HasVtableAnalysis<'ctx> { impl<'ctx> HasVtableAnalysis<'ctx> { fn consider_edge(kind: EdgeKind) -> bool { - // These are the only edges that can affect whether a type has a - // vtable or not. - matches!( - kind, + match kind { + // These are the only edges that can affect whether a type has a + // vtable or not. EdgeKind::TypeReference | - EdgeKind::BaseMember | - EdgeKind::TemplateDeclaration - ) + EdgeKind::BaseMember | + EdgeKind::TemplateDeclaration => true, + _ => false, + } } fn insert<Id: Into<ItemId>>( diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs index eb9a1c0..ec4d20f 100644 --- a/src/ir/analysis/mod.rs +++ b/src/ir/analysis/mod.rs @@ -184,7 +184,7 @@ where let mut dependencies = HashMap::default(); for &item in ctx.allowlisted_items() { - dependencies.entry(item).or_insert_with(Vec::new); + dependencies.entry(item).or_insert(vec![]); { // We reverse our natural IR graph edges to find dependencies @@ -197,7 +197,7 @@ where { dependencies .entry(sub_item) - .or_insert_with(Vec::new) + .or_insert(vec![]) .push(item); } }, diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs index 251c374..a3ef753 100644 --- a/src/ir/analysis/sizedness.rs +++ b/src/ir/analysis/sizedness.rs @@ -112,17 +112,17 @@ pub struct SizednessAnalysis<'ctx> { impl<'ctx> SizednessAnalysis<'ctx> { fn consider_edge(kind: EdgeKind) -> bool { - // These are the only edges that can affect whether a type is - // zero-sized or not. - matches!( - kind, + match kind { + // These are the only edges that can affect whether a type is + // zero-sized or not. EdgeKind::TemplateArgument | - EdgeKind::TemplateParameterDefinition | - EdgeKind::TemplateDeclaration | - EdgeKind::TypeReference | - EdgeKind::BaseMember | - EdgeKind::Field - ) + EdgeKind::TemplateParameterDefinition | + EdgeKind::TemplateDeclaration | + EdgeKind::TypeReference | + EdgeKind::BaseMember | + EdgeKind::Field => true, + _ => false, + } } /// Insert an incremental result, and return whether this updated our diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs index e88b774..c2f18b1 100644 --- a/src/ir/analysis/template_params.rs +++ b/src/ir/analysis/template_params.rs @@ -239,7 +239,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> { let args = instantiation .template_arguments() - .iter() + .into_iter() .map(|a| { a.into_resolver() .through_type_refs() @@ -399,8 +399,8 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { .collect(); for item in allowlisted_and_blocklisted_items { - dependencies.entry(item).or_insert_with(Vec::new); - used.entry(item).or_insert_with(|| Some(ItemSet::new())); + dependencies.entry(item).or_insert(vec![]); + used.entry(item).or_insert(Some(ItemSet::new())); { // We reverse our natural IR graph edges to find dependencies @@ -408,11 +408,10 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { item.trace( ctx, &mut |sub_item: ItemId, _| { - used.entry(sub_item) - .or_insert_with(|| Some(ItemSet::new())); + used.entry(sub_item).or_insert(Some(ItemSet::new())); dependencies .entry(sub_item) - .or_insert_with(Vec::new) + .or_insert(vec![]) .push(item); }, &(), @@ -422,42 +421,39 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { // Additionally, whether a template instantiation's template // arguments are used depends on whether the template declaration's // 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 - { - let decl = ctx.resolve_type(inst.template_definition()); - let args = inst.template_arguments(); - - // Although template definitions should always have - // template parameters, there is a single exception: - // opaque templates. Hence the unwrap_or. - let params = decl.self_template_params(ctx); - - for (arg, param) in args.iter().zip(params.iter()) { - let arg = arg - .into_resolver() - .through_type_aliases() - .through_type_refs() - .resolve(ctx) - .id(); - - let param = param - .into_resolver() - .through_type_aliases() - .through_type_refs() - .resolve(ctx) - .id(); - - used.entry(arg).or_insert_with(|| Some(ItemSet::new())); - used.entry(param).or_insert_with(|| Some(ItemSet::new())); - - dependencies - .entry(arg) - .or_insert_with(Vec::new) - .push(param); + ctx.resolve_item(item).as_type().map(|ty| match ty.kind() { + &TypeKind::TemplateInstantiation(ref inst) => { + let decl = ctx.resolve_type(inst.template_definition()); + let args = inst.template_arguments(); + + // Although template definitions should always have + // template parameters, there is a single exception: + // opaque templates. Hence the unwrap_or. + let params = decl.self_template_params(ctx); + + for (arg, param) in args.iter().zip(params.iter()) { + let arg = arg + .into_resolver() + .through_type_aliases() + .through_type_refs() + .resolve(ctx) + .id(); + + let param = param + .into_resolver() + .through_type_aliases() + .through_type_refs() + .resolve(ctx) + .id(); + + used.entry(arg).or_insert(Some(ItemSet::new())); + used.entry(param).or_insert(Some(ItemSet::new())); + + dependencies.entry(arg).or_insert(vec![]).push(param); + } } - } + _ => {} + }); } if cfg!(feature = "testing_only_extra_assertions") { @@ -486,10 +482,10 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> { } UsedTemplateParameters { - ctx, - used, - dependencies, - allowlisted_items, + ctx: ctx, + used: used, + dependencies: dependencies, + allowlisted_items: allowlisted_items, } } diff --git a/src/ir/annotations.rs b/src/ir/annotations.rs index 9bcda50..12664f6 100644 --- a/src/ir/annotations.rs +++ b/src/ir/annotations.rs @@ -25,7 +25,7 @@ pub enum FieldAccessorKind { /// documentation: /// /// http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html -#[derive(Default, Clone, PartialEq, Debug)] +#[derive(Clone, PartialEq, Debug)] pub struct Annotations { /// Whether this item is marked as opaque. Only applies to types. opaque: bool, @@ -42,8 +42,6 @@ pub struct Annotations { disallow_debug: bool, /// Manually disable deriving/implement default on this type. disallow_default: bool, - /// Whether to add a #[must_use] annotation to this type. - must_use_type: bool, /// Whether fields should be marked as private or not. You can set this on /// structs (it will apply to all the fields), or individual fields. private_fields: Option<bool>, @@ -77,6 +75,23 @@ fn parse_accessor(s: &str) -> FieldAccessorKind { } } +impl Default for Annotations { + fn default() -> Self { + Annotations { + opaque: false, + hide: false, + use_instead_of: None, + disallow_copy: false, + disallow_debug: false, + disallow_default: false, + private_fields: None, + accessor_kind: None, + constify_enum_variant: false, + derives: vec![], + } + } +} + impl Annotations { /// Construct new annotations for the given cursor and its bindgen comments /// (if any). @@ -125,7 +140,7 @@ impl Annotations { /// /// That is, code for `Foo` is used to generate `Bar`. pub fn use_instead_of(&self) -> Option<&[String]> { - self.use_instead_of.as_deref() + self.use_instead_of.as_ref().map(|s| &**s) } /// The list of derives that have been specified in this annotation. @@ -148,11 +163,6 @@ impl Annotations { self.disallow_default } - /// Should this type get a `#[must_use]` annotation? - pub fn must_use_type(&self) -> bool { - self.must_use_type - } - /// Should the fields be private? pub fn private_fields(&self) -> Option<bool> { self.private_fields @@ -180,7 +190,6 @@ impl Annotations { "nocopy" => self.disallow_copy = true, "nodebug" => self.disallow_debug = true, "nodefault" => self.disallow_default = true, - "mustusetype" => self.must_use_type = true, "replaces" => { self.use_instead_of = Some( attr.value.split("::").map(Into::into).collect(), diff --git a/src/ir/comment.rs b/src/ir/comment.rs index c96e3eb..4ebe19a 100644 --- a/src/ir/comment.rs +++ b/src/ir/comment.rs @@ -1,5 +1,7 @@ //! Utilities for manipulating C/C++ comments. +use std::iter; + /// The type of a comment. #[derive(Debug, PartialEq, Eq)] enum Kind { @@ -13,7 +15,7 @@ enum Kind { /// Preprocesses a C/C++ comment so that it is a valid Rust comment. pub fn preprocess(comment: &str, indent: usize) -> String { - match self::kind(comment) { + match self::kind(&comment) { Some(Kind::SingleLines) => preprocess_single_lines(comment, indent), Some(Kind::MultiLine) => preprocess_multi_line(comment, indent), None => comment.to_owned(), @@ -33,7 +35,7 @@ fn kind(comment: &str) -> Option<Kind> { fn make_indent(indent: usize) -> String { const RUST_INDENTATION: usize = 4; - " ".repeat(indent * RUST_INDENTATION) + iter::repeat(' ').take(indent * RUST_INDENTATION).collect() } /// Preprocesses multiple single line comments. diff --git a/src/ir/comp.rs b/src/ir/comp.rs index a221e52..52dcddd 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -111,10 +111,11 @@ impl Method { /// Is this a virtual method? pub fn is_virtual(&self) -> bool { - matches!( - self.kind, - MethodKind::Virtual { .. } | MethodKind::VirtualDestructor { .. } - ) + match self.kind { + MethodKind::Virtual { .. } | + MethodKind::VirtualDestructor { .. } => true, + _ => false, + } } /// Is this a static method? @@ -629,7 +630,7 @@ where bitfield_unit_count, unit_size_in_bits, unit_align, - mem::take(&mut bitfields_in_unit), + mem::replace(&mut bitfields_in_unit, vec![]), packed, ); @@ -638,12 +639,15 @@ where offset = 0; unit_align = 0; } - } else if offset != 0 && - (bitfield_width == 0 || - (offset & (bitfield_align * 8 - 1)) + bitfield_width > - bitfield_size * 8) - { - offset = align_to(offset, bitfield_align * 8); + } else { + if offset != 0 && + (bitfield_width == 0 || + (offset & (bitfield_align * 8 - 1)) + + bitfield_width > + bitfield_size * 8) + { + offset = align_to(offset, bitfield_align * 8); + } } } @@ -702,24 +706,24 @@ where /// after. #[derive(Debug)] enum CompFields { - Before(Vec<RawField>), - After { + BeforeComputingBitfieldUnits(Vec<RawField>), + AfterComputingBitfieldUnits { fields: Vec<Field>, has_bitfield_units: bool, }, - Error, + ErrorComputingBitfieldUnits, } impl Default for CompFields { fn default() -> CompFields { - CompFields::Before(vec![]) + CompFields::BeforeComputingBitfieldUnits(vec![]) } } impl CompFields { fn append_raw_field(&mut self, raw: RawField) { match *self { - CompFields::Before(ref mut raws) => { + CompFields::BeforeComputingBitfieldUnits(ref mut raws) => { raws.push(raw); } _ => { @@ -732,7 +736,9 @@ impl CompFields { fn compute_bitfield_units(&mut self, ctx: &BindgenContext, packed: bool) { let raws = match *self { - CompFields::Before(ref mut raws) => mem::take(raws), + CompFields::BeforeComputingBitfieldUnits(ref mut raws) => { + mem::replace(raws, vec![]) + } _ => { panic!("Already computed bitfield units"); } @@ -742,23 +748,25 @@ impl CompFields { match result { Ok((fields, has_bitfield_units)) => { - *self = CompFields::After { + *self = CompFields::AfterComputingBitfieldUnits { fields, has_bitfield_units, }; } Err(()) => { - *self = CompFields::Error; + *self = CompFields::ErrorComputingBitfieldUnits; } } } fn deanonymize_fields(&mut self, ctx: &BindgenContext, methods: &[Method]) { let fields = match *self { - CompFields::After { ref mut fields, .. } => fields, + CompFields::AfterComputingBitfieldUnits { + ref mut fields, .. + } => fields, // Nothing to do here. - CompFields::Error => return, - CompFields::Before(_) => { + CompFields::ErrorComputingBitfieldUnits => return, + CompFields::BeforeComputingBitfieldUnits(_) => { panic!("Not yet computed bitfield units."); } }; @@ -770,7 +778,7 @@ impl CompFields { ) -> bool { methods.iter().any(|method| { let method_name = ctx.resolve_func(method.signature()).name(); - method_name == name || ctx.rust_mangle(method_name) == name + method_name == name || ctx.rust_mangle(&method_name) == name }) } @@ -812,7 +820,7 @@ impl CompFields { for field in fields.iter_mut() { match *field { Field::DataMember(FieldData { ref mut name, .. }) => { - if name.is_some() { + if let Some(_) = *name { continue; } @@ -850,13 +858,13 @@ impl Trace for CompFields { T: Tracer, { match *self { - CompFields::Error => {} - CompFields::Before(ref fields) => { + CompFields::ErrorComputingBitfieldUnits => {} + CompFields::BeforeComputingBitfieldUnits(ref fields) => { for f in fields { tracer.visit_kind(f.ty().into(), EdgeKind::Field); } } - CompFields::After { ref fields, .. } => { + CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { for f in fields { f.trace(context, tracer, &()); } @@ -892,7 +900,7 @@ pub struct FieldData { impl FieldMethods for FieldData { fn name(&self) -> Option<&str> { - self.name.as_deref() + self.name.as_ref().map(|n| &**n) } fn ty(&self) -> TypeId { @@ -900,7 +908,7 @@ impl FieldMethods for FieldData { } fn comment(&self) -> Option<&str> { - self.comment.as_deref() + self.comment.as_ref().map(|c| &**c) } fn bitfield_width(&self) -> Option<u32> { @@ -1105,72 +1113,46 @@ impl CompInfo { } // empty union case - if !self.has_fields() { + if self.fields().is_empty() { return None; } let mut max_size = 0; // Don't allow align(0) let mut max_align = 1; - self.each_known_field_layout(ctx, |layout| { - max_size = cmp::max(max_size, layout.size); - max_align = cmp::max(max_align, layout.align); - }); - - Some(Layout::new(max_size, max_align)) - } + for field in self.fields() { + let field_layout = field.layout(ctx); - /// Get this type's set of fields. - pub fn fields(&self) -> &[Field] { - match self.fields { - CompFields::Error => &[], - CompFields::After { ref fields, .. } => fields, - CompFields::Before(..) => { - panic!("Should always have computed bitfield units first"); + if let Some(layout) = field_layout { + max_size = cmp::max(max_size, layout.size); + max_align = cmp::max(max_align, layout.align); } } - } - fn has_fields(&self) -> bool { - match self.fields { - CompFields::Error => false, - CompFields::After { ref fields, .. } => !fields.is_empty(), - CompFields::Before(ref raw_fields) => !raw_fields.is_empty(), - } + Some(Layout::new(max_size, max_align)) } - fn each_known_field_layout( - &self, - ctx: &BindgenContext, - mut callback: impl FnMut(Layout), - ) { + /// Get this type's set of fields. + pub fn fields(&self) -> &[Field] { match self.fields { - CompFields::Error => {} - CompFields::After { ref fields, .. } => { - for field in fields.iter() { - if let Some(layout) = field.layout(ctx) { - callback(layout); - } - } + CompFields::ErrorComputingBitfieldUnits => &[], + CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { + fields } - CompFields::Before(ref raw_fields) => { - for field in raw_fields.iter() { - let field_ty = ctx.resolve_type(field.0.ty); - if let Some(layout) = field_ty.layout(ctx) { - callback(layout); - } - } + CompFields::BeforeComputingBitfieldUnits(_) => { + panic!("Should always have computed bitfield units first"); } } } fn has_bitfields(&self) -> bool { match self.fields { - CompFields::Error => false, - CompFields::After { - has_bitfield_units, .. + CompFields::ErrorComputingBitfieldUnits => false, + CompFields::AfterComputingBitfieldUnits { + has_bitfield_units, + .. } => has_bitfield_units, - CompFields::Before(_) => { + CompFields::BeforeComputingBitfieldUnits(_) => { panic!("Should always have computed bitfield units first"); } } @@ -1267,7 +1249,6 @@ impl CompInfo { let mut ci = CompInfo::new(kind); ci.is_forward_declaration = location.map_or(true, |cur| match cur.kind() { - CXCursor_ParmDecl => true, CXCursor_StructDecl | CXCursor_UnionDecl | CXCursor_ClassDecl => !cur.is_definition(), _ => false, @@ -1393,26 +1374,21 @@ impl CompInfo { let inner = Item::parse(cur, Some(potential_id), ctx) .expect("Inner ClassDecl"); - // If we avoided recursion parsing this type (in - // `Item::from_ty_with_id()`), then this might not be a - // valid type ID, so check and gracefully handle this. - if ctx.resolve_item_fallible(inner).is_some() { - let inner = inner.expect_type_id(ctx); + let inner = inner.expect_type_id(ctx); - ci.inner_types.push(inner); + ci.inner_types.push(inner); - // A declaration of an union or a struct without name - // could also be an unnamed field, unfortunately. - if cur.spelling().is_empty() && - cur.kind() != CXCursor_EnumDecl - { - let ty = cur.cur_type(); - let public = cur.public_accessible(); - let offset = cur.offset_of_field().ok(); + // A declaration of an union or a struct without name could + // also be an unnamed field, unfortunately. + if cur.spelling().is_empty() && + cur.kind() != CXCursor_EnumDecl + { + let ty = cur.cur_type(); + let public = cur.public_accessible(); + let offset = cur.offset_of_field().ok(); - maybe_anonymous_struct_field = - Some((inner, ty, public, offset)); - } + maybe_anonymous_struct_field = + Some((inner, ty, public, offset)); } } CXCursor_PackedAttr => { @@ -1621,17 +1597,23 @@ impl CompInfo { // Even though `libclang` doesn't expose `#pragma packed(...)`, we can // detect it through its effects. if let Some(parent_layout) = layout { - let mut packed = false; - self.each_known_field_layout(ctx, |layout| { - packed = packed || layout.align > parent_layout.align; - }); - if packed { + if self.fields().iter().any(|f| match *f { + Field::Bitfields(ref unit) => { + unit.layout().align > parent_layout.align + } + Field::DataMember(ref data) => { + let field_ty = ctx.resolve_type(data.ty()); + field_ty.layout(ctx).map_or(false, |field_ty_layout| { + field_ty_layout.align > parent_layout.align + }) + } + }) { info!("Found a struct that was defined within `#pragma packed(...)`"); return true; - } - - if self.has_own_virtual_method && parent_layout.align == 1 { - return true; + } else if self.has_own_virtual_method { + if parent_layout.align == 1 { + return true; + } } } @@ -1644,13 +1626,10 @@ impl CompInfo { } /// Compute this compound structure's bitfield allocation units. - pub fn compute_bitfield_units( - &mut self, - ctx: &BindgenContext, - layout: Option<&Layout>, - ) { - let packed = self.is_packed(ctx, layout); - self.fields.compute_bitfield_units(ctx, packed) + pub fn compute_bitfield_units(&mut self, ctx: &BindgenContext) { + // TODO(emilio): If we could detect #pragma packed here we'd fix layout + // tests in divide-by-zero-in-struct-layout.rs + self.fields.compute_bitfield_units(ctx, self.packed_attr) } /// Assign for each anonymous field a generated name. @@ -1761,7 +1740,7 @@ impl IsOpaque for CompInfo { // is a type parameter), then we can't compute bitfield units. We are // left with no choice but to make the whole struct opaque, or else we // might generate structs with incorrect sizes and alignments. - if let CompFields::Error = self.fields { + if let CompFields::ErrorComputingBitfieldUnits = self.fields { return true; } diff --git a/src/ir/context.rs b/src/ir/context.rs index a9e19fb..ccb05e7 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -29,7 +29,7 @@ use clang_sys; use proc_macro2::{Ident, Span}; use std::borrow::Cow; use std::cell::{Cell, RefCell}; -use std::collections::{BTreeSet, HashMap as StdHashMap}; +use std::collections::HashMap as StdHashMap; use std::iter::IntoIterator; use std::mem; @@ -299,7 +299,7 @@ where /// types. #[derive(Eq, PartialEq, Hash, Debug)] enum TypeKey { - Usr(String), + USR(String), Declaration(Cursor), } @@ -354,9 +354,6 @@ pub struct BindgenContext { /// This needs to be an std::HashMap because the cexpr API requires it. parsed_macros: StdHashMap<Vec<u8>, cexpr::expr::EvalResult>, - /// A set of all the included filenames. - deps: BTreeSet<String>, - /// The active replacements collected from replaces="xxx" annotations. replacements: HashMap<Vec<String>, ItemId>, @@ -548,16 +545,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" let root_module = Self::build_root_module(ItemId(0)); let root_module_id = root_module.id().as_module_id_unchecked(); - // depfiles need to include the explicitly listed headers too - let mut deps = BTreeSet::default(); - if let Some(filename) = &options.input_header { - deps.insert(filename.clone()); - } - deps.extend(options.extra_input_headers.iter().cloned()); - BindgenContext { items: vec![Some(root_module)], - deps, types: Default::default(), type_params: Default::default(), modules: Default::default(), @@ -640,20 +629,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" /// Get the user-provided callbacks by reference, if any. pub fn parse_callbacks(&self) -> Option<&dyn ParseCallbacks> { - self.options().parse_callbacks.as_deref() - } - - /// Add another path to the set of included files. - pub fn include_file(&mut self, filename: String) { - if let Some(cbs) = self.parse_callbacks() { - cbs.include_file(&filename); - } - self.deps.insert(filename); - } - - /// Get any included files. - pub fn deps(&self) -> &BTreeSet<String> { - &self.deps + self.options().parse_callbacks.as_ref().map(|t| &**t) } /// Define a new item. @@ -702,10 +678,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" // Unnamed items can have an USR, but they can't be referenced from // other sites explicitly and the USR can match if the unnamed items are // nested, so don't bother tracking them. - if !is_type || is_template_instantiation { - return; - } - if let Some(mut declaration) = declaration { + if is_type && !is_template_instantiation && declaration.is_some() { + let mut declaration = declaration.unwrap(); if !declaration.is_valid() { if let Some(location) = location { if location.is_template_like() { @@ -734,7 +708,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let key = if is_unnamed { TypeKey::Declaration(declaration) } else if let Some(usr) = declaration.usr() { - TypeKey::Usr(usr) + TypeKey::USR(usr) } else { warn!( "Valid declaration with no USR: {:?}, {:?}", @@ -831,32 +805,31 @@ If you encounter an error missing from this list, please file an issue or a PR!" // TODO: Move all this syntax crap to other part of the code. /// Mangles a name so it doesn't conflict with any keyword. - #[rustfmt::skip] pub fn rust_mangle<'a>(&self, name: &'a str) -> Cow<'a, str> { - if name.contains('@') || - name.contains('?') || - name.contains('$') || - matches!( - name, + if name.contains("@") || + name.contains("?") || + name.contains("$") || + match name { "abstract" | "alignof" | "as" | "async" | "become" | - "box" | "break" | "const" | "continue" | "crate" | "do" | - "dyn" | "else" | "enum" | "extern" | "false" | "final" | - "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | - "macro" | "match" | "mod" | "move" | "mut" | "offsetof" | - "override" | "priv" | "proc" | "pub" | "pure" | "ref" | - "return" | "Self" | "self" | "sizeof" | "static" | - "struct" | "super" | "trait" | "true" | "try" | "type" | "typeof" | - "unsafe" | "unsized" | "use" | "virtual" | "where" | - "while" | "yield" | "str" | "bool" | "f32" | "f64" | - "usize" | "isize" | "u128" | "i128" | "u64" | "i64" | - "u32" | "i32" | "u16" | "i16" | "u8" | "i8" | "_" - ) + "box" | "break" | "const" | "continue" | "crate" | "do" | + "dyn" | "else" | "enum" | "extern" | "false" | "final" | + "fn" | "for" | "if" | "impl" | "in" | "let" | "loop" | + "macro" | "match" | "mod" | "move" | "mut" | "offsetof" | + "override" | "priv" | "proc" | "pub" | "pure" | "ref" | + "return" | "Self" | "self" | "sizeof" | "static" | + "struct" | "super" | "trait" | "true" | "type" | "typeof" | + "unsafe" | "unsized" | "use" | "virtual" | "where" | + "while" | "yield" | "str" | "bool" | "f32" | "f64" | + "usize" | "isize" | "u128" | "i128" | "u64" | "i64" | + "u32" | "i32" | "u16" | "i16" | "u8" | "i8" | "_" => true, + _ => false, + } { let mut s = name.to_owned(); s = s.replace("@", "_"); s = s.replace("?", "_"); s = s.replace("$", "_"); - s.push('_'); + s.push_str("_"); return Cow::Owned(s); } Cow::Borrowed(name) @@ -906,10 +879,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" None => continue, }; - if let TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) = - *ty.kind() - { - typerefs.push((id, *ty, loc, parent_id)); + match *ty.kind() { + TypeKind::UnresolvedTypeRef(ref ty, loc, parent_id) => { + typerefs.push((id, ty.clone(), loc, parent_id)); + } + _ => {} }; } typerefs @@ -980,14 +954,15 @@ If you encounter an error missing from this list, please file an issue or a PR!" assert!(self.collected_typerefs()); let need_bitfield_allocation = - mem::take(&mut self.need_bitfield_allocation); + mem::replace(&mut self.need_bitfield_allocation, vec![]); for id in need_bitfield_allocation { self.with_loaned_item(id, |ctx, item| { - let ty = item.kind_mut().as_type_mut().unwrap(); - let layout = ty.layout(ctx); - ty.as_comp_mut() + item.kind_mut() + .as_type_mut() .unwrap() - .compute_bitfield_units(ctx, layout.as_ref()); + .as_comp_mut() + .unwrap() + .compute_bitfield_units(ctx); }); } } @@ -1123,8 +1098,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .ancestors(immut_self) .find(|id| immut_self.resolve_item(*id).is_module()) }; - let new_module = - new_module.unwrap_or_else(|| self.root_module.into()); + let new_module = new_module.unwrap_or(self.root_module.into()); if new_module == old_module { // Already in the correct module. @@ -1332,12 +1306,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" // any sense of template parameter usage, and you're on your own. let mut used_params = HashMap::default(); for &id in self.allowlisted_items() { - used_params.entry(id).or_insert_with(|| { + used_params.entry(id).or_insert( id.self_template_params(self) .into_iter() .map(|p| p.into()) - .collect() - }); + .collect(), + ); } self.used_template_parameters = Some(used_params); } @@ -1423,7 +1397,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" fn build_root_module(id: ItemId) -> Item { let module = Module::new(Some("root".into()), ModuleKind::Normal); - Item::new(id, None, None, id, ItemKind::Module(module), None) + Item::new(id, None, None, id, ItemKind::Module(module)) } /// Get the root module. @@ -1733,7 +1707,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Type(sub_ty), - Some(child.location()), ); // Bypass all the validations in add_item explicitly. @@ -1798,7 +1771,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Type(ty), - Some(location.location()), ); // Bypass all the validations in add_item explicitly. @@ -1820,7 +1792,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" .or_else(|| { decl.cursor() .usr() - .and_then(|usr| self.types.get(&TypeKey::Usr(usr))) + .and_then(|usr| self.types.get(&TypeKey::USR(usr))) }) .cloned() } @@ -1836,8 +1808,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" ) -> Option<TypeId> { use clang_sys::{CXCursor_TypeAliasTemplateDecl, CXCursor_TypeRef}; debug!( - "builtin_or_resolved_ty: {:?}, {:?}, {:?}, {:?}", - ty, location, with_id, parent_id + "builtin_or_resolved_ty: {:?}, {:?}, {:?}", + ty, location, parent_id ); if let Some(decl) = ty.canonical_declaration(location.as_ref()) { @@ -1853,32 +1825,32 @@ If you encounter an error missing from this list, please file an issue or a PR!" // of it, or // * we have already parsed and resolved this type, and // there's nothing left to do. - if let Some(location) = location { - if decl.cursor().is_template_like() && - *ty != decl.cursor().cur_type() - { - // For specialized type aliases, there's no way to get the - // template parameters as of this writing (for a struct - // specialization we wouldn't be in this branch anyway). - // - // Explicitly return `None` if there aren't any - // unspecialized parameters (contains any `TypeRef`) so we - // resolve the canonical type if there is one and it's - // exposed. - // - // This is _tricky_, I know :( - if decl.cursor().kind() == - CXCursor_TypeAliasTemplateDecl && - !location.contains_cursor(CXCursor_TypeRef) && - ty.canonical_type().is_valid_and_exposed() - { - return None; - } + if decl.cursor().is_template_like() && + *ty != decl.cursor().cur_type() && + location.is_some() + { + let location = location.unwrap(); - return self - .instantiate_template(with_id, id, ty, location) - .or(Some(id)); + // For specialized type aliases, there's no way to get the + // template parameters as of this writing (for a struct + // specialization we wouldn't be in this branch anyway). + // + // Explicitly return `None` if there aren't any + // unspecialized parameters (contains any `TypeRef`) so we + // resolve the canonical type if there is one and it's + // exposed. + // + // This is _tricky_, I know :( + if decl.cursor().kind() == CXCursor_TypeAliasTemplateDecl && + !location.contains_cursor(CXCursor_TypeRef) && + ty.canonical_type().is_valid_and_exposed() + { + return None; } + + return self + .instantiate_template(with_id, id, ty, location) + .or_else(|| Some(id)); } return Some(self.build_ty_wrapper(with_id, id, parent_id, ty)); @@ -1932,16 +1904,14 @@ If you encounter an error missing from this list, please file an issue or a PR!" ) -> TypeId { let spelling = ty.spelling(); let layout = ty.fallible_layout(self).ok(); - let location = ty.declaration().location(); let type_kind = TypeKind::ResolvedTypeRef(wrapped_id); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let item = Item::new( with_id, None, None, - parent_id.unwrap_or_else(|| self.current_module.into()), + parent_id.unwrap_or(self.current_module.into()), ItemKind::Type(ty), - Some(location), ); self.add_builtin_item(item); with_id.as_type_id_unchecked() @@ -2002,7 +1972,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" let spelling = ty.spelling(); let is_const = ty.is_const(); let layout = ty.fallible_layout(self).ok(); - let location = ty.declaration().location(); let ty = Type::new(Some(spelling), layout, type_kind, is_const); let id = self.next_item_id(); let item = Item::new( @@ -2011,7 +1980,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.root_module.into(), ItemKind::Type(ty), - Some(location), ); self.add_builtin_item(item); Some(id.as_type_id_unchecked()) @@ -2083,7 +2051,10 @@ If you encounter an error missing from this list, please file an issue or a PR!" id: Id, ) -> bool { let id = id.into(); - matches!(self.replacements.get(path), Some(replaced_by) if *replaced_by != id) + match self.replacements.get(path) { + Some(replaced_by) if *replaced_by != id => true, + _ => false, + } } /// Is the type with the given `name` marked as opaque? @@ -2118,9 +2089,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" module_name = Some(spelling) } + let tokens = cursor.tokens(); + let mut iter = tokens.iter(); let mut kind = ModuleKind::Normal; let mut found_namespace_keyword = false; - for token in cursor.tokens().iter() { + while let Some(token) = iter.next() { match token.spelling() { b"inline" => { assert!(!found_namespace_keyword); @@ -2200,7 +2173,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" None, self.current_module.into(), ItemKind::Module(module), - Some(cursor.location()), ); let module_id = module.id().as_module_id_unchecked(); @@ -2248,6 +2220,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" assert!(self.in_codegen_phase()); assert!(self.current_module == self.root_module); + let cb = match self.options.parse_callbacks { + Some(ref cb) => cb, + None => return CanDerive::No, + }; + *self .blocklisted_types_implement_traits .borrow_mut() @@ -2257,27 +2234,8 @@ If you encounter an error missing from this list, please file an issue or a PR!" .or_insert_with(|| { item.expect_type() .name() - .and_then(|name| match self.options.parse_callbacks { - Some(ref cb) => cb.blocklisted_type_implements_trait( - name, - derive_trait, - ), - // Sized integer types from <stdint.h> get mapped to Rust primitive - // types regardless of whether they are blocklisted, so ensure that - // standard traits are considered derivable for them too. - None => match name { - "int8_t" | "uint8_t" | "int16_t" | "uint16_t" | - "int32_t" | "uint32_t" | "int64_t" | - "uint64_t" | "uintptr_t" | "intptr_t" | - "ptrdiff_t" => Some(CanDerive::Yes), - "size_t" if self.options.size_t_is_usize => { - Some(CanDerive::Yes) - } - "ssize_t" if self.options.size_t_is_usize => { - Some(CanDerive::Yes) - } - _ => Some(CanDerive::No), - }, + .and_then(|name| { + cb.blocklisted_type_implements_trait(name, derive_trait) }) .unwrap_or(CanDerive::No) }) @@ -2418,7 +2376,7 @@ If you encounter an error missing from this list, please file an issue or a PR!" let codegen_items = if self.options().allowlist_recursively { AllowlistedItemsTraversal::new( self, - roots, + roots.clone(), traversal::codegen_edges, ) .collect::<ItemSet>() @@ -2682,12 +2640,6 @@ If you encounter an error missing from this list, please file an issue or a PR!" let name = item.path_for_allowlisting(self)[1..].join("::"); self.options().no_hash_types.matches(&name) } - - /// Check if `--must-use-type` flag is enabled for this item. - pub fn must_use_type_by_name(&self, item: &Item) -> bool { - let name = item.path_for_allowlisting(self)[1..].join("::"); - self.options().must_use_types.matches(&name) - } } /// A builder struct for configuring item resolution options. @@ -2719,7 +2671,7 @@ impl ItemResolver { pub fn new<Id: Into<ItemId>>(id: Id) -> ItemResolver { let id = id.into(); ItemResolver { - id, + id: id, through_type_refs: false, through_type_aliases: false, } @@ -2742,16 +2694,8 @@ impl ItemResolver { assert!(ctx.collected_typerefs()); let mut id = self.id; - let mut seen_ids = HashSet::default(); loop { let item = ctx.resolve_item(id); - - // Detect cycles and bail out. These can happen in certain cases - // involving incomplete qualified dependent types (#2085). - if !seen_ids.insert(id) { - return item; - } - let ty_kind = item.as_type().map(|t| t.kind()); match ty_kind { Some(&TypeKind::ResolvedTypeRef(next_id)) @@ -2786,7 +2730,7 @@ impl PartialType { /// Construct a new `PartialType`. pub fn new(decl: Cursor, id: ItemId) -> PartialType { // assert!(decl == decl.canonical()); - PartialType { decl, id } + PartialType { decl: decl, id: id } } /// The cursor pointing to this partial type's declaration location. diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs index 97455c9..15d4136 100644 --- a/src/ir/enum_ty.rs +++ b/src/ir/enum_ty.rs @@ -86,7 +86,7 @@ impl Enum { } else { Some(type_name) }; - let type_name = type_name.as_deref(); + let type_name = type_name.as_ref().map(String::as_str); let definition = declaration.definition().unwrap_or(declaration); definition.visit(|cursor| { @@ -286,7 +286,7 @@ impl EnumVariant { /// Get this variant's documentation. pub fn comment(&self) -> Option<&str> { - self.comment.as_deref() + self.comment.as_ref().map(|s| &**s) } /// Returns whether this variant should be enforced to be a constant by code diff --git a/src/ir/function.rs b/src/ir/function.rs index a3a2bbf..a6f63a6 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -28,9 +28,7 @@ pub enum FunctionKind { } impl FunctionKind { - /// Given a clang cursor, return the kind of function it represents, or - /// `None` otherwise. - pub fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> { + fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> { // FIXME(emilio): Deduplicate logic with `ir::comp`. Some(match cursor.kind() { clang_sys::CXCursor_FunctionDecl => FunctionKind::Function, @@ -123,7 +121,7 @@ impl Function { /// Get this function's name. pub fn mangled_name(&self) -> Option<&str> { - self.mangled_name.as_deref() + self.mangled_name.as_ref().map(|n| &**n) } /// Get this function's signature type. @@ -187,7 +185,10 @@ pub enum Abi { impl Abi { /// Returns whether this Abi is known or not. fn is_unknown(&self) -> bool { - matches!(*self, Abi::Unknown(..)) + match *self { + Abi::Unknown(..) => true, + _ => false, + } } } @@ -337,7 +338,7 @@ fn args_from_ty_and_cursor( }); let cursor = arg_cur.unwrap_or(*cursor); - let ty = arg_ty.unwrap_or_else(|| cursor.cur_type()); + let ty = arg_ty.unwrap_or(cursor.cur_type()); (name, Item::from_ty_or_ref(ty, cursor, None, ctx)) }) .collect() @@ -357,7 +358,7 @@ impl FunctionSig { argument_types, is_variadic, must_use, - abi, + abi: abi, } } @@ -408,7 +409,7 @@ impl FunctionSig { CXCursor_CXXMethod | CXCursor_ObjCInstanceMethodDecl | CXCursor_ObjCClassMethodDecl => { - args_from_ty_and_cursor(ty, &cursor, ctx) + args_from_ty_and_cursor(&ty, &cursor, ctx) } _ => { // For non-CXCursor_FunctionDecl, visiting the cursor's children @@ -431,7 +432,7 @@ impl FunctionSig { // right AST for functions tagged as stdcall and such... // // https://bugs.llvm.org/show_bug.cgi?id=45919 - args_from_ty_and_cursor(ty, &cursor, ctx) + args_from_ty_and_cursor(&ty, &cursor, ctx) } else { args } @@ -519,7 +520,7 @@ impl FunctionSig { warn!("Unknown calling convention: {:?}", call_conv); } - Ok(Self::new(ret, args, ty.is_variadic(), must_use, abi)) + Ok(Self::new(ret.into(), args, ty.is_variadic(), must_use, abi)) } /// Get this function signature's return type. @@ -564,7 +565,10 @@ impl FunctionSig { return false; } - matches!(self.abi, Abi::C | Abi::Unknown(..)) + match self.abi { + Abi::C | Abi::Unknown(..) => true, + _ => false, + } } } @@ -591,13 +595,10 @@ impl ClangSubItemParser for Function { return Err(ParseError::Continue); } - if cursor.is_inlined_function() { - if !context.options().generate_inline_functions { - return Err(ParseError::Continue); - } - if cursor.is_deleted_function() { - return Err(ParseError::Continue); - } + if !context.options().generate_inline_functions && + cursor.is_inlined_function() + { + return Err(ParseError::Continue); } let linkage = cursor.linkage(); diff --git a/src/ir/item.rs b/src/ir/item.rs index 8692575..4541504 100644 --- a/src/ir/item.rs +++ b/src/ir/item.rs @@ -4,7 +4,7 @@ use super::super::codegen::{EnumVariation, CONSTIFIED_ENUM_MODULE_REPR_NAME}; use super::analysis::{HasVtable, HasVtableResult, Sizedness, SizednessResult}; use super::annotations::Annotations; use super::comment; -use super::comp::{CompKind, MethodKind}; +use super::comp::MethodKind; use super::context::{BindgenContext, ItemId, PartialType, TypeId}; use super::derive::{ CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq, @@ -417,8 +417,6 @@ pub struct Item { parent_id: ItemId, /// The item kind. kind: ItemKind, - /// The source location of the item. - location: Option<clang::SourceLocation>, } impl AsRef<ItemId> for Item { @@ -435,20 +433,18 @@ impl Item { annotations: Option<Annotations>, parent_id: ItemId, kind: ItemKind, - location: Option<clang::SourceLocation>, ) -> Self { debug_assert!(id != parent_id || kind.is_module()); Item { - id, + id: id, local_id: LazyCell::new(), next_child_local_id: Cell::new(1), canonical_name: LazyCell::new(), path_for_allowlisting: LazyCell::new(), - parent_id, - comment, + parent_id: parent_id, + comment: comment, annotations: annotations.unwrap_or_default(), - kind, - location, + kind: kind, } } @@ -458,15 +454,10 @@ impl Item { ty: &clang::Type, ctx: &mut BindgenContext, ) -> TypeId { - let location = ty.declaration().location(); let ty = Opaque::from_clang_ty(ty, ctx); let kind = ItemKind::Type(ty); let parent = ctx.root_module().into(); - ctx.add_item( - Item::new(with_id, None, None, parent, kind, Some(location)), - None, - None, - ); + ctx.add_item(Item::new(with_id, None, None, parent, kind), None, None); with_id.as_type_id_unchecked() } @@ -621,7 +612,10 @@ impl Item { /// Is this item a module? pub fn is_module(&self) -> bool { - matches!(self.kind, ItemKind::Module(..)) + match self.kind { + ItemKind::Module(..) => true, + _ => false, + } } /// Get this item's annotations. @@ -641,24 +635,13 @@ impl Item { return true; } - if !ctx.options().blocklisted_files.is_empty() { - if let Some(location) = &self.location { - let (file, _, _, _) = location.location(); - if let Some(filename) = file.name() { - if ctx.options().blocklisted_files.matches(&filename) { - return true; - } - } - } - } - let path = self.path_for_allowlisting(ctx); let name = path[1..].join("::"); ctx.options().blocklisted_items.matches(&name) || match self.kind { ItemKind::Type(..) => { ctx.options().blocklisted_types.matches(&name) || - ctx.is_replaced_type(path, self.id) + ctx.is_replaced_type(&path, self.id) } ItemKind::Function(..) => { ctx.options().blocklisted_functions.matches(&name) @@ -675,7 +658,10 @@ impl Item { /// Is this item a var type? pub fn is_var(&self) -> bool { - matches!(*self.kind(), ItemKind::Var(..)) + match *self.kind() { + ItemKind::Var(..) => true, + _ => false, + } } /// Take out item NameOptions @@ -736,7 +722,7 @@ impl Item { .through_type_refs() .resolve(ctx) .push_disambiguated_name(ctx, to, level + 1); - to.push('_'); + to.push_str("_"); } to.push_str(&format!("close{}", level)); } @@ -849,7 +835,7 @@ impl Item { if ctx.options().enable_cxx_namespaces { return path.last().unwrap().clone(); } - return path.join("_"); + return path.join("_").to_owned(); } let base_name = target.base_name(ctx); @@ -887,7 +873,7 @@ impl Item { // If target is anonymous we need find its first named ancestor. if target.is_anon() { - for id in ids_iter.by_ref() { + while let Some(id) = ids_iter.next() { ids.push(id); if !ctx.resolve_item(id).is_anon() { @@ -918,12 +904,6 @@ impl Item { names.push(base_name); } - if ctx.options().c_naming { - if let Some(prefix) = self.c_naming_prefix() { - names.insert(0, prefix.to_string()); - } - } - let name = names.join("_"); let name = if opt.user_mangled == UserMangled::Yes { @@ -1074,23 +1054,6 @@ impl Item { path.reverse(); path } - - /// Returns a prefix for the canonical name when C naming is enabled. - fn c_naming_prefix(&self) -> Option<&str> { - let ty = match self.kind { - ItemKind::Type(ref ty) => ty, - _ => return None, - }; - - Some(match ty.kind() { - TypeKind::Comp(ref ci) => match ci.kind() { - CompKind::Struct => "struct", - CompKind::Union => "union", - }, - TypeKind::Enum(..) => "enum", - _ => return None, - }) - } } impl<T> IsOpaque for T @@ -1118,7 +1081,7 @@ impl IsOpaque for Item { ); self.annotations.opaque() || self.as_type().map_or(false, |ty| ty.is_opaque(ctx, self)) || - ctx.opaque_by_name(self.path_for_allowlisting(ctx)) + ctx.opaque_by_name(&self.path_for_allowlisting(ctx)) } } @@ -1128,16 +1091,20 @@ where { fn has_vtable(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); - id.as_type_id(ctx).map_or(false, |id| { - !matches!(ctx.lookup_has_vtable(id), HasVtableResult::No) - }) + id.as_type_id(ctx) + .map_or(false, |id| match ctx.lookup_has_vtable(id) { + HasVtableResult::No => false, + _ => true, + }) } fn has_vtable_ptr(&self, ctx: &BindgenContext) -> bool { let id: ItemId = (*self).into(); - id.as_type_id(ctx).map_or(false, |id| { - matches!(ctx.lookup_has_vtable(id), HasVtableResult::SelfHasVtable) - }) + id.as_type_id(ctx) + .map_or(false, |id| match ctx.lookup_has_vtable(id) { + HasVtableResult::SelfHasVtable => true, + _ => false, + }) } } @@ -1317,7 +1284,7 @@ impl ClangItemParser for Item { let id = ctx.next_item_id(); let module = ctx.root_module().into(); ctx.add_item( - Item::new(id, None, None, module, ItemKind::Type(ty), None), + Item::new(id, None, None, module, ItemKind::Type(ty)), None, None, ); @@ -1355,7 +1322,6 @@ impl ClangItemParser for Item { annotations, relevant_parent_id, ItemKind::$what(item), - Some(cursor.location()), ), declaration, Some(cursor), @@ -1403,7 +1369,7 @@ impl ClangItemParser for Item { } ctx.known_semantic_parent(definition) .or(parent_id) - .unwrap_or_else(|| ctx.current_module().into()) + .unwrap_or(ctx.current_module().into()) } None => relevant_parent_id, }; @@ -1449,7 +1415,9 @@ impl ClangItemParser for Item { ); } Some(filename) => { - ctx.include_file(filename); + if let Some(cb) = ctx.parse_callbacks() { + cb.include_file(&filename) + } } } } @@ -1535,9 +1503,8 @@ impl ClangItemParser for Item { potential_id, None, None, - parent_id.unwrap_or_else(|| current_module.into()), + parent_id.unwrap_or(current_module.into()), ItemKind::Type(Type::new(None, None, kind, is_const)), - Some(location.location()), ), None, None, @@ -1593,21 +1560,9 @@ impl ClangItemParser for Item { } } - // Treat all types that are declared inside functions as opaque. The Rust binding - // won't be able to do anything with them anyway. - // - // (If we don't do this check here, we can have subtle logic bugs because we generally - // ignore function bodies. See issue #2036.) - if let Some(ref parent) = ty.declaration().fallible_semantic_parent() { - if FunctionKind::from_cursor(parent).is_some() { - debug!("Skipping type declared inside function: {:?}", ty); - return Ok(Item::new_opaque_type(id, ty, ctx)); - } - } - let decl = { - let canonical_def = ty.canonical_type().declaration().definition(); - canonical_def.unwrap_or_else(|| ty.declaration()) + let decl = ty.declaration(); + decl.definition().unwrap_or(decl) }; let comment = decl.raw_comment().or_else(|| location.raw_comment()); @@ -1615,7 +1570,7 @@ impl ClangItemParser for Item { Annotations::new(&decl).or_else(|| Annotations::new(&location)); if let Some(ref annotations) = annotations { - if let Some(replaced) = annotations.use_instead_of() { + if let Some(ref replaced) = annotations.use_instead_of() { ctx.replace(replaced, id); } } @@ -1669,7 +1624,6 @@ impl ClangItemParser for Item { annotations, relevant_parent_id, ItemKind::Type(item), - Some(location.location()), ), declaration, Some(location), @@ -1864,7 +1818,11 @@ impl ClangItemParser for Item { clang_sys::CXChildVisit_Continue }); - definition? + if let Some(def) = definition { + def + } else { + return None; + } }; assert!(is_template_with_spelling(&definition, &ty_spelling)); @@ -1898,7 +1856,6 @@ impl ClangItemParser for Item { None, parent, ItemKind::Type(Type::named(name)), - Some(location.location()), ); ctx.add_type_param(item, definition); Some(id.as_type_id_unchecked()) @@ -1949,7 +1906,7 @@ impl ItemCanonicalPath for Item { path.push(CONSTIFIED_ENUM_MODULE_REPR_NAME.into()); } - path + return path; } fn canonical_path(&self, ctx: &BindgenContext) -> Vec<String> { @@ -1982,8 +1939,8 @@ impl<'a> NameOptions<'a> { /// Construct a new `NameOptions` pub fn new(item: &'a Item, ctx: &'a BindgenContext) -> Self { NameOptions { - item, - ctx, + item: item, + ctx: ctx, within_namespaces: false, user_mangled: UserMangled::Yes, } diff --git a/src/ir/layout.rs b/src/ir/layout.rs index 6cf9113..28a6604 100644 --- a/src/ir/layout.rs +++ b/src/ir/layout.rs @@ -64,7 +64,7 @@ impl Layout { next_align *= 2; } Layout { - size, + size: size, align: next_align / 2, packed: false, } diff --git a/src/ir/module.rs b/src/ir/module.rs index d5aca94..13b7c19 100644 --- a/src/ir/module.rs +++ b/src/ir/module.rs @@ -32,15 +32,15 @@ impl Module { /// Construct a new `Module`. pub fn new(name: Option<String>, kind: ModuleKind) -> Self { Module { - name, - kind, + name: name, + kind: kind, children: ItemSet::new(), } } /// Get this module's name. pub fn name(&self) -> Option<&str> { - self.name.as_deref() + self.name.as_ref().map(|n| &**n) } /// Get a mutable reference to this module's children. diff --git a/src/ir/objc.rs b/src/ir/objc.rs index 0845ad0..91855c6 100644 --- a/src/ir/objc.rs +++ b/src/ir/objc.rs @@ -89,10 +89,12 @@ impl ObjCInterface { pub fn rust_name(&self) -> String { if let Some(ref cat) = self.category { format!("{}_{}", self.name(), cat) - } else if self.is_protocol { - format!("P{}", self.name()) } else { - format!("I{}", self.name().to_owned()) + if self.is_protocol { + format!("P{}", self.name()) + } else { + format!("I{}", self.name().to_owned()) + } } } @@ -147,34 +149,28 @@ impl ObjCInterface { // Gather protocols this interface conforms to let needle = format!("P{}", c.spelling()); let items_map = ctx.items(); - debug!( - "Interface {} conforms to {}, find the item", - interface.name, needle - ); + debug!("Interface {} conforms to {}, find the item", interface.name, needle); - for (id, item) in items_map { + for (id, item) in items_map + { if let Some(ty) = item.as_type() { - if let TypeKind::ObjCInterface(ref protocol) = - *ty.kind() - { - if protocol.is_protocol { - debug!( - "Checking protocol {}, ty.name {:?}", - protocol.name, - ty.name() - ); - if Some(needle.as_ref()) == ty.name() { - debug!( - "Found conforming protocol {:?}", - item - ); - interface.conforms_to.push(id); - break; + match *ty.kind() { + TypeKind::ObjCInterface(ref protocol) => { + if protocol.is_protocol + { + debug!("Checking protocol {}, ty.name {:?}", protocol.name, ty.name()); + if Some(needle.as_ref()) == ty.name() { + debug!("Found conforming protocol {:?}", item); + interface.conforms_to.push(id); + break; + } } } + _ => {} } } } + } CXCursor_ObjCInstanceMethodDecl | CXCursor_ObjCClassMethodDecl => { @@ -182,10 +178,8 @@ impl ObjCInterface { let signature = FunctionSig::from_ty(&c.cur_type(), &c, ctx) .expect("Invalid function sig"); - let is_class_method = - c.kind() == CXCursor_ObjCClassMethodDecl; - let method = - ObjCMethod::new(&name, signature, is_class_method); + let is_class_method = c.kind() == CXCursor_ObjCClassMethodDecl; + let method = ObjCMethod::new(&name, signature, is_class_method); interface.add_method(method); } CXCursor_TemplateTypeParameter => { @@ -195,7 +189,7 @@ impl ObjCInterface { CXCursor_ObjCSuperClassRef => { let item = Item::from_ty_or_ref(c.cur_type(), c, None, ctx); interface.parent_class = Some(item.into()); - } + }, _ => {} } CXChildVisit_Continue @@ -224,7 +218,7 @@ impl ObjCMethod { ObjCMethod { name: name.to_owned(), - rust_name, + rust_name: rust_name.to_owned(), signature, is_class_method, } @@ -267,7 +261,7 @@ impl ObjCMethod { .collect(); // No arguments - if args.is_empty() && split_name.len() == 1 { + if args.len() == 0 && split_name.len() == 1 { let name = &split_name[0]; return quote! { #name @@ -275,12 +269,13 @@ impl ObjCMethod { } // Check right amount of arguments - assert!( - args.len() == split_name.len() - 1, - "Incorrect method name or arguments for objc method, {:?} vs {:?}", - args, - split_name - ); + if args.len() != split_name.len() - 1 { + panic!( + "Incorrect method name or arguments for objc method, {:?} vs {:?}", + args, + split_name, + ); + } // Get arguments without type signatures to pass to `msg_send!` let mut args_without_types = vec![]; diff --git a/src/ir/template.rs b/src/ir/template.rs index 8b06748..b519fff 100644 --- a/src/ir/template.rs +++ b/src/ir/template.rs @@ -134,10 +134,10 @@ pub trait TemplateParameters: Sized { where Self: ItemAncestors, { - let mut ancestors: Vec<_> = self.ancestors(ctx).collect(); - ancestors.reverse(); + let ancestors: Vec<_> = self.ancestors(ctx).collect(); ancestors .into_iter() + .rev() .flat_map(|id| id.self_template_params(ctx).into_iter()) .collect() } diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs index 088e744..430dd02 100644 --- a/src/ir/traversal.rs +++ b/src/ir/traversal.rs @@ -24,9 +24,9 @@ impl Edge { } } -impl From<Edge> for ItemId { - fn from(val: Edge) -> Self { - val.to +impl Into<ItemId> for Edge { + fn into(self) -> ItemId { + self.to } } @@ -424,10 +424,10 @@ where } ItemTraversal { - ctx, - seen, - queue, - predicate, + ctx: ctx, + seen: seen, + queue: queue, + predicate: predicate, currently_traversing: None, } } diff --git a/src/ir/ty.rs b/src/ir/ty.rs index d573408..e6eecc3 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -39,6 +39,7 @@ pub struct Type { /// traits, and so if we have a type containing an array with more than this /// many items, we won't be able to derive common traits on that type. /// +/// We need type-level integers yesterday :'( pub const RUST_DERIVE_IN_ARRAY_LIMIT: usize = 32; impl Type { @@ -87,17 +88,23 @@ impl Type { /// Get this type's name. pub fn name(&self) -> Option<&str> { - self.name.as_deref() + self.name.as_ref().map(|name| &**name) } /// Whether this is a block pointer type. pub fn is_block_pointer(&self) -> bool { - matches!(self.kind, TypeKind::BlockPointer(..)) + match self.kind { + TypeKind::BlockPointer(..) => true, + _ => false, + } } /// Is this a compound type? pub fn is_comp(&self) -> bool { - matches!(self.kind, TypeKind::Comp(..)) + match self.kind { + TypeKind::Comp(..) => true, + _ => false, + } } /// Is this a union? @@ -110,43 +117,58 @@ impl Type { /// Is this type of kind `TypeKind::TypeParam`? pub fn is_type_param(&self) -> bool { - matches!(self.kind, TypeKind::TypeParam) + match self.kind { + TypeKind::TypeParam => true, + _ => false, + } } /// Is this a template instantiation type? pub fn is_template_instantiation(&self) -> bool { - matches!(self.kind, TypeKind::TemplateInstantiation(..)) + match self.kind { + TypeKind::TemplateInstantiation(..) => true, + _ => false, + } } /// Is this a template alias type? pub fn is_template_alias(&self) -> bool { - matches!(self.kind, TypeKind::TemplateAlias(..)) + match self.kind { + TypeKind::TemplateAlias(..) => true, + _ => false, + } } /// Is this a function type? pub fn is_function(&self) -> bool { - matches!(self.kind, TypeKind::Function(..)) + match self.kind { + TypeKind::Function(..) => true, + _ => false, + } } /// Is this an enum type? pub fn is_enum(&self) -> bool { - matches!(self.kind, TypeKind::Enum(..)) + match self.kind { + TypeKind::Enum(..) => true, + _ => false, + } } /// Is this either a builtin or named type? pub fn is_builtin_or_type_param(&self) -> bool { - matches!( - self.kind, + match self.kind { TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Function(..) | - TypeKind::Array(..) | - TypeKind::Reference(..) | - TypeKind::Pointer(..) | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::TypeParam - ) + TypeKind::NullPtr | + TypeKind::Function(..) | + TypeKind::Array(..) | + TypeKind::Reference(..) | + TypeKind::Pointer(..) | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::TypeParam => true, + _ => false, + } } /// Creates a new named type, with name `name`. @@ -157,17 +179,26 @@ impl Type { /// Is this a floating point type? pub fn is_float(&self) -> bool { - matches!(self.kind, TypeKind::Float(..)) + match self.kind { + TypeKind::Float(..) => true, + _ => false, + } } /// Is this a boolean type? pub fn is_bool(&self) -> bool { - matches!(self.kind, TypeKind::Int(IntKind::Bool)) + match self.kind { + TypeKind::Int(IntKind::Bool) => true, + _ => false, + } } /// Is this an integer type? pub fn is_integer(&self) -> bool { - matches!(self.kind, TypeKind::Int(..)) + match self.kind { + TypeKind::Int(..) => true, + _ => false, + } } /// Cast this type to an integer kind, or `None` if it is not an integer @@ -186,15 +217,19 @@ impl Type { /// Is this a reference to another type? pub fn is_type_ref(&self) -> bool { - matches!( - self.kind, - TypeKind::ResolvedTypeRef(_) | TypeKind::UnresolvedTypeRef(_, _, _) - ) + match self.kind { + TypeKind::ResolvedTypeRef(_) | + TypeKind::UnresolvedTypeRef(_, _, _) => true, + _ => false, + } } /// Is this an unresolved reference? pub fn is_unresolved_ref(&self) -> bool { - matches!(self.kind, TypeKind::UnresolvedTypeRef(_, _, _)) + match self.kind { + TypeKind::UnresolvedTypeRef(_, _, _) => true, + _ => false, + } } /// Is this a incomplete array type? @@ -244,14 +279,14 @@ impl Type { match self.kind { TypeKind::TypeParam => { let name = self.name().expect("Unnamed named type?"); - !clang::is_valid_identifier(name) + !clang::is_valid_identifier(&name) } _ => false, } } /// Takes `name`, and returns a suitable identifier representation for it. - fn sanitize_name(name: &str) -> Cow<str> { + fn sanitize_name<'a>(name: &'a str) -> Cow<'a, str> { if clang::is_valid_identifier(name) { return Cow::Borrowed(name); } @@ -266,8 +301,12 @@ impl Type { ctx: &BindgenContext, ) -> Option<Cow<'a, str>> { let name_info = match *self.kind() { - TypeKind::Pointer(inner) => Some((inner, Cow::Borrowed("ptr"))), - TypeKind::Reference(inner) => Some((inner, Cow::Borrowed("ref"))), + TypeKind::Pointer(inner) => { + Some((inner.into(), Cow::Borrowed("ptr"))) + } + TypeKind::Reference(inner) => { + Some((inner.into(), Cow::Borrowed("ref"))) + } TypeKind::Array(inner, length) => { Some((inner, format!("array{}", length).into())) } @@ -337,16 +376,16 @@ impl Type { /// There are some types we don't want to stop at when finding an opaque /// item, so we can arrive to the proper item that needs to be generated. pub fn should_be_traced_unconditionally(&self) -> bool { - matches!( - self.kind, + match self.kind { TypeKind::Comp(..) | - TypeKind::Function(..) | - TypeKind::Pointer(..) | - TypeKind::Array(..) | - TypeKind::Reference(..) | - TypeKind::TemplateInstantiation(..) | - TypeKind::ResolvedTypeRef(..) - ) + TypeKind::Function(..) | + TypeKind::Pointer(..) | + TypeKind::Array(..) | + TypeKind::Reference(..) | + TypeKind::TemplateInstantiation(..) | + TypeKind::ResolvedTypeRef(..) => true, + _ => false, + } } } @@ -753,7 +792,7 @@ impl Type { (ty.template_args().is_some() && ty_kind != CXType_Typedef) { // This is a template instantiation. - match TemplateInstantiation::from_ty(ty, ctx) { + match TemplateInstantiation::from_ty(&ty, ctx) { Some(inst) => TypeKind::TemplateInstantiation(inst), None => TypeKind::Opaque, } @@ -1082,16 +1121,7 @@ impl Type { let inner = cursor.typedef_type().expect("Not valid Type?"); let inner = Item::from_ty_or_ref(inner, location, None, ctx); - if inner == potential_id { - warn!( - "Generating oqaque type instead of self-referential \ - typedef"); - // This can happen if we bail out of recursive situations - // within the clang parsing. - TypeKind::Opaque - } else { - TypeKind::Alias(inner) - } + TypeKind::Alias(inner) } CXType_Enum => { let enum_ = Enum::from_ty(ty, ctx).expect("Not an enum?"); diff --git a/src/ir/var.rs b/src/ir/var.rs index cd17937..49c4f30 100644 --- a/src/ir/var.rs +++ b/src/ir/var.rs @@ -88,7 +88,7 @@ impl Var { /// Get this variable's mangled name. pub fn mangled_name(&self) -> Option<&str> { - self.mangled_name.as_deref() + self.mangled_name.as_ref().map(|n| &**n) } } @@ -282,7 +282,7 @@ impl ClangSubItemParser for Var { .parse_callbacks() .and_then(|c| c.int_macro(&name, value)) .unwrap_or_else(|| { - default_macro_constant_type(ctx, value) + default_macro_constant_type(&ctx, value) }); (TypeKind::Int(kind), VarType::Int(value)) @@ -398,8 +398,11 @@ fn parse_macro( let parser = expr::IdentifierParser::new(ctx.parsed_macros()); - if let Ok((_, (id, val))) = parser.macro_definition(&cexpr_tokens) { - return Some((id.into(), val)); + match parser.macro_definition(&cexpr_tokens) { + Ok((_, (id, val))) => { + return Some((id.into(), val)); + } + _ => {} } // Try without the last token, to workaround a libclang bug in versions @@ -51,7 +51,6 @@ macro_rules! doc_mod { mod clang; mod codegen; -mod deps; mod features; mod ir; mod parse; @@ -89,7 +88,7 @@ type HashSet<K> = ::rustc_hash::FxHashSet<K>; pub(crate) use std::collections::hash_map::Entry; /// Default prefix for the anon fields. -pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_"; +pub const DEFAULT_ANON_FIELDS_PREFIX: &'static str = "__bindgen_anon_"; fn file_is_cpp(name_file: &str) -> bool { name_file.ends_with(".hpp") || @@ -308,7 +307,6 @@ impl Builder { (&self.options.blocklisted_types, "--blocklist-type"), (&self.options.blocklisted_functions, "--blocklist-function"), (&self.options.blocklisted_items, "--blocklist-item"), - (&self.options.blocklisted_files, "--blocklist-file"), (&self.options.opaque_types, "--opaque-type"), (&self.options.allowlisted_functions, "--allowlist-function"), (&self.options.allowlisted_types, "--allowlist-type"), @@ -318,7 +316,6 @@ impl Builder { (&self.options.no_debug_types, "--no-debug"), (&self.options.no_default_types, "--no-default"), (&self.options.no_hash_types, "--no-hash"), - (&self.options.must_use_types, "--must-use-type"), ]; for (set, flag) in regex_sets { @@ -560,14 +557,6 @@ impl Builder { output_vector.push("--translate-enum-integer-types".into()); } - if self.options.c_naming { - output_vector.push("--c-naming".into()); - } - - if self.options.force_explicit_padding { - output_vector.push("--explicit-padding".into()); - } - // Add clang arguments output_vector.push("--".into()); @@ -615,19 +604,6 @@ impl Builder { self } - /// Add a depfile output which will be written alongside the generated bindings. - pub fn depfile<H: Into<String>, D: Into<PathBuf>>( - mut self, - output_module: H, - depfile: D, - ) -> Builder { - self.options.depfile = Some(deps::DepfileSpec { - output_module: output_module.into(), - depfile_path: depfile.into(), - }); - self - } - /// Add `contents` as an input C/C++ header named `name`. /// /// The file `name` will be added to the clang arguments. @@ -822,13 +798,6 @@ impl Builder { self } - /// Hide any contents of the given file from the generated bindings, - /// regardless of whether it's a type, function, module etc. - pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder { - self.options.blocklisted_files.insert(arg); - self - } - /// Treat the given type as opaque in the generated bindings. Regular /// expressions are supported. /// @@ -1432,22 +1401,11 @@ impl Builder { self } - /// If true, always emit explicit padding fields. - /// - /// If a struct needs to be serialized in its native format (padding bytes - /// and all), for example writing it to a file or sending it on the network, - /// then this should be enabled, as anything reading the padding bytes of - /// a struct may lead to Undefined Behavior. - pub fn explicit_padding(mut self, doit: bool) -> Self { - self.options.force_explicit_padding = doit; - self - } - /// Generate the Rust bindings using the options built up thus far. pub fn generate(mut self) -> Result<Bindings, ()> { // Add any extra arguments from the environment to the clang command line. if let Some(extra_clang_args) = - get_target_dependent_env_var("BINDGEN_EXTRA_CLANG_ARGS") + env::var("BINDGEN_EXTRA_CLANG_ARGS").ok() { // Try to parse it with shell quoting. If we fail, make it one single big argument. if let Some(strings) = shlex::split(&extra_clang_args) { @@ -1459,13 +1417,11 @@ impl Builder { // Transform input headers to arguments on the clang command line. self.options.input_header = self.input_headers.pop(); - self.options.extra_input_headers = self.input_headers; - self.options.clang_args.extend( - self.options.extra_input_headers.iter().flat_map(|header| { - iter::once("-include".into()) - .chain(iter::once(header.to_string())) - }), - ); + self.options + .clang_args + .extend(self.input_headers.drain(..).flat_map(|header| { + iter::once("-include".into()).chain(iter::once(header)) + })); self.options.input_unsaved_files.extend( self.input_header_contents @@ -1597,13 +1553,6 @@ impl Builder { self } - /// Add `#[must_use]` for the given type. Regular - /// expressions are supported. - pub fn must_use_type<T: Into<String>>(mut self, arg: T) -> Builder { - self.options.must_use_types.insert(arg.into()); - self - } - /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut) pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self { self.options.array_pointers_in_arguments = doit; @@ -1651,15 +1600,6 @@ impl Builder { self.options.translate_enum_integer_types = doit; self } - - /// Generate types with C style naming. - /// - /// This will add prefixes to the generated type names. For example instead of a struct `A` we - /// will generate struct `struct_A`. Currently applies to structs, unions, and enums. - pub fn c_naming(mut self, doit: bool) -> Self { - self.options.c_naming = doit; - self - } } /// Configuration options for generated bindings. @@ -1677,10 +1617,6 @@ struct BindgenOptions { /// blocklisted and should not appear in the generated code. blocklisted_items: RegexSet, - /// The set of files whose contents should be blocklisted and should not - /// appear in the generated code. - blocklisted_files: RegexSet, - /// The set of types that should be treated as opaque structures in the /// generated code. opaque_types: RegexSet, @@ -1688,9 +1624,6 @@ struct BindgenOptions { /// The explicit rustfmt path. rustfmt_path: Option<PathBuf>, - /// The path to which we should write a Makefile-syntax depfile (if any). - depfile: Option<deps::DepfileSpec>, - /// The set of types that we should have bindings for in the generated /// code. /// @@ -1852,9 +1785,6 @@ struct BindgenOptions { /// The input header file. input_header: Option<String>, - /// Any additional input header files. - extra_input_headers: Vec<String>, - /// Unsaved files for input. input_unsaved_files: Vec<clang::UnsavedFile>, @@ -1948,9 +1878,6 @@ struct BindgenOptions { /// The set of types that we should not derive `Hash` for. no_hash_types: RegexSet, - /// The set of types that we should be annotated with `#[must_use]`. - must_use_types: RegexSet, - /// Decide if C arrays should be regular pointers in rust or array pointers array_pointers_in_arguments: bool, @@ -1972,12 +1899,6 @@ struct BindgenOptions { /// Always translate enum integer types to native Rust integer types. translate_enum_integer_types: bool, - - /// Generate types with C style naming. - c_naming: bool, - - /// Always output explicit padding fields - force_explicit_padding: bool, } /// TODO(emilio): This is sort of a lie (see the error message that results from @@ -1994,7 +1915,6 @@ impl BindgenOptions { &mut self.blocklisted_types, &mut self.blocklisted_functions, &mut self.blocklisted_items, - &mut self.blocklisted_files, &mut self.opaque_types, &mut self.bitfield_enums, &mut self.constified_enums, @@ -2010,7 +1930,6 @@ impl BindgenOptions { &mut self.no_debug_types, &mut self.no_default_types, &mut self.no_hash_types, - &mut self.must_use_types, ]; let record_matches = self.record_matches; for regex_set in &mut regex_sets { @@ -2042,10 +1961,8 @@ impl Default for BindgenOptions { blocklisted_types: Default::default(), blocklisted_functions: Default::default(), blocklisted_items: Default::default(), - blocklisted_files: Default::default(), opaque_types: Default::default(), rustfmt_path: Default::default(), - depfile: Default::default(), allowlisted_types: Default::default(), allowlisted_functions: Default::default(), allowlisted_vars: Default::default(), @@ -2091,7 +2008,6 @@ impl Default for BindgenOptions { module_lines: HashMap::default(), clang_args: vec![], input_header: None, - extra_input_headers: vec![], input_unsaved_files: vec![], parse_callbacks: None, codegen_config: CodegenConfig::all(), @@ -2116,15 +2032,12 @@ impl Default for BindgenOptions { no_debug_types: Default::default(), no_default_types: Default::default(), no_hash_types: Default::default(), - must_use_types: Default::default(), array_pointers_in_arguments: false, wasm_import_module_name: None, dynamic_library_name: None, dynamic_link_require_all: false, respect_cxx_access_specs: false, translate_enum_integer_types: false, - c_naming: false, - force_explicit_padding: false, } } } @@ -2162,7 +2075,7 @@ pub struct Bindings { module: proc_macro2::TokenStream, } -pub(crate) const HOST_TARGET: &str = +pub(crate) const HOST_TARGET: &'static str = include_str!(concat!(env!("OUT_DIR"), "/host-target.txt")); // Some architecture triplets are different between rust and libclang, see #1211 @@ -2170,8 +2083,7 @@ pub(crate) const HOST_TARGET: &str = fn rust_to_clang_target(rust_target: &str) -> String { if rust_target.starts_with("aarch64-apple-") { let mut clang_target = "arm64-apple-".to_owned(); - clang_target - .push_str(rust_target.strip_prefix("aarch64-apple-").unwrap()); + clang_target.push_str(&rust_target["aarch64-apple-".len()..]); return clang_target; } rust_target.to_owned() @@ -2293,7 +2205,10 @@ impl Bindings { // Whether we are working with C or C++ inputs. let is_cpp = args_are_cpp(&options.clang_args) || - options.input_header.as_deref().map_or(false, file_is_cpp); + options + .input_header + .as_ref() + .map_or(false, |i| file_is_cpp(&i)); let search_paths = if is_cpp { clang.cpp_search_paths @@ -2381,6 +2296,15 @@ impl Bindings { }) } + /// Convert these bindings into source text (with raw lines prepended). + pub fn to_string(&self) -> String { + let mut bytes = vec![]; + self.write(Box::new(&mut bytes) as Box<dyn Write>) + .expect("writing to a vec cannot fail"); + String::from_utf8(bytes) + .expect("we should only write bindings that are valid utf-8") + } + /// Write these bindings as source text to a file. pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> { let file = OpenOptions::new() @@ -2395,7 +2319,7 @@ impl Bindings { /// Write these bindings as source text to the given `Write`able. pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> { if !self.options.disable_header_comment { - let version = Some("0.59.2"); + let version = Some("0.58.1"); let header = format!( "/* automatically generated by rust-bindgen {} */\n\n", version.unwrap_or("(unknown version)") @@ -2430,7 +2354,7 @@ impl Bindings { } /// Gets the rustfmt path to rustfmt the generated bindings. - fn rustfmt_path(&self) -> io::Result<Cow<PathBuf>> { + fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> { debug_assert!(self.options.rustfmt_bindings); if let Some(ref p) = self.options.rustfmt_path { return Ok(Cow::Borrowed(p)); @@ -2521,18 +2445,6 @@ impl Bindings { } } -impl std::fmt::Display for Bindings { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut bytes = vec![]; - self.write(Box::new(&mut bytes) as Box<dyn Write>) - .expect("writing to a vec cannot fail"); - f.write_str( - std::str::from_utf8(&bytes) - .expect("we should only write bindings that are valid utf-8"), - ) - } -} - /// Determines whether the given cursor is in any of the files matched by the /// options. fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool { @@ -2581,7 +2493,7 @@ fn parse(context: &mut BindgenContext) -> Result<(), ()> { if context.options().emit_ast { fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult { if !cur.is_builtin() { - clang::ast_dump(cur, 0) + clang::ast_dump(&cur, 0) } else { CXChildVisit_Continue } @@ -2618,19 +2530,26 @@ pub fn clang_version() -> ClangVersion { let raw_v: String = clang::extract_clang_version(); let split_v: Option<Vec<&str>> = raw_v .split_whitespace() - .find(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit())) + .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit())) + .next() .map(|v| v.split('.').collect()); - if let Some(v) = split_v { - if v.len() >= 2 { - let maybe_major = v[0].parse::<u32>(); - let maybe_minor = v[1].parse::<u32>(); - if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) { - return ClangVersion { - parsed: Some((major, minor)), - full: raw_v.clone(), - }; + match split_v { + Some(v) => { + if v.len() >= 2 { + let maybe_major = v[0].parse::<u32>(); + let maybe_minor = v[1].parse::<u32>(); + match (maybe_major, maybe_minor) { + (Ok(major), Ok(minor)) => { + return ClangVersion { + parsed: Some((major, minor)), + full: raw_v.clone(), + } + } + _ => {} + } } } + None => {} }; ClangVersion { parsed: None, @@ -2638,25 +2557,10 @@ pub fn clang_version() -> ClangVersion { } } -/// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found. -fn get_target_dependent_env_var(var: &str) -> Option<String> { - if let Ok(target) = env::var("TARGET") { - if let Ok(v) = env::var(&format!("{}_{}", var, target)) { - return Some(v); - } - if let Ok(v) = - env::var(&format!("{}_{}", var, target.replace("-", "_"))) - { - return Some(v); - } - } - env::var(var).ok() -} - /// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed /// line /// -/// When running inside a `build.rs` script, this can be used to make cargo invalidate the +/// When running in side a `build.rs` script, this can be used to make cargo invalidate the /// generated bindings whenever any of the files included from the header change: /// ``` /// use bindgen::builder; diff --git a/src/log_stubs.rs b/src/log_stubs.rs index 8315983..4af496c 100644 --- a/src/log_stubs.rs +++ b/src/log_stubs.rs @@ -1,32 +1,32 @@ #![allow(unused)] macro_rules! log { - (target: $target:expr, $lvl:expr, $($arg:tt)+) => {{ + (target: $target:expr, $lvl:expr, $($arg:tt)+) => { let _ = $target; let _ = log!($lvl, $($arg)+); - }}; + }; ($lvl:expr, $($arg:tt)+) => {{ let _ = $lvl; let _ = format_args!($($arg)+); }}; } macro_rules! error { - (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; - ($($arg:tt)+) => { log!("", $($arg)+) }; + (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; + ($($arg:tt)*) => { log!("", $($arg)*); }; } macro_rules! warn { - (target: $target:expr, $($arg:tt)*) => { log!(target: $target, "", $($arg)*) }; - ($($arg:tt)*) => { log!("", $($arg)*) }; + (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; + ($($arg:tt)*) => { log!("", $($arg)*); }; } macro_rules! info { - (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; - ($($arg:tt)+) => { log!("", $($arg)+) }; + (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; + ($($arg:tt)*) => { log!("", $($arg)*); }; } macro_rules! debug { - (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; - ($($arg:tt)+) => { log!("", $($arg)+) }; + (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; + ($($arg:tt)*) => { log!("", $($arg)*); }; } macro_rules! trace { - (target: $target:expr, $($arg:tt)+) => { log!(target: $target, "", $($arg)+) }; - ($($arg:tt)+) => { log!("", $($arg)+) }; + (target: $target:expr, $($arg:tt)*) => { log!($target, $($arg)*); }; + ($($arg:tt)*) => { log!("", $($arg)*); }; } diff --git a/src/main.rs b/src/main.rs index f3398db..1768ed8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ fn clang_version_check() { ); if expected_version.is_some() { - // assert_eq!(version.parsed, version.parsed); + assert_eq!(version.parsed, version.parsed); } } @@ -45,7 +45,9 @@ pub fn main() { #[cfg(feature = "logging")] env_logger::init(); - match builder_from_flags(env::args()) { + let bind_args: Vec<_> = env::args().collect(); + + match builder_from_flags(bind_args.into_iter()) { Ok((builder, output, verbose)) => { clang_version_check(); let builder_result = panic::catch_unwind(|| { diff --git a/src/options.rs b/src/options.rs index 94f3047..70b7990 100644 --- a/src/options.rs +++ b/src/options.rs @@ -23,17 +23,13 @@ where ); let matches = App::new("bindgen") - .version(Some("0.59.2").unwrap_or("unknown")) + .version(Some("0.58.1").unwrap_or("unknown")) .about("Generates Rust bindings from C/C++ headers.") .usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...") .args(&[ Arg::with_name("header") .help("C or C++ header file") .required(true), - Arg::with_name("depfile") - .long("depfile") - .takes_value(true) - .help("Path to write depfile to"), Arg::with_name("default-enum-style") .long("default-enum-style") .help("The default style of code used to generate enums.") @@ -164,14 +160,6 @@ where .takes_value(true) .multiple(true) .number_of_values(1), - Arg::with_name("blocklist-file") - .alias("blacklist-file") - .long("blocklist-file") - .help("Mark all contents of <path> as hidden.") - .value_name("path") - .takes_value(true) - .multiple(true) - .number_of_values(1), Arg::with_name("no-layout-tests") .long("no-layout-tests") .help("Avoid generating layout tests for any type."), @@ -494,13 +482,6 @@ where .takes_value(true) .multiple(true) .number_of_values(1), - Arg::with_name("must-use-type") - .long("must-use-type") - .help("Add #[must_use] annotation to types matching <regex>.") - .value_name("regex") - .takes_value(true) - .multiple(true) - .number_of_values(1), Arg::with_name("enable-function-attribute-detection") .long("enable-function-attribute-detection") .help( @@ -528,12 +509,6 @@ where Arg::with_name("translate-enum-integer-types") .long("translate-enum-integer-types") .help("Always translate enum integer types to native Rust integer types."), - Arg::with_name("c-naming") - .long("c-naming") - .help("Generate types with C style naming."), - Arg::with_name("explicit-padding") - .long("explicit-padding") - .help("Always output explicit padding fields."), ]) // .args() .get_matches_from(args); @@ -638,12 +613,6 @@ where } } - if let Some(hidden_files) = matches.values_of("blocklist-file") { - for file in hidden_files { - builder = builder.blocklist_file(file); - } - } - if matches.is_present("builtins") { builder = builder.emit_builtins(); } @@ -731,7 +700,7 @@ where if let Some(what_to_generate) = matches.value_of("generate") { let mut config = CodegenConfig::empty(); - for what in what_to_generate.split(',') { + for what in what_to_generate.split(",") { match what { "functions" => config.insert(CodegenConfig::FUNCTIONS), "types" => config.insert(CodegenConfig::TYPES), @@ -879,14 +848,8 @@ where let output = if let Some(path) = matches.value_of("output") { let file = File::create(path)?; - if let Some(depfile) = matches.value_of("depfile") { - builder = builder.depfile(path, depfile); - } Box::new(io::BufWriter::new(file)) as Box<dyn io::Write> } else { - if let Some(depfile) = matches.value_of("depfile") { - builder = builder.depfile("-", depfile); - } Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write> }; @@ -964,12 +927,6 @@ where } } - if let Some(must_use_type) = matches.values_of("must-use-type") { - for regex in must_use_type { - builder = builder.must_use_type(regex); - } - } - if let Some(dynamic_library_name) = matches.value_of("dynamic-loading") { builder = builder.dynamic_library_name(dynamic_library_name); } @@ -986,14 +943,6 @@ where builder = builder.translate_enum_integer_types(true); } - if matches.is_present("c-naming") { - builder = builder.c_naming(true); - } - - if matches.is_present("explicit-padding") { - builder = builder.explicit_padding(true); - } - let verbose = matches.is_present("verbose"); Ok((builder, output, verbose)) |