diff options
author | Joel Galenson <jgalenson@google.com> | 2021-08-09 10:25:17 -0700 |
---|---|---|
committer | Joel Galenson <jgalenson@google.com> | 2021-08-09 10:25:17 -0700 |
commit | 4c81ebb91aaef7c1a3ccfc8776dec3f957724f4a (patch) | |
tree | d2a83d4133ed2768b4266925a20b1d5ab38d5056 | |
parent | 2ed72dfeb742b69cd09e24fb399ac405c202d40f (diff) | |
download | bindgen-4c81ebb91aaef7c1a3ccfc8776dec3f957724f4a.tar.gz |
Upgrade rust/crates/bindgen to 0.59.1
Test: make
Change-Id: I283fdfff59971959dc5ee949379329db19e56b17
-rw-r--r-- | .cargo_vcs_info.json | 2 | ||||
-rw-r--r-- | Android.bp | 19 | ||||
-rw-r--r-- | Cargo.lock | 144 | ||||
-rw-r--r-- | Cargo.toml | 7 | ||||
-rw-r--r-- | Cargo.toml.orig | 7 | ||||
-rw-r--r-- | METADATA | 8 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | build.rs | 8 | ||||
-rw-r--r-- | src/callbacks.rs | 8 | ||||
-rw-r--r-- | src/clang.rs | 23 | ||||
-rw-r--r-- | src/codegen/impl_debug.rs | 4 | ||||
-rw-r--r-- | src/codegen/impl_partialeq.rs | 4 | ||||
-rw-r--r-- | src/codegen/mod.rs | 74 | ||||
-rw-r--r-- | src/codegen/struct_layout.rs | 42 | ||||
-rw-r--r-- | src/deps.rs | 20 | ||||
-rw-r--r-- | src/features.rs | 8 | ||||
-rw-r--r-- | src/ir/analysis/derive.rs | 21 | ||||
-rw-r--r-- | src/ir/comp.rs | 89 | ||||
-rw-r--r-- | src/ir/context.rs | 39 | ||||
-rw-r--r-- | src/ir/function.rs | 15 | ||||
-rw-r--r-- | src/ir/item.rs | 41 | ||||
-rw-r--r-- | src/ir/ty.rs | 1 | ||||
-rw-r--r-- | src/lib.rs | 89 | ||||
-rw-r--r-- | src/options.rs | 26 |
24 files changed, 605 insertions, 100 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json index 2263767..7298dd9 100644 --- a/.cargo_vcs_info.json +++ b/.cargo_vcs_info.json @@ -1,5 +1,5 @@ { "git": { - "sha1": "696455d1c15e682b2b89f81f409315ea4964aef3" + "sha1": "9a9438f3d6a3523c69d7bc890e8608b63dbe38a5" } } @@ -110,28 +110,33 @@ rust_library_host { // ansi_term-0.11.0 // atty-0.2.14 // bitflags-1.2.1 "default" -// cexpr-0.4.0 +// bitvec-0.19.5 "alloc,std" +// cexpr-0.5.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" +// funty-1.1.0 // glob-0.3.0 // lazy_static-1.4.0 // lazycell-1.3.0 -// libc-0.2.93 "default,std" +// libc-0.2.98 "default,std" // libloading-0.7.0 // memchr-2.3.4 "std,use_std" -// nom-5.1.2 "alloc,std" +// nom-6.2.1 "alloc,bitvec,funty,std" // peeking_take_while-0.1.2 -// proc-macro2-1.0.26 +// proc-macro2-1.0.28 // 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" +// radium-0.5.3 +// regex-1.4.6 "std,unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment" +// regex-syntax-0.6.25 "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 +// tap-1.0.1 // textwrap-0.11.0 // unicode-width-0.1.8 "default" -// unicode-xid-0.2.1 "default" +// unicode-xid-0.2.2 "default" // vec_map-0.8.2 // version_check-0.9.3 // which-3.1.1 +// wyz-0.2.0 "alloc" @@ -33,7 +33,7 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.58.1" +version = "0.59.1" dependencies = [ "bitflags", "cexpr", @@ -50,6 +50,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", + "tempfile", "which", ] @@ -60,10 +61,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" [[package]] +name = "bitvec" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8942c8d352ae1838c9dda0b0ca2ab657696ef2232a20147cf1b30ae1a9cb4321" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] name = "cexpr" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27" +checksum = "db507a7679252d2276ed0dd8113c6875ec56d3089f9225b2b42c30cc1f8e5c89" dependencies = [ "nom", ] @@ -126,6 +139,23 @@ dependencies = [ ] [[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + +[[package]] +name = "getrandom" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi", +] + +[[package]] name = "glob" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -191,10 +221,12 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" [[package]] name = "nom" -version = "5.1.2" +version = "6.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" +checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6" dependencies = [ + "bitvec", + "funty", "memchr", "version_check", ] @@ -206,6 +238,12 @@ 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.24" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -224,6 +262,61 @@ dependencies = [ ] [[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + +[[package]] +name = "rand" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" +dependencies = [ + "bitflags", +] + +[[package]] name = "regex" version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -242,6 +335,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" [[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + +[[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -260,6 +362,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + +[[package]] name = "termcolor" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -311,6 +433,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" [[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] name = "which" version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -349,3 +477,9 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" @@ -13,7 +13,7 @@ [package] edition = "2018" name = "bindgen" -version = "0.58.1" +version = "0.59.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"] @@ -38,7 +38,7 @@ required-features = ["clap"] version = "1.0.3" [dependencies.cexpr] -version = "0.4" +version = "0.5" [dependencies.clang-sys] version = "1" @@ -97,6 +97,9 @@ 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 dd30f09..7cf5953 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.58.1" +version = "0.59.1" edition = "2018" build = "build.rs" @@ -43,10 +43,11 @@ required-features = ["clap"] diff = "0.1" clap = "2" shlex = "1" +tempfile = "3" [dependencies] bitflags = "1.0.3" -cexpr = "0.4" +cexpr = "0.5" # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 clap = { version = "2", optional = true } clang-sys = { version = "1", features = ["clang_6_0"] } @@ -58,8 +59,6 @@ regex = { version = "1.0", default-features = false , features = [ "std", "unico 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] @@ -7,13 +7,13 @@ third_party { } url { type: ARCHIVE - value: "https://static.crates.io/crates/bindgen/bindgen-0.58.1.crate" + value: "https://static.crates.io/crates/bindgen/bindgen-0.59.1.crate" } - version: "0.58.1" + version: "0.59.1" license_type: NOTICE last_upgrade_date { year: 2021 - month: 4 - day: 16 + month: 8 + day: 9 } } @@ -39,7 +39,7 @@ extern "C" { ## MSRV -The minimum supported Rust version is **1.40**. +The minimum supported Rust version is **1.44**. No MSRV bump policy has been established yet, so MSRV may increase in any release. @@ -60,6 +60,10 @@ 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]. @@ -79,4 +79,12 @@ 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/src/callbacks.rs b/src/callbacks.rs index e288af4..9b34544 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -95,4 +95,12 @@ 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 6612508..db6467e 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -241,7 +241,7 @@ impl Cursor { self.x.kind } - /// Returns true is the cursor is a definition + /// Returns true if the cursor is a definition pub fn is_definition(&self) -> bool { unsafe { clang_isCursorDefinition(self.x) != 0 } } @@ -469,6 +469,27 @@ 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> { diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs index b8fdd0d..661711e 100644 --- a/src/codegen/impl_debug.rs +++ b/src/codegen/impl_debug.rs @@ -181,7 +181,9 @@ impl<'a> ImplDebug<'a> for Item { format!("{}: Array with length {}", name, len), vec![], )) - } else if len < RUST_DERIVE_IN_ARRAY_LIMIT { + } else if len < RUST_DERIVE_IN_ARRAY_LIMIT || + ctx.options().rust_features().larger_arrays + { // The simple case debug_print(name, quote! { #name_ident }) } else { diff --git a/src/codegen/impl_partialeq.rs b/src/codegen/impl_partialeq.rs index 5f2600e..5a1ba3f 100644 --- a/src/codegen/impl_partialeq.rs +++ b/src/codegen/impl_partialeq.rs @@ -114,7 +114,9 @@ fn gen_field( } TypeKind::Array(_, len) => { - if len <= RUST_DERIVE_IN_ARRAY_LIMIT { + if len <= RUST_DERIVE_IN_ARRAY_LIMIT || + ctx.options().rust_features().larger_arrays + { quote_equals(name_ident) } else { quote! { diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index e62b1a8..0f3337a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -618,12 +618,18 @@ 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 ; }); } @@ -643,6 +649,7 @@ impl CodeGenerator for Var { helpers::ast_ty::uint_expr(val as _) }; result.push(quote! { + #(#attrs)* pub const #canonical_ident : #ty = #val ; }); } @@ -660,12 +667,14 @@ impl CodeGenerator for Var { Ok(string) => { let cstr = helpers::ast_ty::cstr_expr(string); result.push(quote! { + #(#attrs)* 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 ; }); } @@ -674,6 +683,7 @@ impl CodeGenerator for Var { VarType::Float(f) => { match helpers::ast_ty::float_expr(ctx, f) { Ok(expr) => result.push(quote! { + #(#attrs)* pub const #canonical_ident : #ty = #expr ; }), Err(..) => return, @@ -681,13 +691,12 @@ impl CodeGenerator for Var { } 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(self.name()); if !utils::names_will_be_identical_after_mangling( @@ -1493,7 +1502,10 @@ 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. + // 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. let mut generate_ctor = layout.size <= RUST_DERIVE_IN_ARRAY_LIMIT; let mut access_spec = !fields_should_be_private; @@ -1503,7 +1515,9 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit { continue; } - if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT { + if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT && + !ctx.options().rust_features().larger_arrays + { continue; } @@ -1788,6 +1802,14 @@ 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 { @@ -1988,6 +2010,15 @@ 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)) } @@ -2187,9 +2218,32 @@ 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 { unsafe { ::#prefix::mem::zeroed() } } + fn default() -> Self { + #body + } } }); } @@ -4198,6 +4252,16 @@ 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, diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs index 2e4b973..1c6b977 100644 --- a/src/codegen/struct_layout.rs +++ b/src/codegen/struct_layout.rs @@ -217,8 +217,11 @@ 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 = padding_bytes >= field_layout.align || + let need_padding = force_padding || + padding_bytes >= field_layout.align || field_layout.align > MAX_GUARANTEED_ALIGN; debug!( @@ -236,11 +239,14 @@ 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, - cmp::min(field_layout.align, MAX_GUARANTEED_ALIGN), - )) + Some(Layout::new(padding_bytes, padding_align)) } else { None } @@ -262,6 +268,32 @@ 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; + } + + 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, diff --git a/src/deps.rs b/src/deps.rs new file mode 100644 index 0000000..479c396 --- /dev/null +++ b/src/deps.rs @@ -0,0 +1,20 @@ +/// 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 4ec9dee..99b789e 100644 --- a/src/features.rs +++ b/src/features.rs @@ -123,6 +123,9 @@ 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; @@ -134,7 +137,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_40; +pub const LATEST_STABLE_RUST: RustTarget = RustTarget::Stable_1_47; /// Create RustFeatures struct definition, new(), and a getter for each field macro_rules! rust_feature_def { @@ -222,6 +225,9 @@ rust_feature_def!( Stable_1_40 { => non_exhaustive; } + Stable_1_47 { + => larger_arrays; + } Nightly { => thiscall_abi; } diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs index be62666..44e6702 100644 --- a/src/ir/analysis/derive.rs +++ b/src/ir/analysis/derive.rs @@ -255,7 +255,7 @@ impl<'ctx> CannotDerive<'ctx> { return CanDerive::No; } - if self.derive_trait.can_derive_large_array() { + if self.derive_trait.can_derive_large_array(&self.ctx) { trace!(" array can derive {}", self.derive_trait); return CanDerive::Yes; } @@ -377,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() && + if !self.derive_trait.can_derive_large_array(&self.ctx) && info.has_too_large_bitfield_unit() && !item.is_opaque(self.ctx, &()) { @@ -496,10 +496,17 @@ impl DeriveTrait { } } - fn can_derive_large_array(&self) -> bool { - match self { - DeriveTrait::Copy => true, - _ => false, + fn can_derive_large_array(&self, ctx: &BindgenContext) -> bool { + if ctx.options().rust_features().larger_arrays { + match self { + DeriveTrait::Default => false, + _ => true, + } + } else { + match self { + DeriveTrait::Copy => true, + _ => false, + } } } @@ -686,7 +693,7 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> { Some(ty) => { let mut can_derive = self.constrain_type(item, ty); if let CanDerive::Yes = can_derive { - if !self.derive_trait.can_derive_large_array() && + if !self.derive_trait.can_derive_large_array(&self.ctx) && ty.layout(self.ctx).map_or(false, |l| { l.align > RUST_DERIVE_IN_ARRAY_LIMIT }) diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 52dcddd..e554f9a 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1113,21 +1113,17 @@ impl CompInfo { } // empty union case - if self.fields().is_empty() { + if !self.has_fields() { return None; } let mut max_size = 0; // Don't allow align(0) let mut max_align = 1; - for field in self.fields() { - let field_layout = field.layout(ctx); - - if let Some(layout) = field_layout { - max_size = cmp::max(max_size, layout.size); - max_align = cmp::max(max_align, layout.align); - } - } + 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)) } @@ -1139,12 +1135,49 @@ impl CompInfo { CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { fields } - CompFields::BeforeComputingBitfieldUnits(_) => { + CompFields::BeforeComputingBitfieldUnits(..) => { panic!("Should always have computed bitfield units first"); } } } + fn has_fields(&self) -> bool { + match self.fields { + CompFields::ErrorComputingBitfieldUnits => false, + CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { + !fields.is_empty() + } + CompFields::BeforeComputingBitfieldUnits(ref raw_fields) => { + !raw_fields.is_empty() + } + } + } + + fn each_known_field_layout( + &self, + ctx: &BindgenContext, + mut callback: impl FnMut(Layout), + ) { + match self.fields { + CompFields::ErrorComputingBitfieldUnits => return, + CompFields::AfterComputingBitfieldUnits { ref fields, .. } => { + for field in fields.iter() { + if let Some(layout) = field.layout(ctx) { + callback(layout); + } + } + } + CompFields::BeforeComputingBitfieldUnits(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); + } + } + } + } + } + fn has_bitfields(&self) -> bool { match self.fields { CompFields::ErrorComputingBitfieldUnits => false, @@ -1249,6 +1282,7 @@ 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, @@ -1597,23 +1631,17 @@ impl CompInfo { // Even though `libclang` doesn't expose `#pragma packed(...)`, we can // detect it through its effects. if let Some(parent_layout) = layout { - 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 - }) - } - }) { + let mut packed = false; + self.each_known_field_layout(ctx, |layout| { + packed = packed || layout.align > parent_layout.align; + }); + if packed { info!("Found a struct that was defined within `#pragma packed(...)`"); return true; - } else if self.has_own_virtual_method { - if parent_layout.align == 1 { - return true; - } + } + + if self.has_own_virtual_method && parent_layout.align == 1 { + return true; } } @@ -1626,10 +1654,13 @@ impl CompInfo { } /// Compute this compound structure's bitfield allocation units. - 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) + 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) } /// Assign for each anonymous field a generated name. diff --git a/src/ir/context.rs b/src/ir/context.rs index ccb05e7..72ce06b 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::HashMap as StdHashMap; +use std::collections::{BTreeSet, HashMap as StdHashMap}; use std::iter::IntoIterator; use std::mem; @@ -354,6 +354,9 @@ 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>, @@ -545,8 +548,16 @@ 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(), @@ -632,6 +643,19 @@ If you encounter an error missing from this list, please file an issue or a PR!" self.options().parse_callbacks.as_ref().map(|t| &**t) } + /// 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 + } + /// Define a new item. /// /// This inserts it into the internal items set, and its type into the @@ -957,12 +981,11 @@ If you encounter an error missing from this list, please file an issue or a PR!" mem::replace(&mut self.need_bitfield_allocation, vec![]); for id in need_bitfield_allocation { self.with_loaned_item(id, |ctx, item| { - item.kind_mut() - .as_type_mut() - .unwrap() - .as_comp_mut() + let ty = item.kind_mut().as_type_mut().unwrap(); + let layout = ty.layout(ctx); + ty.as_comp_mut() .unwrap() - .compute_bitfield_units(ctx); + .compute_bitfield_units(ctx, layout.as_ref()); }); } } @@ -1808,8 +1831,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, parent_id + "builtin_or_resolved_ty: {:?}, {:?}, {:?}, {:?}", + ty, location, with_id, parent_id ); if let Some(decl) = ty.canonical_declaration(location.as_ref()) { diff --git a/src/ir/function.rs b/src/ir/function.rs index a6f63a6..661ee59 100644 --- a/src/ir/function.rs +++ b/src/ir/function.rs @@ -28,7 +28,9 @@ pub enum FunctionKind { } impl FunctionKind { - fn from_cursor(cursor: &clang::Cursor) -> Option<FunctionKind> { + /// Given a clang cursor, return the kind of function it represents, or + /// `None` otherwise. + pub 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, @@ -595,10 +597,13 @@ impl ClangSubItemParser for Function { return Err(ParseError::Continue); } - if !context.options().generate_inline_functions && - cursor.is_inlined_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); + } } let linkage = cursor.linkage(); diff --git a/src/ir/item.rs b/src/ir/item.rs index 4541504..4e0ba80 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::MethodKind; +use super::comp::{CompKind, MethodKind}; use super::context::{BindgenContext, ItemId, PartialType, TypeId}; use super::derive::{ CanDeriveCopy, CanDeriveDebug, CanDeriveDefault, CanDeriveEq, @@ -904,6 +904,12 @@ 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 { @@ -1054,6 +1060,23 @@ 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 @@ -1415,9 +1438,7 @@ impl ClangItemParser for Item { ); } Some(filename) => { - if let Some(cb) = ctx.parse_callbacks() { - cb.include_file(&filename) - } + ctx.include_file(filename); } } } @@ -1560,6 +1581,18 @@ 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 decl = ty.declaration(); decl.definition().unwrap_or(decl) diff --git a/src/ir/ty.rs b/src/ir/ty.rs index e6eecc3..e049ed6 100644 --- a/src/ir/ty.rs +++ b/src/ir/ty.rs @@ -39,7 +39,6 @@ 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 { @@ -51,6 +51,7 @@ macro_rules! doc_mod { mod clang; mod codegen; +mod deps; mod features; mod ir; mod parse; @@ -557,6 +558,14 @@ 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()); @@ -604,6 +613,19 @@ 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. @@ -1401,11 +1423,22 @@ 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) = - env::var("BINDGEN_EXTRA_CLANG_ARGS").ok() + get_target_dependent_env_var("BINDGEN_EXTRA_CLANG_ARGS") { // 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) { @@ -1417,11 +1450,13 @@ impl Builder { // Transform input headers to arguments on the clang command line. self.options.input_header = self.input_headers.pop(); - self.options - .clang_args - .extend(self.input_headers.drain(..).flat_map(|header| { - iter::once("-include".into()).chain(iter::once(header)) - })); + 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.input_unsaved_files.extend( self.input_header_contents @@ -1600,6 +1635,15 @@ 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. @@ -1624,6 +1668,9 @@ 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. /// @@ -1785,6 +1832,9 @@ 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>, @@ -1899,6 +1949,12 @@ 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 @@ -1963,6 +2019,7 @@ impl Default for BindgenOptions { blocklisted_items: 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(), @@ -2008,6 +2065,7 @@ 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(), @@ -2038,6 +2096,8 @@ impl Default for BindgenOptions { dynamic_link_require_all: false, respect_cxx_access_specs: false, translate_enum_integer_types: false, + c_naming: false, + force_explicit_padding: false, } } } @@ -2319,7 +2379,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.58.1"); + let version = Some("0.59.1"); let header = format!( "/* automatically generated by rust-bindgen {} */\n\n", version.unwrap_or("(unknown version)") @@ -2557,6 +2617,21 @@ 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 /// diff --git a/src/options.rs b/src/options.rs index 70b7990..c02f275 100644 --- a/src/options.rs +++ b/src/options.rs @@ -23,13 +23,17 @@ where ); let matches = App::new("bindgen") - .version(Some("0.58.1").unwrap_or("unknown")) + .version(Some("0.59.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.") @@ -509,6 +513,12 @@ 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); @@ -848,8 +858,14 @@ 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> }; @@ -943,6 +959,14 @@ 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)) |