aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2021-04-19 15:47:23 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-04-19 15:47:23 +0000
commit0336a0dd1f2ad6c5e7edd70d95d1c6c6df213bc7 (patch)
tree194e88a2399cee0d737c1a4b2106ed6d8ca3a602
parent9233a598d437106969ae7fb397c5628f4b5ccedc (diff)
parentc1527f10f53365eb5c66eee3981825faf9f14429 (diff)
downloadbindgen-android12-mainline-art-release.tar.gz
Upgrade rust/crates/bindgen to 0.58.1 am: 64466033e1 am: cddef73ab2 am: 6bb386ebbc am: c1527f10f5android-mainline-12.0.0_r99android-mainline-12.0.0_r98android-mainline-12.0.0_r97android-mainline-12.0.0_r96android-mainline-12.0.0_r95android-mainline-12.0.0_r94android-mainline-12.0.0_r93android-mainline-12.0.0_r92android-mainline-12.0.0_r91android-mainline-12.0.0_r90android-mainline-12.0.0_r9android-mainline-12.0.0_r89android-mainline-12.0.0_r88android-mainline-12.0.0_r87android-mainline-12.0.0_r86android-mainline-12.0.0_r85android-mainline-12.0.0_r84android-mainline-12.0.0_r83android-mainline-12.0.0_r82android-mainline-12.0.0_r81android-mainline-12.0.0_r80android-mainline-12.0.0_r8android-mainline-12.0.0_r79android-mainline-12.0.0_r78android-mainline-12.0.0_r77android-mainline-12.0.0_r76android-mainline-12.0.0_r75android-mainline-12.0.0_r74android-mainline-12.0.0_r73android-mainline-12.0.0_r72android-mainline-12.0.0_r71android-mainline-12.0.0_r70android-mainline-12.0.0_r7android-mainline-12.0.0_r69android-mainline-12.0.0_r68android-mainline-12.0.0_r67android-mainline-12.0.0_r66android-mainline-12.0.0_r65android-mainline-12.0.0_r64android-mainline-12.0.0_r63android-mainline-12.0.0_r62android-mainline-12.0.0_r61android-mainline-12.0.0_r60android-mainline-12.0.0_r6android-mainline-12.0.0_r59android-mainline-12.0.0_r58android-mainline-12.0.0_r57android-mainline-12.0.0_r56android-mainline-12.0.0_r53android-mainline-12.0.0_r52android-mainline-12.0.0_r51android-mainline-12.0.0_r50android-mainline-12.0.0_r5android-mainline-12.0.0_r49android-mainline-12.0.0_r48android-mainline-12.0.0_r47android-mainline-12.0.0_r46android-mainline-12.0.0_r45android-mainline-12.0.0_r44android-mainline-12.0.0_r43android-mainline-12.0.0_r42android-mainline-12.0.0_r41android-mainline-12.0.0_r40android-mainline-12.0.0_r39android-mainline-12.0.0_r38android-mainline-12.0.0_r37android-mainline-12.0.0_r35android-mainline-12.0.0_r34android-mainline-12.0.0_r33android-mainline-12.0.0_r32android-mainline-12.0.0_r31android-mainline-12.0.0_r30android-mainline-12.0.0_r3android-mainline-12.0.0_r29android-mainline-12.0.0_r28android-mainline-12.0.0_r27android-mainline-12.0.0_r26android-mainline-12.0.0_r25android-mainline-12.0.0_r24android-mainline-12.0.0_r23android-mainline-12.0.0_r22android-mainline-12.0.0_r21android-mainline-12.0.0_r20android-mainline-12.0.0_r2android-mainline-12.0.0_r19android-mainline-12.0.0_r18android-mainline-12.0.0_r17android-mainline-12.0.0_r16android-mainline-12.0.0_r15android-mainline-12.0.0_r14android-mainline-12.0.0_r13android-mainline-12.0.0_r126android-mainline-12.0.0_r125android-mainline-12.0.0_r124android-mainline-12.0.0_r123android-mainline-12.0.0_r122android-mainline-12.0.0_r121android-mainline-12.0.0_r120android-mainline-12.0.0_r12android-mainline-12.0.0_r119android-mainline-12.0.0_r118android-mainline-12.0.0_r117android-mainline-12.0.0_r116android-mainline-12.0.0_r115android-mainline-12.0.0_r114android-mainline-12.0.0_r113android-mainline-12.0.0_r110android-mainline-12.0.0_r11android-mainline-12.0.0_r109android-mainline-12.0.0_r108android-mainline-12.0.0_r107android-mainline-12.0.0_r106android-mainline-12.0.0_r105android-mainline-12.0.0_r104android-mainline-12.0.0_r103android-mainline-12.0.0_r102android-mainline-12.0.0_r101android-mainline-12.0.0_r100android-mainline-12.0.0_r10android-mainline-12.0.0_r1aml_wif_311811030aml_tz3_311312010aml_tet_311811050aml_sdk_311710000aml_pco_311011000aml_mpr_311911090aml_doc_310851020android12-mainline-wifi-releaseandroid12-mainline-tethering-releaseandroid12-mainline-statsd-releaseandroid12-mainline-sdkext-releaseandroid12-mainline-resolv-releaseandroid12-mainline-permission-releaseandroid12-mainline-neuralnetworks-releaseandroid12-mainline-networkstack-releaseandroid12-mainline-mediaprovider-releaseandroid12-mainline-media-swcodec-releaseandroid12-mainline-media-releaseandroid12-mainline-ipsec-releaseandroid12-mainline-extservices-releaseandroid12-mainline-documentsui-releaseandroid12-mainline-conscrypt-releaseandroid12-mainline-cellbroadcast-releaseandroid12-mainline-captiveportallogin-releaseandroid12-mainline-art-releaseandroid12-mainline-adbd-release
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/bindgen/+/1678110 Change-Id: I9e8747da5c0813609f2b20ea77f8830bd691d734
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp19
-rw-r--r--Cargo.lock8
-rw-r--r--Cargo.toml6
-rw-r--r--Cargo.toml.orig6
-rw-r--r--METADATA8
-rw-r--r--TEST_MAPPING5
-rw-r--r--src/callbacks.rs19
-rw-r--r--src/codegen/dyngen.rs56
-rw-r--r--src/codegen/impl_debug.rs4
-rw-r--r--src/codegen/mod.rs321
-rw-r--r--src/codegen/struct_layout.rs39
-rw-r--r--src/ir/analysis/derive.rs33
-rw-r--r--src/ir/analysis/has_destructor.rs2
-rw-r--r--src/ir/analysis/has_float.rs2
-rw-r--r--src/ir/analysis/has_type_param_in_array.rs2
-rw-r--r--src/ir/analysis/has_vtable.rs2
-rw-r--r--src/ir/analysis/mod.rs4
-rw-r--r--src/ir/analysis/sizedness.rs2
-rw-r--r--src/ir/analysis/template_params.rs60
-rw-r--r--src/ir/comp.rs21
-rw-r--r--src/ir/context.rs178
-rw-r--r--src/ir/dot.rs6
-rw-r--r--src/ir/enum_ty.rs17
-rw-r--r--src/ir/item.rs44
-rw-r--r--src/ir/template.rs4
-rw-r--r--src/ir/traversal.rs4
-rw-r--r--src/lib.rs270
-rw-r--r--src/options.rs99
29 files changed, 777 insertions, 466 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index d047a4d..2263767 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,5 +1,5 @@
{
"git": {
- "sha1": "5ca2fc7a0221cacde41fd60b0ce485ee5ab8dac3"
+ "sha1": "696455d1c15e682b2b89f81f409315ea4964aef3"
}
}
diff --git a/Android.bp b/Android.bp
index df447b4..305d025 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,4 +1,5 @@
// 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 {
default_applicable_licenses: ["external_rust_crates_bindgen_license"],
@@ -111,26 +112,26 @@ rust_library_host {
// bitflags-1.2.1 "default"
// cexpr-0.4.0
// cfg-if-1.0.0
-// clang-sys-1.0.3 "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"
+// 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.86 "default,std"
-// libloading-0.6.7
+// 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.24
-// quote-1.0.8
-// regex-1.4.3 "std,unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment"
-// regex-syntax-0.6.22 "unicode,unicode-age,unicode-bool,unicode-case,unicode-gencat,unicode-perl,unicode-script,unicode-segment"
+// 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-0.1.1
+// 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.2
+// version_check-0.9.3
// which-3.1.1
diff --git a/Cargo.lock b/Cargo.lock
index 7e09431..7fc4535 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
+version = 3
+
[[package]]
name = "aho-corasick"
version = "0.7.15"
@@ -31,7 +33,7 @@ dependencies = [
[[package]]
name = "bindgen"
-version = "0.57.0"
+version = "0.58.1"
dependencies = [
"bitflags",
"cexpr",
@@ -247,9 +249,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "shlex"
-version = "0.1.1"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
+checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
[[package]]
name = "strsim"
diff --git a/Cargo.toml b/Cargo.toml
index fdb4a1a..7cf9236 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
[package]
edition = "2018"
name = "bindgen"
-version = "0.57.0"
+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"]
@@ -82,7 +82,7 @@ default-features = false
version = "1.0.1"
[dependencies.shlex]
-version = "0.1"
+version = "1"
[dependencies.which]
version = "3.0"
@@ -95,7 +95,7 @@ version = "2"
version = "0.1"
[dev-dependencies.shlex]
-version = "0.1"
+version = "1"
[features]
default = ["logging", "clap", "runtime", "which-rustfmt"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 4f8ac75..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.57.0"
+version = "0.58.1"
edition = "2018"
build = "build.rs"
@@ -42,7 +42,7 @@ required-features = ["clap"]
[dev-dependencies]
diff = "0.1"
clap = "2"
-shlex = "0.1"
+shlex = "1"
[dependencies]
bitflags = "1.0.3"
@@ -56,7 +56,7 @@ peeking_take_while = "0.1.2"
quote = { version = "1", default-features = false }
regex = { version = "1.0", default-features = false , features = [ "std", "unicode"]}
which = { version = "3.0", optional = true, default-features = false }
-shlex = "0.1"
+shlex = "1"
rustc-hash = "1.0.1"
# New validation in 0.3.6 breaks bindgen-integration:
# https://github.com/alexcrichton/proc-macro2/commit/489c642.
diff --git a/METADATA b/METADATA
index 743cf5b..bed57d2 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@ third_party {
}
url {
type: ARCHIVE
- value: "https://static.crates.io/crates/bindgen/bindgen-0.57.0.crate"
+ value: "https://static.crates.io/crates/bindgen/bindgen-0.58.1.crate"
}
- version: "0.57.0"
+ version: "0.58.1"
license_type: NOTICE
last_upgrade_date {
year: 2021
- month: 2
- day: 9
+ month: 4
+ day: 16
}
}
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 7de080a..a731acb 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -2,10 +2,13 @@
{
"presubmit": [
{
+ "name": "keystore2_test"
+ },
+ {
"name": "libsqlite3-sys_device_test_src_lib"
},
{
- "name": "keystore2_test"
+ "name": "vpnprofilestore_test"
}
]
}
diff --git a/src/callbacks.rs b/src/callbacks.rs
index 1cd7f37..e288af4 100644
--- a/src/callbacks.rs
+++ b/src/callbacks.rs
@@ -1,5 +1,7 @@
//! A public API for more fine-grained customization of bindgen behavior.
+pub use crate::ir::analysis::DeriveTrait;
+pub use crate::ir::derive::CanDerive as ImplementsTrait;
pub use crate::ir::enum_ty::{EnumVariantCustomBehavior, EnumVariantValue};
pub use crate::ir::int::IntKind;
use std::fmt;
@@ -76,4 +78,21 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe {
/// This will be called on every file inclusion, with the full path of the included file.
fn include_file(&self, _filename: &str) {}
+
+ /// This will be called to determine whether a particular blocklisted type
+ /// implements a trait or not. This will be used to implement traits on
+ /// other types containing the blocklisted type.
+ ///
+ /// * `None`: use the default behavior
+ /// * `Some(ImplementsTrait::Yes)`: `_name` implements `_derive_trait`
+ /// * `Some(ImplementsTrait::Manually)`: any type including `_name` can't
+ /// derive `_derive_trait` but can implemented it manually
+ /// * `Some(ImplementsTrait::No)`: `_name` doesn't implement `_derive_trait`
+ fn blocklisted_type_implements_trait(
+ &self,
+ _name: &str,
+ _derive_trait: DeriveTrait,
+ ) -> Option<ImplementsTrait> {
+ None
+ }
}
diff --git a/src/codegen/dyngen.rs b/src/codegen/dyngen.rs
index 94dd574..71c4dab 100644
--- a/src/codegen/dyngen.rs
+++ b/src/codegen/dyngen.rs
@@ -77,6 +77,7 @@ impl DynamicItems {
let constructor_inits = &self.constructor_inits;
let init_fields = &self.init_fields;
let struct_implementation = &self.struct_implementation;
+
quote! {
extern crate libloading;
@@ -90,14 +91,20 @@ impl DynamicItems {
path: P
) -> Result<Self, ::libloading::Error>
where P: AsRef<::std::ffi::OsStr> {
- let __library = ::libloading::Library::new(path)?;
+ let library = ::libloading::Library::new(path)?;
+ Self::from_library(library)
+ }
+
+ pub unsafe fn from_library<L>(
+ library: L
+ ) -> Result<Self, ::libloading::Error>
+ where L: Into<::libloading::Library> {
+ let __library = library.into();
#( #constructor_inits )*
- Ok(
- #lib_ident {
- __library,
- #( #init_fields ),*
- }
- )
+ Ok(#lib_ident {
+ __library,
+ #( #init_fields ),*
+ })
}
#( #struct_implementation )*
@@ -110,6 +117,7 @@ impl DynamicItems {
ident: Ident,
abi: Abi,
is_variadic: bool,
+ is_required: bool,
args: Vec<proc_macro2::TokenStream>,
args_identifiers: Vec<proc_macro2::TokenStream>,
ret: proc_macro2::TokenStream,
@@ -119,24 +127,48 @@ impl DynamicItems {
assert_eq!(args.len(), args_identifiers.len());
}
+ let signature = quote! { unsafe extern #abi fn ( #( #args),* ) #ret };
+ let member = if is_required {
+ signature
+ } else {
+ quote! { Result<#signature, ::libloading::Error> }
+ };
+
self.struct_members.push(quote! {
- pub #ident: Result<unsafe extern #abi fn ( #( #args ),* ) #ret, ::libloading::Error>,
+ pub #ident: #member,
});
+ // N.B: If the signature was required, it won't be wrapped in a Result<...>
+ // and we can simply call it directly.
+ let fn_ = if is_required {
+ quote! { self.#ident }
+ } else {
+ quote! { self.#ident.as_ref().expect("Expected function, got error.") }
+ };
+ let call_body = quote! {
+ (#fn_)(#( #args_identifiers ),*)
+ };
+
// We can't implement variadic functions from C easily, so we allow to
// access the function pointer so that the user can call it just fine.
if !is_variadic {
self.struct_implementation.push(quote! {
pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty {
- let sym = self.#ident.as_ref().expect("Expected function, got error.");
- (sym)(#( #args_identifiers ),*)
+ #call_body
}
});
}
+ // N.B: Unwrap the signature upon construction if it is required to be resolved.
let ident_str = codegen::helpers::ast_ty::cstr_expr(ident.to_string());
- self.constructor_inits.push(quote! {
- let #ident = __library.get(#ident_str).map(|sym| *sym);
+ self.constructor_inits.push(if is_required {
+ quote! {
+ let #ident = __library.get(#ident_str).map(|sym| *sym)?;
+ }
+ } else {
+ quote! {
+ let #ident = __library.get(#ident_str).map(|sym| *sym);
+ }
});
self.init_fields.push(quote! {
diff --git a/src/codegen/impl_debug.rs b/src/codegen/impl_debug.rs
index ed1a5e2..b8fdd0d 100644
--- a/src/codegen/impl_debug.rs
+++ b/src/codegen/impl_debug.rs
@@ -120,9 +120,9 @@ impl<'a> ImplDebug<'a> for Item {
) -> Option<(String, Vec<proc_macro2::TokenStream>)> {
let name_ident = ctx.rust_ident(name);
- // We don't know if blacklisted items `impl Debug` or not, so we can't
+ // We don't know if blocklisted items `impl Debug` or not, so we can't
// add them to the format string we're building up.
- if !ctx.whitelisted_items().contains(&self.id()) {
+ if !ctx.allowlisted_items().contains(&self.id()) {
return None;
}
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index cad2f47..e62b1a8 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -422,45 +422,62 @@ trait CodeGenerator {
/// Extra information from the caller.
type Extra;
+ /// Extra information returned to the caller.
+ type Return;
+
fn codegen<'a>(
&self,
ctx: &BindgenContext,
result: &mut CodegenResult<'a>,
extra: &Self::Extra,
- );
+ ) -> Self::Return;
}
-impl CodeGenerator for Item {
- type Extra = ();
-
- fn codegen<'a>(
+impl Item {
+ fn process_before_codegen(
&self,
ctx: &BindgenContext,
- result: &mut CodegenResult<'a>,
- _extra: &(),
- ) {
+ result: &mut CodegenResult,
+ ) -> bool {
if !self.is_enabled_for_codegen(ctx) {
- return;
+ return false;
}
- if self.is_blacklisted(ctx) || result.seen(self.id()) {
+ if self.is_blocklisted(ctx) || result.seen(self.id()) {
debug!(
- "<Item as CodeGenerator>::codegen: Ignoring hidden or seen: \
+ "<Item as CodeGenerator>::process_before_codegen: Ignoring hidden or seen: \
self = {:?}",
self
);
- return;
+ return false;
}
- debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
if !ctx.codegen_items().contains(&self.id()) {
// TODO(emilio, #453): Figure out what to do when this happens
// legitimately, we could track the opaque stuff and disable the
// assertion there I guess.
- warn!("Found non-whitelisted item in code generation: {:?}", self);
+ warn!("Found non-allowlisted item in code generation: {:?}", self);
}
result.set_seen(self.id());
+ true
+ }
+}
+
+impl CodeGenerator for Item {
+ type Extra = ();
+ type Return = ();
+
+ fn codegen<'a>(
+ &self,
+ ctx: &BindgenContext,
+ result: &mut CodegenResult<'a>,
+ _extra: &(),
+ ) {
+ debug!("<Item as CodeGenerator>::codegen: self = {:?}", self);
+ if !self.process_before_codegen(ctx, result) {
+ return;
+ }
match *self.kind() {
ItemKind::Module(ref module) => {
@@ -481,6 +498,7 @@ impl CodeGenerator for Item {
impl CodeGenerator for Module {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -572,6 +590,8 @@ impl CodeGenerator for Module {
impl CodeGenerator for Var {
type Extra = Item;
+ type Return = ();
+
fn codegen<'a>(
&self,
ctx: &BindgenContext,
@@ -698,6 +718,7 @@ impl CodeGenerator for Var {
impl CodeGenerator for Type {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -725,7 +746,7 @@ impl CodeGenerator for Type {
// These items don't need code generation, they only need to be
// 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_whitelisted_and_codegen_items.
+ // it to BindgenContext::compute_allowlisted_and_codegen_items.
return;
}
TypeKind::TemplateInstantiation(ref inst) => {
@@ -1004,6 +1025,7 @@ impl<'a> Vtable<'a> {
impl<'a> CodeGenerator for Vtable<'a> {
type Extra = Item;
+ type Return = ();
fn codegen<'b>(
&self,
@@ -1048,6 +1070,7 @@ impl<'a> TryToRustTy for Vtable<'a> {
impl CodeGenerator for TemplateInstantiation {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -1219,7 +1242,7 @@ impl<'a> FieldCodegen<'a> for FieldData {
ty.append_implicit_template_params(ctx, field_item);
// NB: If supported, we use proper `union` types.
- let ty = if parent.is_union() && !parent.can_be_rust_union(ctx) {
+ let ty = if parent.is_union() && !struct_layout.is_rust_union() {
result.saw_bindgen_union();
if ctx.options().enable_cxx_namespaces {
quote! {
@@ -1263,12 +1286,10 @@ impl<'a> FieldCodegen<'a> for FieldData {
.expect("Each field should have a name in codegen!");
let field_ident = ctx.rust_ident_raw(field_name.as_str());
- if !parent.is_union() {
- if let Some(padding_field) =
- struct_layout.pad_field(&field_name, field_ty, self.offset())
- {
- fields.extend(Some(padding_field));
- }
+ if let Some(padding_field) =
+ struct_layout.saw_field(&field_name, field_ty, self.offset())
+ {
+ fields.extend(Some(padding_field));
}
let is_private = (!self.is_public() &&
@@ -1433,7 +1454,7 @@ impl<'a> FieldCodegen<'a> for BitfieldUnit {
let layout = self.layout();
let unit_field_ty = helpers::bitfield_unit(ctx, layout);
let field_ty = {
- if parent.is_union() && !parent.can_be_rust_union(ctx) {
+ if parent.is_union() && !struct_layout.is_rust_union() {
result.saw_bindgen_union();
if ctx.options().enable_cxx_namespaces {
quote! {
@@ -1571,7 +1592,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
_accessor_kind: FieldAccessorKind,
parent: &CompInfo,
_result: &mut CodegenResult,
- _struct_layout: &mut StructLayoutTracker,
+ struct_layout: &mut StructLayoutTracker,
_fields: &mut F,
methods: &mut M,
(unit_field_name, bitfield_representable_as_int): (&'a str, &mut bool),
@@ -1612,7 +1633,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
self.is_public() && !fields_should_be_private,
);
- if parent.is_union() && !parent.can_be_rust_union(ctx) {
+ if parent.is_union() && !struct_layout.is_rust_union() {
methods.extend(Some(quote! {
#[inline]
#access_spec fn #getter_name(&self) -> #bitfield_ty {
@@ -1666,6 +1687,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
impl CodeGenerator for CompInfo {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -1768,15 +1790,53 @@ impl CodeGenerator for CompInfo {
}
}
- let is_union = self.kind() == CompKind::Union;
- let layout = item.kind().expect_type().layout(ctx);
-
- let mut explicit_align = None;
if is_opaque {
// Opaque item should not have generated methods, fields.
debug_assert!(fields.is_empty());
debug_assert!(methods.is_empty());
+ }
+
+ let is_union = self.kind() == CompKind::Union;
+ let layout = item.kind().expect_type().layout(ctx);
+ let zero_sized = item.is_zero_sized(ctx);
+ let forward_decl = self.is_forward_declaration();
+
+ let mut explicit_align = None;
+ // C++ requires every struct to be addressable, so what C++ compilers do
+ // is making the struct 1-byte sized.
+ //
+ // This is apparently not the case for C, see:
+ // https://github.com/rust-lang/rust-bindgen/issues/551
+ //
+ // Just get the layout, and assume C++ if not.
+ //
+ // NOTE: This check is conveniently here to avoid the dummy fields we
+ // may add for unused template parameters.
+ if !forward_decl && zero_sized {
+ let has_address = if is_opaque {
+ // Generate the address field if it's an opaque type and
+ // couldn't determine the layout of the blob.
+ layout.is_none()
+ } else {
+ layout.map_or(true, |l| l.size != 0)
+ };
+
+ if has_address {
+ let layout = Layout::new(1, 1);
+ let ty = helpers::blob(ctx, Layout::new(1, 1));
+ struct_layout.saw_field_with_layout(
+ "_address",
+ layout,
+ /* offset = */ Some(0),
+ );
+ fields.push(quote! {
+ pub _address: #ty,
+ });
+ }
+ }
+
+ if is_opaque {
match layout {
Some(l) => {
explicit_align = Some(l.align);
@@ -1790,7 +1850,7 @@ impl CodeGenerator for CompInfo {
warn!("Opaque type without layout! Expect dragons!");
}
}
- } else if !is_union && !item.is_zero_sized(ctx) {
+ } else if !is_union && !zero_sized {
if let Some(padding_field) =
layout.and_then(|layout| struct_layout.pad_struct(layout))
{
@@ -1815,57 +1875,26 @@ impl CodeGenerator for CompInfo {
}
}
}
- } else if is_union && !self.is_forward_declaration() {
+ } else if is_union && !forward_decl {
// TODO(emilio): It'd be nice to unify this with the struct path
// above somehow.
let layout = layout.expect("Unable to get layout information?");
- struct_layout.saw_union(layout);
-
if struct_layout.requires_explicit_align(layout) {
explicit_align = Some(layout.align);
}
- let ty = helpers::blob(ctx, layout);
- fields.push(if self.can_be_rust_union(ctx) {
- quote! {
- _bindgen_union_align: #ty ,
- }
- } else {
- quote! {
+ if !struct_layout.is_rust_union() {
+ let ty = helpers::blob(ctx, layout);
+ fields.push(quote! {
pub bindgen_union_field: #ty ,
- }
- });
+ })
+ }
}
- // C++ requires every struct to be addressable, so what C++ compilers do
- // is making the struct 1-byte sized.
- //
- // This is apparently not the case for C, see:
- // https://github.com/rust-lang/rust-bindgen/issues/551
- //
- // Just get the layout, and assume C++ if not.
- //
- // NOTE: This check is conveniently here to avoid the dummy fields we
- // may add for unused template parameters.
- if self.is_forward_declaration() {
+ if forward_decl {
fields.push(quote! {
_unused: [u8; 0],
});
- } else if item.is_zero_sized(ctx) {
- let has_address = if is_opaque {
- // Generate the address field if it's an opaque type and
- // couldn't determine the layout of the blob.
- layout.is_none()
- } else {
- layout.map_or(true, |l| l.size != 0)
- };
-
- if has_address {
- let ty = helpers::blob(ctx, Layout::new(1, 1));
- fields.push(quote! {
- pub _address: #ty,
- });
- }
}
let mut generic_param_names = vec![];
@@ -1963,7 +1992,7 @@ impl CodeGenerator for CompInfo {
attributes.push(attributes::derives(&derives))
}
- let mut tokens = if is_union && self.can_be_rust_union(ctx) {
+ let mut tokens = if is_union && struct_layout.is_rust_union() {
quote! {
#( #attributes )*
pub union #canonical_ident
@@ -2256,13 +2285,15 @@ impl MethodCodegen for Method {
// First of all, output the actual function.
let function_item = ctx.resolve_item(self.signature());
- if function_item.is_blacklisted(ctx) {
- // We shouldn't emit a method declaration if the function is blacklisted
+ if !function_item.process_before_codegen(ctx, result) {
return;
}
- function_item.codegen(ctx, result, &());
-
let function = function_item.expect_function();
+ let times_seen = function.codegen(ctx, result, &function_item);
+ let times_seen = match times_seen {
+ Some(seen) => seen,
+ None => return,
+ };
let signature_item = ctx.resolve_item(function.signature());
let mut name = match self.kind() {
MethodKind::Constructor => "new".into(),
@@ -2297,7 +2328,11 @@ impl MethodCodegen for Method {
name.push_str(&count.to_string());
}
- let function_name = ctx.rust_ident(function_item.canonical_name(ctx));
+ let mut function_name = function_item.canonical_name(ctx);
+ if times_seen > 0 {
+ write!(&mut function_name, "{}", times_seen).unwrap();
+ }
+ let function_name = ctx.rust_ident(function_name);
let mut args = utils::fnsig_arguments(ctx, signature);
let mut ret = utils::fnsig_return_ty(ctx, signature);
@@ -2519,7 +2554,7 @@ impl<'a> EnumBuilder<'a> {
/// the representation, and which variation it should be generated as.
fn new(
name: &'a str,
- attrs: Vec<proc_macro2::TokenStream>,
+ mut attrs: Vec<proc_macro2::TokenStream>,
repr: proc_macro2::TokenStream,
enum_variation: EnumVariation,
enum_codegen_depth: usize,
@@ -2538,6 +2573,8 @@ impl<'a> EnumBuilder<'a> {
},
EnumVariation::Rust { .. } => {
+ // `repr` is guaranteed to be Rustified in Enum::codegen
+ attrs.insert(0, quote! { #[repr( #repr )] });
let tokens = quote!();
EnumBuilder::Rust {
codegen_depth: enum_codegen_depth + 1,
@@ -2801,6 +2838,7 @@ impl<'a> EnumBuilder<'a> {
impl CodeGenerator for Enum {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
@@ -2815,51 +2853,73 @@ impl CodeGenerator for Enum {
let ident = ctx.rust_ident(&name);
let enum_ty = item.expect_type();
let layout = enum_ty.layout(ctx);
+ let variation = self.computed_enum_variation(ctx, item);
- let repr = self.repr().map(|repr| ctx.resolve_type(repr));
- let repr = match repr {
- Some(repr) => match *repr.canonical_type(ctx).kind() {
- TypeKind::Int(int_kind) => int_kind,
- _ => panic!("Unexpected type as enum repr"),
- },
- None => {
- warn!(
- "Guessing type of enum! Forward declarations of enums \
- shouldn't be legal!"
- );
- IntKind::Int
+ let repr_translated;
+ let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) {
+ Some(repr)
+ if !ctx.options().translate_enum_integer_types &&
+ !variation.is_rust() =>
+ {
+ repr
}
- };
+ repr => {
+ // An enum's integer type is translated to a native Rust
+ // integer type in 3 cases:
+ // * the enum is Rustified and we need a translated type for
+ // the repr attribute
+ // * the representation couldn't be determined from the C source
+ // * it was explicitly requested as a bindgen option
+
+ let kind = match repr {
+ Some(repr) => match *repr.canonical_type(ctx).kind() {
+ TypeKind::Int(int_kind) => int_kind,
+ _ => panic!("Unexpected type as enum repr"),
+ },
+ None => {
+ warn!(
+ "Guessing type of enum! Forward declarations of enums \
+ shouldn't be legal!"
+ );
+ IntKind::Int
+ }
+ };
+
+ let signed = kind.is_signed();
+ let size = layout
+ .map(|l| l.size)
+ .or_else(|| kind.known_size())
+ .unwrap_or(0);
+
+ let translated = match (signed, size) {
+ (true, 1) => IntKind::I8,
+ (false, 1) => IntKind::U8,
+ (true, 2) => IntKind::I16,
+ (false, 2) => IntKind::U16,
+ (true, 4) => IntKind::I32,
+ (false, 4) => IntKind::U32,
+ (true, 8) => IntKind::I64,
+ (false, 8) => IntKind::U64,
+ _ => {
+ warn!(
+ "invalid enum decl: signed: {}, size: {}",
+ signed, size
+ );
+ IntKind::I32
+ }
+ };
- let signed = repr.is_signed();
- let size = layout
- .map(|l| l.size)
- .or_else(|| repr.known_size())
- .unwrap_or(0);
-
- let repr_name = match (signed, size) {
- (true, 1) => "i8",
- (false, 1) => "u8",
- (true, 2) => "i16",
- (false, 2) => "u16",
- (true, 4) => "i32",
- (false, 4) => "u32",
- (true, 8) => "i64",
- (false, 8) => "u64",
- _ => {
- warn!("invalid enum decl: signed: {}, size: {}", signed, size);
- "i32"
+ repr_translated =
+ Type::new(None, None, TypeKind::Int(translated), false);
+ &repr_translated
}
};
let mut attrs = vec![];
- let variation = self.computed_enum_variation(ctx, item);
-
// TODO(emilio): Delegate this to the builders?
match variation {
EnumVariation::Rust { non_exhaustive } => {
- attrs.push(attributes::repr(repr_name));
if non_exhaustive &&
ctx.options().rust_features().non_exhaustive
{
@@ -2929,13 +2989,7 @@ impl CodeGenerator for Enum {
});
}
- let repr = match self.repr() {
- Some(ty) => ty.to_rust_ty_or_opaque(ctx, &()),
- None => {
- let repr_name = ctx.rust_ident_raw(repr_name);
- quote! { #repr_name }
- }
- };
+ let repr = repr.to_rust_ty_or_opaque(ctx, item);
let mut builder = EnumBuilder::new(
&name,
@@ -3708,19 +3762,23 @@ impl TryToRustTy for FunctionSig {
impl CodeGenerator for Function {
type Extra = Item;
+ /// If we've actually generated the symbol, the number of times we've seen
+ /// it.
+ type Return = Option<u32>;
+
fn codegen<'a>(
&self,
ctx: &BindgenContext,
result: &mut CodegenResult<'a>,
item: &Item,
- ) {
+ ) -> Self::Return {
debug!("<Function as CodeGenerator>::codegen: item = {:?}", item);
debug_assert!(item.is_enabled_for_codegen(ctx));
// We can't currently do anything with Internal functions so just
// avoid generating anything for them.
match self.linkage() {
- Linkage::Internal => return,
+ Linkage::Internal => return None,
Linkage::External => {}
}
@@ -3730,7 +3788,7 @@ impl CodeGenerator for Function {
FunctionKind::Method(ref method_kind)
if method_kind.is_pure_virtual() =>
{
- return;
+ return None;
}
_ => {}
}
@@ -3740,7 +3798,7 @@ impl CodeGenerator for Function {
// instantiations is open ended and we have no way of knowing which
// monomorphizations actually exist.
if !item.all_template_params(ctx).is_empty() {
- return;
+ return None;
}
let name = self.name();
@@ -3753,7 +3811,7 @@ impl CodeGenerator for Function {
// TODO: Maybe warn here if there's a type/argument mismatch, or
// something?
if result.seen_function(seen_symbol_name) {
- return;
+ return None;
}
result.saw_function(seen_symbol_name);
}
@@ -3780,21 +3838,14 @@ impl CodeGenerator for Function {
attributes.push(attributes::doc(comment));
}
- // Handle overloaded functions by giving each overload its own unique
- // suffix.
- let times_seen = result.overload_number(&canonical_name);
- if times_seen > 0 {
- write!(&mut canonical_name, "{}", times_seen).unwrap();
- }
-
let abi = match signature.abi() {
Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => {
warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target");
- return;
+ return None;
}
Abi::Win64 if signature.is_variadic() => {
warn!("Skipping variadic function with Win64 ABI that isn't supported");
- return;
+ return None;
}
Abi::Unknown(unknown_abi) => {
panic!(
@@ -3805,6 +3856,13 @@ impl CodeGenerator for Function {
abi => abi,
};
+ // Handle overloaded functions by giving each overload its own unique
+ // suffix.
+ let times_seen = result.overload_number(&canonical_name);
+ if times_seen > 0 {
+ write!(&mut canonical_name, "{}", times_seen).unwrap();
+ }
+
let link_name = mangled_name.unwrap_or(name);
if !utils::names_will_be_identical_after_mangling(
&canonical_name,
@@ -3846,6 +3904,7 @@ impl CodeGenerator for Function {
ident,
abi,
signature.is_variadic(),
+ ctx.options().dynamic_link_require_all,
args,
args_identifiers,
ret,
@@ -3854,6 +3913,7 @@ impl CodeGenerator for Function {
} else {
result.push(tokens);
}
+ Some(times_seen)
}
}
@@ -3909,6 +3969,7 @@ fn objc_method_codegen(
impl CodeGenerator for ObjCInterface {
type Extra = Item;
+ type Return = ();
fn codegen<'a>(
&self,
diff --git a/src/codegen/struct_layout.rs b/src/codegen/struct_layout.rs
index 4536e88..2e4b973 100644
--- a/src/codegen/struct_layout.rs
+++ b/src/codegen/struct_layout.rs
@@ -19,6 +19,7 @@ pub struct StructLayoutTracker<'a> {
comp: &'a CompInfo,
is_packed: bool,
known_type_layout: Option<Layout>,
+ is_rust_union: bool,
latest_offset: usize,
padding_count: usize,
latest_field_layout: Option<Layout>,
@@ -89,12 +90,15 @@ impl<'a> StructLayoutTracker<'a> {
) -> Self {
let known_type_layout = ty.layout(ctx);
let is_packed = comp.is_packed(ctx, known_type_layout.as_ref());
+ let is_rust_union = comp.is_union() &&
+ comp.can_be_rust_union(ctx, known_type_layout.as_ref());
StructLayoutTracker {
name,
ctx,
comp,
is_packed,
known_type_layout,
+ is_rust_union,
latest_offset: 0,
padding_count: 0,
latest_field_layout: None,
@@ -103,6 +107,10 @@ impl<'a> StructLayoutTracker<'a> {
}
}
+ pub fn is_rust_union(&self) -> bool {
+ self.is_rust_union
+ }
+
pub fn saw_vtable(&mut self) {
debug!("saw vtable for {}", self.name);
@@ -143,18 +151,9 @@ impl<'a> StructLayoutTracker<'a> {
// actually generate the dummy alignment.
}
- pub fn saw_union(&mut self, layout: Layout) {
- debug!("saw union for {}: {:?}", self.name, layout);
- self.align_to_latest_field(layout);
-
- self.latest_offset += self.padding_bytes(layout) + layout.size;
- self.latest_field_layout = Some(layout);
- self.max_field_align = cmp::max(self.max_field_align, layout.align);
- }
-
- /// Add a padding field if necessary for a given new field _before_ adding
- /// that field.
- pub fn pad_field(
+ /// Returns a padding field if necessary for a given new field _before_
+ /// adding that field.
+ pub fn saw_field(
&mut self,
field_name: &str,
field_ty: &Type,
@@ -181,15 +180,27 @@ impl<'a> StructLayoutTracker<'a> {
}
}
}
+ self.saw_field_with_layout(field_name, field_layout, field_offset)
+ }
+ pub fn saw_field_with_layout(
+ &mut self,
+ field_name: &str,
+ field_layout: Layout,
+ field_offset: Option<usize>,
+ ) -> Option<proc_macro2::TokenStream> {
let will_merge_with_bitfield = self.align_to_latest_field(field_layout);
+ let is_union = self.comp.is_union();
let padding_bytes = match field_offset {
Some(offset) if offset / 8 > self.latest_offset => {
offset / 8 - self.latest_offset
}
_ => {
- if will_merge_with_bitfield || field_layout.align == 0 {
+ if will_merge_with_bitfield ||
+ field_layout.align == 0 ||
+ is_union
+ {
0
} else if !self.is_packed {
self.padding_bytes(field_layout)
@@ -203,7 +214,7 @@ impl<'a> StructLayoutTracker<'a> {
self.latest_offset += padding_bytes;
- let padding_layout = if self.is_packed {
+ let padding_layout = if self.is_packed || is_union {
None
} else {
// Otherwise the padding is useless.
diff --git a/src/ir/analysis/derive.rs b/src/ir/analysis/derive.rs
index 6c50fa6..be62666 100644
--- a/src/ir/analysis/derive.rs
+++ b/src/ir/analysis/derive.rs
@@ -16,7 +16,7 @@ use crate::ir::ty::{Type, TypeKind};
use crate::{Entry, HashMap, HashSet};
/// Which trait to consider when doing the `CannotDerive` analysis.
-#[derive(Debug, Copy, Clone)]
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum DeriveTrait {
/// The `Copy` trait.
Copy,
@@ -138,12 +138,25 @@ impl<'ctx> CannotDerive<'ctx> {
}
fn constrain_type(&mut self, item: &Item, ty: &Type) -> CanDerive {
- if !self.ctx.whitelisted_items().contains(&item.id()) {
- trace!(
- " cannot derive {} for blacklisted type",
- self.derive_trait
- );
- return CanDerive::No;
+ if !self.ctx.allowlisted_items().contains(&item.id()) {
+ let can_derive = self
+ .ctx
+ .blocklisted_type_implements_trait(item, self.derive_trait);
+ match can_derive {
+ CanDerive::Yes => trace!(
+ " blocklisted type explicitly implements {}",
+ self.derive_trait
+ ),
+ CanDerive::Manually => trace!(
+ " blocklisted type requires manual implementation of {}",
+ self.derive_trait
+ ),
+ CanDerive::No => trace!(
+ " cannot derive {} for blocklisted type",
+ self.derive_trait
+ ),
+ }
+ return can_derive;
}
if self.derive_trait.not_by_name(self.ctx, &item) {
@@ -640,10 +653,10 @@ impl<'ctx> MonotoneFramework for CannotDerive<'ctx> {
}
fn initial_worklist(&self) -> Vec<ItemId> {
- // The transitive closure of all whitelisted items, including explicitly
- // blacklisted items.
+ // The transitive closure of all allowlisted items, including explicitly
+ // blocklisted items.
self.ctx
- .whitelisted_items()
+ .allowlisted_items()
.iter()
.cloned()
.flat_map(|i| {
diff --git a/src/ir/analysis/has_destructor.rs b/src/ir/analysis/has_destructor.rs
index ca4f253..5fa22e3 100644
--- a/src/ir/analysis/has_destructor.rs
+++ b/src/ir/analysis/has_destructor.rs
@@ -83,7 +83,7 @@ impl<'ctx> MonotoneFramework for HasDestructorAnalysis<'ctx> {
}
fn initial_worklist(&self) -> Vec<ItemId> {
- self.ctx.whitelisted_items().iter().cloned().collect()
+ self.ctx.allowlisted_items().iter().cloned().collect()
}
fn constrain(&mut self, id: ItemId) -> ConstrainResult {
diff --git a/src/ir/analysis/has_float.rs b/src/ir/analysis/has_float.rs
index d21e651..bbf2126 100644
--- a/src/ir/analysis/has_float.rs
+++ b/src/ir/analysis/has_float.rs
@@ -94,7 +94,7 @@ impl<'ctx> MonotoneFramework for HasFloat<'ctx> {
}
fn initial_worklist(&self) -> Vec<ItemId> {
- self.ctx.whitelisted_items().iter().cloned().collect()
+ self.ctx.allowlisted_items().iter().cloned().collect()
}
fn constrain(&mut self, id: ItemId) -> ConstrainResult {
diff --git a/src/ir/analysis/has_type_param_in_array.rs b/src/ir/analysis/has_type_param_in_array.rs
index ebdb7e3..aa52304 100644
--- a/src/ir/analysis/has_type_param_in_array.rs
+++ b/src/ir/analysis/has_type_param_in_array.rs
@@ -100,7 +100,7 @@ impl<'ctx> MonotoneFramework for HasTypeParameterInArray<'ctx> {
}
fn initial_worklist(&self) -> Vec<ItemId> {
- self.ctx.whitelisted_items().iter().cloned().collect()
+ self.ctx.allowlisted_items().iter().cloned().collect()
}
fn constrain(&mut self, id: ItemId) -> ConstrainResult {
diff --git a/src/ir/analysis/has_vtable.rs b/src/ir/analysis/has_vtable.rs
index d2a57d5..7f5f911 100644
--- a/src/ir/analysis/has_vtable.rs
+++ b/src/ir/analysis/has_vtable.rs
@@ -147,7 +147,7 @@ impl<'ctx> MonotoneFramework for HasVtableAnalysis<'ctx> {
}
fn initial_worklist(&self) -> Vec<ItemId> {
- self.ctx.whitelisted_items().iter().cloned().collect()
+ self.ctx.allowlisted_items().iter().cloned().collect()
}
fn constrain(&mut self, id: ItemId) -> ConstrainResult {
diff --git a/src/ir/analysis/mod.rs b/src/ir/analysis/mod.rs
index 2cb021f..ec4d20f 100644
--- a/src/ir/analysis/mod.rs
+++ b/src/ir/analysis/mod.rs
@@ -183,7 +183,7 @@ where
{
let mut dependencies = HashMap::default();
- for &item in ctx.whitelisted_items() {
+ for &item in ctx.allowlisted_items() {
dependencies.entry(item).or_insert(vec![]);
{
@@ -192,7 +192,7 @@ where
item.trace(
ctx,
&mut |sub_item: ItemId, edge_kind| {
- if ctx.whitelisted_items().contains(&sub_item) &&
+ if ctx.allowlisted_items().contains(&sub_item) &&
consider_edge(edge_kind)
{
dependencies
diff --git a/src/ir/analysis/sizedness.rs b/src/ir/analysis/sizedness.rs
index d8bced7..a3ef753 100644
--- a/src/ir/analysis/sizedness.rs
+++ b/src/ir/analysis/sizedness.rs
@@ -194,7 +194,7 @@ impl<'ctx> MonotoneFramework for SizednessAnalysis<'ctx> {
fn initial_worklist(&self) -> Vec<TypeId> {
self.ctx
- .whitelisted_items()
+ .allowlisted_items()
.iter()
.cloned()
.filter_map(|id| id.as_type_id(self.ctx))
diff --git a/src/ir/analysis/template_params.rs b/src/ir/analysis/template_params.rs
index f0d9b5e..c2f18b1 100644
--- a/src/ir/analysis/template_params.rs
+++ b/src/ir/analysis/template_params.rs
@@ -137,13 +137,13 @@ use crate::{HashMap, HashSet};
/// analysis. If we didn't, then we would mistakenly determine that ever
/// template parameter is always used.
///
-/// The final wrinkle is handling of blacklisted types. Normally, we say that
-/// the set of whitelisted items is the transitive closure of items explicitly
-/// called out for whitelisting, *without* any items explicitly called out as
-/// blacklisted. However, for the purposes of this analysis's correctness, we
+/// The final wrinkle is handling of blocklisted types. Normally, we say that
+/// the set of allowlisted items is the transitive closure of items explicitly
+/// called out for allowlisting, *without* any items explicitly called out as
+/// blocklisted. However, for the purposes of this analysis's correctness, we
/// simplify and consider run the analysis on the full transitive closure of
-/// whitelisted items. We do, however, treat instantiations of blacklisted items
-/// specially; see `constrain_instantiation_of_blacklisted_template` and its
+/// allowlisted items. We do, however, treat instantiations of blocklisted items
+/// specially; see `constrain_instantiation_of_blocklisted_template` and its
/// documentation for details.
#[derive(Debug, Clone)]
pub struct UsedTemplateParameters<'ctx> {
@@ -155,10 +155,10 @@ pub struct UsedTemplateParameters<'ctx> {
dependencies: HashMap<ItemId, Vec<ItemId>>,
- // The set of whitelisted items, without any blacklisted items reachable
- // from the whitelisted items which would otherwise be considered
- // whitelisted as well.
- whitelisted_items: HashSet<ItemId>,
+ // The set of allowlisted items, without any blocklisted items reachable
+ // from the allowlisted items which would otherwise be considered
+ // allowlisted as well.
+ allowlisted_items: HashSet<ItemId>,
}
impl<'ctx> UsedTemplateParameters<'ctx> {
@@ -221,19 +221,19 @@ impl<'ctx> UsedTemplateParameters<'ctx> {
)
}
- /// We say that blacklisted items use all of their template parameters. The
- /// blacklisted type is most likely implemented explicitly by the user,
+ /// We say that blocklisted items use all of their template parameters. The
+ /// blocklisted type is most likely implemented explicitly by the user,
/// since it won't be in the generated bindings, and we don't know exactly
/// what they'll to with template parameters, but we can push the issue down
/// the line to them.
- fn constrain_instantiation_of_blacklisted_template(
+ fn constrain_instantiation_of_blocklisted_template(
&self,
this_id: ItemId,
used_by_this_id: &mut ItemSet,
instantiation: &TemplateInstantiation,
) {
trace!(
- " instantiation of blacklisted template, uses all template \
+ " instantiation of blocklisted template, uses all template \
arguments"
);
@@ -379,10 +379,10 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
fn new(ctx: &'ctx BindgenContext) -> UsedTemplateParameters<'ctx> {
let mut used = HashMap::default();
let mut dependencies = HashMap::default();
- let whitelisted_items: HashSet<_> =
- ctx.whitelisted_items().iter().cloned().collect();
+ let allowlisted_items: HashSet<_> =
+ ctx.allowlisted_items().iter().cloned().collect();
- let whitelisted_and_blacklisted_items: ItemSet = whitelisted_items
+ let allowlisted_and_blocklisted_items: ItemSet = allowlisted_items
.iter()
.cloned()
.flat_map(|i| {
@@ -398,7 +398,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
})
.collect();
- for item in whitelisted_and_blacklisted_items {
+ for item in allowlisted_and_blocklisted_items {
dependencies.entry(item).or_insert(vec![]);
used.entry(item).or_insert(Some(ItemSet::new()));
@@ -457,17 +457,17 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
}
if cfg!(feature = "testing_only_extra_assertions") {
- // Invariant: The `used` map has an entry for every whitelisted
- // item, as well as all explicitly blacklisted items that are
- // reachable from whitelisted items.
+ // Invariant: The `used` map has an entry for every allowlisted
+ // item, as well as all explicitly blocklisted items that are
+ // reachable from allowlisted items.
//
// Invariant: the `dependencies` map has an entry for every
- // whitelisted item.
+ // allowlisted item.
//
// (This is so that every item we call `constrain` on is guaranteed
// to have a set of template parameters, and we can allow
- // blacklisted templates to use all of their parameters).
- for item in whitelisted_items.iter() {
+ // blocklisted templates to use all of their parameters).
+ for item in allowlisted_items.iter() {
extra_assert!(used.contains_key(item));
extra_assert!(dependencies.contains_key(item));
item.trace(
@@ -485,15 +485,15 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
ctx: ctx,
used: used,
dependencies: dependencies,
- whitelisted_items: whitelisted_items,
+ allowlisted_items: allowlisted_items,
}
}
fn initial_worklist(&self) -> Vec<ItemId> {
- // The transitive closure of all whitelisted items, including explicitly
- // blacklisted items.
+ // The transitive closure of all allowlisted items, including explicitly
+ // blocklisted items.
self.ctx
- .whitelisted_items()
+ .allowlisted_items()
.iter()
.cloned()
.flat_map(|i| {
@@ -538,7 +538,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
// template definition uses the corresponding template parameter.
Some(&TypeKind::TemplateInstantiation(ref inst)) => {
if self
- .whitelisted_items
+ .allowlisted_items
.contains(&inst.template_definition().into())
{
self.constrain_instantiation(
@@ -547,7 +547,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
inst,
);
} else {
- self.constrain_instantiation_of_blacklisted_template(
+ self.constrain_instantiation_of_blocklisted_template(
id,
&mut used_by_this_id,
inst,
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 60b1e2f..52dcddd 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -1642,7 +1642,12 @@ impl CompInfo {
/// Requirements:
/// 1. Current RustTarget allows for `untagged_union`
/// 2. Each field can derive `Copy`
- pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool {
+ /// 3. It's not zero-sized.
+ pub fn can_be_rust_union(
+ &self,
+ ctx: &BindgenContext,
+ layout: Option<&Layout>,
+ ) -> bool {
if !ctx.options().rust_features().untagged_union {
return false;
}
@@ -1651,12 +1656,22 @@ impl CompInfo {
return false;
}
- self.fields().iter().all(|f| match *f {
+ let all_can_copy = self.fields().iter().all(|f| match *f {
Field::DataMember(ref field_data) => {
field_data.ty().can_derive_copy(ctx)
}
Field::Bitfields(_) => true,
- })
+ });
+
+ if !all_can_copy {
+ return false;
+ }
+
+ if layout.map_or(false, |l| l.size == 0) {
+ return false;
+ }
+
+ true
}
}
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 0207547..ccb05e7 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -28,7 +28,7 @@ use cexpr;
use clang_sys;
use proc_macro2::{Ident, Span};
use std::borrow::Cow;
-use std::cell::Cell;
+use std::cell::{Cell, RefCell};
use std::collections::HashMap as StdHashMap;
use std::iter::IntoIterator;
use std::mem;
@@ -376,14 +376,18 @@ pub struct BindgenContext {
/// Whether a bindgen complex was generated
generated_bindgen_complex: Cell<bool>,
- /// The set of `ItemId`s that are whitelisted. This the very first thing
+ /// The set of `ItemId`s that are allowlisted. This the very first thing
/// computed after parsing our IR, and before running any of our analyses.
- whitelisted: Option<ItemSet>,
+ allowlisted: Option<ItemSet>,
- /// The set of `ItemId`s that are whitelisted for code generation _and_ that
+ /// Cache for calls to `ParseCallbacks::blocklisted_type_implements_trait`
+ blocklisted_types_implement_traits:
+ RefCell<HashMap<DeriveTrait, HashMap<ItemId, CanDerive>>>,
+
+ /// The set of `ItemId`s that are allowlisted for code generation _and_ that
/// we should generate accounting for the codegen options.
///
- /// It's computed right after computing the whitelisted items.
+ /// It's computed right after computing the allowlisted items.
codegen_items: Option<ItemSet>,
/// Map from an item's id to the set of template parameter items that it
@@ -463,8 +467,8 @@ pub struct BindgenContext {
has_float: Option<HashSet<ItemId>>,
}
-/// A traversal of whitelisted items.
-struct WhitelistedItemsTraversal<'ctx> {
+/// A traversal of allowlisted items.
+struct AllowlistedItemsTraversal<'ctx> {
ctx: &'ctx BindgenContext,
traversal: ItemTraversal<
'ctx,
@@ -474,14 +478,14 @@ struct WhitelistedItemsTraversal<'ctx> {
>,
}
-impl<'ctx> Iterator for WhitelistedItemsTraversal<'ctx> {
+impl<'ctx> Iterator for AllowlistedItemsTraversal<'ctx> {
type Item = ItemId;
fn next(&mut self) -> Option<ItemId> {
loop {
let id = self.traversal.next()?;
- if self.ctx.resolve_item(id).is_blacklisted(self.ctx) {
+ if self.ctx.resolve_item(id).is_blocklisted(self.ctx) {
continue;
}
@@ -490,8 +494,8 @@ impl<'ctx> Iterator for WhitelistedItemsTraversal<'ctx> {
}
}
-impl<'ctx> WhitelistedItemsTraversal<'ctx> {
- /// Construct a new whitelisted items traversal.
+impl<'ctx> AllowlistedItemsTraversal<'ctx> {
+ /// Construct a new allowlisted items traversal.
pub fn new<R>(
ctx: &'ctx BindgenContext,
roots: R,
@@ -500,7 +504,7 @@ impl<'ctx> WhitelistedItemsTraversal<'ctx> {
where
R: IntoIterator<Item = ItemId>,
{
- WhitelistedItemsTraversal {
+ AllowlistedItemsTraversal {
ctx,
traversal: ItemTraversal::new(ctx, roots, predicate),
}
@@ -559,7 +563,8 @@ If you encounter an error missing from this list, please file an issue or a PR!"
target_info,
options,
generated_bindgen_complex: Cell::new(false),
- whitelisted: None,
+ allowlisted: None,
+ blocklisted_types_implement_traits: Default::default(),
codegen_items: None,
used_template_parameters: None,
need_bitfield_allocation: Default::default(),
@@ -718,8 +723,8 @@ If you encounter an error missing from this list, please file an issue or a PR!"
}
/// Ensure that every item (other than the root module) is in a module's
- /// children list. This is to make sure that every whitelisted item get's
- /// codegen'd, even if its parent is not whitelisted. See issue #769 for
+ /// children list. This is to make sure that every allowlisted item get's
+ /// codegen'd, even if its parent is not allowlisted. See issue #769 for
/// details.
fn add_item_to_module(&mut self, item: &Item) {
assert!(item.id() != self.root_module);
@@ -1024,7 +1029,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
_ => continue,
}
- let path = item.path_for_whitelisting(self);
+ let path = item.path_for_allowlisting(self);
let replacement = self.replacements.get(&path[1..]);
if let Some(replacement) = replacement {
@@ -1134,10 +1139,10 @@ If you encounter an error missing from this list, please file an issue or a PR!"
self.assert_no_dangling_references();
- // Compute the whitelisted set after processing replacements and
+ // Compute the allowlisted set after processing replacements and
// resolving type refs, as those are the final mutations of the IR
// graph, and their completion means that the IR graph is now frozen.
- self.compute_whitelisted_and_codegen_items();
+ self.compute_allowlisted_and_codegen_items();
// Make sure to do this after processing replacements, since that messes
// with the parentage and module children, and we want to assert that it
@@ -1293,14 +1298,14 @@ If you encounter an error missing from this list, please file an issue or a PR!"
fn find_used_template_parameters(&mut self) {
let _t = self.timer("find_used_template_parameters");
- if self.options.whitelist_recursively {
+ if self.options.allowlist_recursively {
let used_params = analyze::<UsedTemplateParameters>(self);
self.used_template_parameters = Some(used_params);
} else {
- // If you aren't recursively whitelisting, then we can't really make
+ // If you aren't recursively allowlisting, then we can't really make
// any sense of template parameter usage, and you're on your own.
let mut used_params = HashMap::default();
- for &id in self.whitelisted_items() {
+ for &id in self.allowlisted_items() {
used_params.entry(id).or_insert(
id.self_template_params(self)
.into_iter()
@@ -1319,9 +1324,9 @@ If you encounter an error missing from this list, please file an issue or a PR!"
/// template usage information is only computed as we enter the codegen
/// phase.
///
- /// If the item is blacklisted, then we say that it always uses the template
+ /// If the item is blocklisted, then we say that it always uses the template
/// parameter. This is a little subtle. The template parameter usage
- /// analysis only considers whitelisted items, and if any blacklisted item
+ /// analysis only considers allowlisted items, and if any blocklisted item
/// shows up in the generated bindings, it is the user's responsibility to
/// manually provide a definition for them. To give them the most
/// flexibility when doing that, we assume that they use every template
@@ -1336,7 +1341,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
"We only compute template parameter usage as we enter codegen"
);
- if self.resolve_item(item).is_blacklisted(self) {
+ if self.resolve_item(item).is_blocklisted(self) {
return true;
}
@@ -2194,15 +2199,46 @@ If you encounter an error missing from this list, please file an issue or a PR!"
self.current_module = previous_id;
}
- /// Iterate over all (explicitly or transitively) whitelisted items.
+ /// Iterate over all (explicitly or transitively) allowlisted items.
///
- /// If no items are explicitly whitelisted, then all items are considered
- /// whitelisted.
- pub fn whitelisted_items(&self) -> &ItemSet {
+ /// If no items are explicitly allowlisted, then all items are considered
+ /// allowlisted.
+ pub fn allowlisted_items(&self) -> &ItemSet {
assert!(self.in_codegen_phase());
assert!(self.current_module == self.root_module);
- self.whitelisted.as_ref().unwrap()
+ self.allowlisted.as_ref().unwrap()
+ }
+
+ /// Check whether a particular blocklisted type implements a trait or not.
+ /// Results may be cached.
+ pub fn blocklisted_type_implements_trait(
+ &self,
+ item: &Item,
+ derive_trait: DeriveTrait,
+ ) -> CanDerive {
+ 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()
+ .entry(derive_trait)
+ .or_default()
+ .entry(item.id())
+ .or_insert_with(|| {
+ item.expect_type()
+ .name()
+ .and_then(|name| {
+ cb.blocklisted_type_implements_trait(name, derive_trait)
+ })
+ .unwrap_or(CanDerive::No)
+ })
}
/// Get a reference to the set of items we should generate.
@@ -2212,12 +2248,12 @@ If you encounter an error missing from this list, please file an issue or a PR!"
self.codegen_items.as_ref().unwrap()
}
- /// Compute the whitelisted items set and populate `self.whitelisted`.
- fn compute_whitelisted_and_codegen_items(&mut self) {
+ /// Compute the allowlisted items set and populate `self.allowlisted`.
+ fn compute_allowlisted_and_codegen_items(&mut self) {
assert!(self.in_codegen_phase());
assert!(self.current_module == self.root_module);
- assert!(self.whitelisted.is_none());
- let _t = self.timer("compute_whitelisted_and_codegen_items");
+ assert!(self.allowlisted.is_none());
+ let _t = self.timer("compute_allowlisted_and_codegen_items");
let roots = {
let mut roots = self
@@ -2225,11 +2261,11 @@ If you encounter an error missing from this list, please file an issue or a PR!"
// Only consider roots that are enabled for codegen.
.filter(|&(_, item)| item.is_enabled_for_codegen(self))
.filter(|&(_, item)| {
- // If nothing is explicitly whitelisted, then everything is fair
+ // If nothing is explicitly allowlisted, then everything is fair
// game.
- if self.options().whitelisted_types.is_empty() &&
- self.options().whitelisted_functions.is_empty() &&
- self.options().whitelisted_vars.is_empty()
+ if self.options().allowlisted_types.is_empty() &&
+ self.options().allowlisted_functions.is_empty() &&
+ self.options().allowlisted_vars.is_empty()
{
return true;
}
@@ -2240,25 +2276,25 @@ If you encounter an error missing from this list, please file an issue or a PR!"
return true;
}
- let name = item.path_for_whitelisting(self)[1..].join("::");
- debug!("whitelisted_items: testing {:?}", name);
+ let name = item.path_for_allowlisting(self)[1..].join("::");
+ debug!("allowlisted_items: testing {:?}", name);
match *item.kind() {
ItemKind::Module(..) => true,
ItemKind::Function(_) => {
- self.options().whitelisted_functions.matches(&name)
+ self.options().allowlisted_functions.matches(&name)
}
ItemKind::Var(_) => {
- self.options().whitelisted_vars.matches(&name)
+ self.options().allowlisted_vars.matches(&name)
}
ItemKind::Type(ref ty) => {
- if self.options().whitelisted_types.matches(&name) {
+ if self.options().allowlisted_types.matches(&name) {
return true;
}
- // Auto-whitelist types that don't need code
- // generation if not whitelisting recursively, to
+ // Auto-allowlist types that don't need code
+ // generation if not allowlisting recursively, to
// make the #[derive] analysis not be lame.
- if !self.options().whitelist_recursively {
+ if !self.options().allowlist_recursively {
match *ty.kind() {
TypeKind::Void |
TypeKind::NullPtr |
@@ -2278,7 +2314,7 @@ If you encounter an error missing from this list, please file an issue or a PR!"
}
// Unnamed top-level enums are special and we
- // whitelist them via the `whitelisted_vars` filter,
+ // allowlist them via the `allowlisted_vars` filter,
// since they're effectively top-level constants,
// and there's no way for them to be referenced
// consistently.
@@ -2297,12 +2333,14 @@ If you encounter an error missing from this list, please file an issue or a PR!"
}
let mut prefix_path =
- parent.path_for_whitelisting(self).clone();
+ parent.path_for_allowlisting(self).clone();
enum_.variants().iter().any(|variant| {
- prefix_path.push(variant.name().into());
+ prefix_path.push(
+ variant.name_for_allowlisting().into(),
+ );
let name = prefix_path[1..].join("::");
prefix_path.pop().unwrap();
- self.options().whitelisted_vars.matches(&name)
+ self.options().allowlisted_vars.matches(&name)
})
}
}
@@ -2317,48 +2355,48 @@ If you encounter an error missing from this list, please file an issue or a PR!"
roots
};
- let whitelisted_items_predicate =
- if self.options().whitelist_recursively {
+ let allowlisted_items_predicate =
+ if self.options().allowlist_recursively {
traversal::all_edges
} else {
- // Only follow InnerType edges from the whitelisted roots.
+ // Only follow InnerType edges from the allowlisted roots.
// Such inner types (e.g. anonymous structs/unions) are
- // always emitted by codegen, and they need to be whitelisted
+ // always emitted by codegen, and they need to be allowlisted
// to make sure they are processed by e.g. the derive analysis.
traversal::only_inner_type_edges
};
- let whitelisted = WhitelistedItemsTraversal::new(
+ let allowlisted = AllowlistedItemsTraversal::new(
self,
roots.clone(),
- whitelisted_items_predicate,
+ allowlisted_items_predicate,
)
.collect::<ItemSet>();
- let codegen_items = if self.options().whitelist_recursively {
- WhitelistedItemsTraversal::new(
+ let codegen_items = if self.options().allowlist_recursively {
+ AllowlistedItemsTraversal::new(
self,
roots.clone(),
traversal::codegen_edges,
)
.collect::<ItemSet>()
} else {
- whitelisted.clone()
+ allowlisted.clone()
};
- self.whitelisted = Some(whitelisted);
+ self.allowlisted = Some(allowlisted);
self.codegen_items = Some(codegen_items);
- for item in self.options().whitelisted_functions.unmatched_items() {
- warn!("unused option: --whitelist-function {}", item);
+ for item in self.options().allowlisted_functions.unmatched_items() {
+ warn!("unused option: --allowlist-function {}", item);
}
- for item in self.options().whitelisted_vars.unmatched_items() {
- warn!("unused option: --whitelist-var {}", item);
+ for item in self.options().allowlisted_vars.unmatched_items() {
+ warn!("unused option: --allowlist-var {}", item);
}
- for item in self.options().whitelisted_types.unmatched_items() {
- warn!("unused option: --whitelist-type {}", item);
+ for item in self.options().allowlisted_types.unmatched_items() {
+ warn!("unused option: --allowlist-type {}", item);
}
}
@@ -2575,31 +2613,31 @@ If you encounter an error missing from this list, please file an issue or a PR!"
/// Check if `--no-partialeq` flag is enabled for this item.
pub fn no_partialeq_by_name(&self, item: &Item) -> bool {
- let name = item.path_for_whitelisting(self)[1..].join("::");
+ let name = item.path_for_allowlisting(self)[1..].join("::");
self.options().no_partialeq_types.matches(&name)
}
/// Check if `--no-copy` flag is enabled for this item.
pub fn no_copy_by_name(&self, item: &Item) -> bool {
- let name = item.path_for_whitelisting(self)[1..].join("::");
+ let name = item.path_for_allowlisting(self)[1..].join("::");
self.options().no_copy_types.matches(&name)
}
/// Check if `--no-debug` flag is enabled for this item.
pub fn no_debug_by_name(&self, item: &Item) -> bool {
- let name = item.path_for_whitelisting(self)[1..].join("::");
+ let name = item.path_for_allowlisting(self)[1..].join("::");
self.options().no_debug_types.matches(&name)
}
/// Check if `--no-default` flag is enabled for this item.
pub fn no_default_by_name(&self, item: &Item) -> bool {
- let name = item.path_for_whitelisting(self)[1..].join("::");
+ let name = item.path_for_allowlisting(self)[1..].join("::");
self.options().no_default_types.matches(&name)
}
/// Check if `--no-hash` flag is enabled for this item.
pub fn no_hash_by_name(&self, item: &Item) -> bool {
- let name = item.path_for_whitelisting(self)[1..].join("::");
+ let name = item.path_for_allowlisting(self)[1..].join("::");
self.options().no_hash_types.matches(&name)
}
}
diff --git a/src/ir/dot.rs b/src/ir/dot.rs
index 6bf75bf..f7d07f1 100644
--- a/src/ir/dot.rs
+++ b/src/ir/dot.rs
@@ -32,13 +32,13 @@ where
let mut err: Option<io::Result<_>> = None;
for (id, item) in ctx.items() {
- let is_whitelisted = ctx.whitelisted_items().contains(&id);
+ let is_allowlisted = ctx.allowlisted_items().contains(&id);
writeln!(
&mut dot_file,
r#"{} [fontname="courier", color={}, label=< <table border="0" align="left">"#,
id.as_usize(),
- if is_whitelisted { "black" } else { "gray" }
+ if is_allowlisted { "black" } else { "gray" }
)?;
item.dot_attributes(ctx, &mut dot_file)?;
writeln!(&mut dot_file, r#"</table> >];"#)?;
@@ -56,7 +56,7 @@ where
id.as_usize(),
sub_id.as_usize(),
edge_kind,
- if is_whitelisted { "black" } else { "gray" }
+ if is_allowlisted { "black" } else { "gray" }
) {
Ok(_) => {}
Err(e) => err = Some(Err(e)),
diff --git a/src/ir/enum_ty.rs b/src/ir/enum_ty.rs
index dde4bb1..15d4136 100644
--- a/src/ir/enum_ty.rs
+++ b/src/ir/enum_ty.rs
@@ -118,7 +118,7 @@ impl Enum {
}
});
- let name = ctx
+ let new_name = ctx
.parse_callbacks()
.and_then(|callbacks| {
callbacks.enum_variant_name(type_name, &name, val)
@@ -130,10 +130,11 @@ impl Enum {
.last()
.cloned()
})
- .unwrap_or(name);
+ .unwrap_or_else(|| name.clone());
let comment = cursor.raw_comment();
variants.push(EnumVariant::new(
+ new_name,
name,
comment,
val,
@@ -152,7 +153,7 @@ impl Enum {
enums: &RegexSet,
item: &Item,
) -> bool {
- let path = item.path_for_whitelisting(ctx);
+ let path = item.path_for_allowlisting(ctx);
let enum_ty = item.expect_type();
if enums.matches(&path[1..].join("::")) {
@@ -224,6 +225,9 @@ pub struct EnumVariant {
/// The name of the variant.
name: String,
+ /// The original name of the variant (without user mangling)
+ name_for_allowlisting: String,
+
/// An optional doc comment.
comment: Option<String>,
@@ -251,12 +255,14 @@ impl EnumVariant {
/// Construct a new enumeration variant from the given parts.
pub fn new(
name: String,
+ name_for_allowlisting: String,
comment: Option<String>,
val: EnumVariantValue,
custom_behavior: Option<EnumVariantCustomBehavior>,
) -> Self {
EnumVariant {
name,
+ name_for_allowlisting,
comment,
val,
custom_behavior,
@@ -268,6 +274,11 @@ impl EnumVariant {
&self.name
}
+ /// Get this variant's name.
+ pub fn name_for_allowlisting(&self) -> &str {
+ &self.name_for_allowlisting
+ }
+
/// Get this variant's value.
pub fn val(&self) -> EnumVariantValue {
self.val
diff --git a/src/ir/item.rs b/src/ir/item.rs
index e9abed7..4541504 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -273,10 +273,10 @@ impl Trace for Item {
where
T: Tracer,
{
- // Even if this item is blacklisted/hidden, we want to trace it. It is
+ // Even if this item is blocklisted/hidden, we want to trace it. It is
// traversal iterators' consumers' responsibility to filter items as
// needed. Generally, this filtering happens in the implementation of
- // `Iterator` for `WhitelistedItems`. Fully tracing blacklisted items is
+ // `Iterator` for `allowlistedItems`. Fully tracing blocklisted items is
// necessary for things like the template parameter usage analysis to
// function correctly.
@@ -301,12 +301,12 @@ impl Trace for Item {
}
ItemKind::Module(_) => {
// Module -> children edges are "weak", and we do not want to
- // trace them. If we did, then whitelisting wouldn't work as
+ // trace them. If we did, then allowlisting wouldn't work as
// expected: everything in every module would end up
- // whitelisted.
+ // allowlisted.
//
// TODO: make a new edge kind for module -> children edges and
- // filter them during whitelisting traversals.
+ // filter them during allowlisting traversals.
}
}
}
@@ -400,9 +400,9 @@ pub struct Item {
/// considerably faster in those cases.
canonical_name: LazyCell<String>,
- /// The path to use for whitelisting and other name-based checks, as
- /// returned by `path_for_whitelisting`, lazily constructed.
- path_for_whitelisting: LazyCell<Vec<String>>,
+ /// The path to use for allowlisting and other name-based checks, as
+ /// returned by `path_for_allowlisting`, lazily constructed.
+ path_for_allowlisting: LazyCell<Vec<String>>,
/// A doc comment over the item, if any.
comment: Option<String>,
@@ -440,7 +440,7 @@ impl Item {
local_id: LazyCell::new(),
next_child_local_id: Cell::new(1),
canonical_name: LazyCell::new(),
- path_for_whitelisting: LazyCell::new(),
+ path_for_allowlisting: LazyCell::new(),
parent_id: parent_id,
comment: comment,
annotations: annotations.unwrap_or_default(),
@@ -623,10 +623,10 @@ impl Item {
&self.annotations
}
- /// Whether this item should be blacklisted.
+ /// Whether this item should be blocklisted.
///
/// This may be due to either annotations or to other kind of configuration.
- pub fn is_blacklisted(&self, ctx: &BindgenContext) -> bool {
+ pub fn is_blocklisted(&self, ctx: &BindgenContext) -> bool {
debug_assert!(
ctx.in_codegen_phase(),
"You're not supposed to call this yet"
@@ -635,18 +635,18 @@ impl Item {
return true;
}
- let path = self.path_for_whitelisting(ctx);
+ let path = self.path_for_allowlisting(ctx);
let name = path[1..].join("::");
- ctx.options().blacklisted_items.matches(&name) ||
+ ctx.options().blocklisted_items.matches(&name) ||
match self.kind {
ItemKind::Type(..) => {
- ctx.options().blacklisted_types.matches(&name) ||
+ ctx.options().blocklisted_types.matches(&name) ||
ctx.is_replaced_type(&path, self.id)
}
ItemKind::Function(..) => {
- ctx.options().blacklisted_functions.matches(&name)
+ ctx.options().blocklisted_functions.matches(&name)
}
- // TODO: Add constant / namespace blacklisting?
+ // TODO: Add constant / namespace blocklisting?
ItemKind::Var(..) | ItemKind::Module(..) => false,
}
}
@@ -1012,10 +1012,10 @@ impl Item {
}
}
- /// Returns the path we should use for whitelisting / blacklisting, which
+ /// Returns the path we should use for allowlisting / blocklisting, which
/// doesn't include user-mangling.
- pub fn path_for_whitelisting(&self, ctx: &BindgenContext) -> &Vec<String> {
- self.path_for_whitelisting
+ pub fn path_for_allowlisting(&self, ctx: &BindgenContext) -> &Vec<String> {
+ self.path_for_allowlisting
.borrow_with(|| self.compute_path(ctx, UserMangled::No))
}
@@ -1081,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_whitelisting(ctx))
+ ctx.opaque_by_name(&self.path_for_allowlisting(ctx))
}
}
@@ -1390,7 +1390,7 @@ impl ClangItemParser for Item {
if cursor.kind() == CXCursor_UnexposedDecl {
Err(ParseError::Recurse)
} else {
- // We whitelist cursors here known to be unhandled, to prevent being
+ // We allowlist cursors here known to be unhandled, to prevent being
// too noisy about this.
match cursor.kind() {
CXCursor_MacroDefinition |
@@ -1918,7 +1918,7 @@ impl ItemCanonicalPath for Item {
/// not.
///
/// Most of the callers probably want just yes, but the ones dealing with
-/// whitelisting and blacklisting don't.
+/// allowlisting and blocklisting don't.
#[derive(Copy, Clone, Debug, PartialEq)]
enum UserMangled {
No,
diff --git a/src/ir/template.rs b/src/ir/template.rs
index 8c625d1..b519fff 100644
--- a/src/ir/template.rs
+++ b/src/ir/template.rs
@@ -306,13 +306,13 @@ impl IsOpaque for TemplateInstantiation {
// correct fix is to make `canonical_{name,path}` include template
// arguments properly.
- let mut path = item.path_for_whitelisting(ctx).clone();
+ let mut path = item.path_for_allowlisting(ctx).clone();
let args: Vec<_> = self
.template_arguments()
.iter()
.map(|arg| {
let arg_path =
- ctx.resolve_item(*arg).path_for_whitelisting(ctx);
+ ctx.resolve_item(*arg).path_for_allowlisting(ctx);
arg_path[1..].join("::")
})
.collect();
diff --git a/src/ir/traversal.rs b/src/ir/traversal.rs
index e4a4470..430dd02 100644
--- a/src/ir/traversal.rs
+++ b/src/ir/traversal.rs
@@ -201,7 +201,7 @@ pub fn all_edges(_: &BindgenContext, _: Edge) -> bool {
/// A `TraversalPredicate` implementation that only follows
/// `EdgeKind::InnerType` edges, and therefore traversals using this predicate
/// will only visit the traversal's roots and their inner types. This is used
-/// in no-recursive-whitelist mode, where inner types such as anonymous
+/// in no-recursive-allowlist mode, where inner types such as anonymous
/// structs/unions still need to be processed.
pub fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool {
edge.kind == EdgeKind::InnerType
@@ -377,7 +377,7 @@ pub trait Trace {
/// An graph traversal of the transitive closure of references between items.
///
-/// See `BindgenContext::whitelisted_items` for more information.
+/// See `BindgenContext::allowlisted_items` for more information.
pub struct ItemTraversal<'ctx, Storage, Queue, Predicate>
where
Storage: TraversalStorage<'ctx>,
diff --git a/src/lib.rs b/src/lib.rs
index 65cf66a..d0253db 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -177,8 +177,8 @@ impl Default for CodegenConfig {
///
/// // Configure and generate bindings.
/// let bindings = builder().header("path/to/input/header")
-/// .whitelist_type("SomeCoolClass")
-/// .whitelist_function("do_some_cool_thing")
+/// .allowlist_type("SomeCoolClass")
+/// .allowlist_function("do_some_cool_thing")
/// .generate()?;
///
/// // Write the generated bindings to an output file.
@@ -304,13 +304,13 @@ impl Builder {
(&self.options.type_alias, "--type-alias"),
(&self.options.new_type_alias, "--new-type-alias"),
(&self.options.new_type_alias_deref, "--new-type-alias-deref"),
- (&self.options.blacklisted_types, "--blacklist-type"),
- (&self.options.blacklisted_functions, "--blacklist-function"),
- (&self.options.blacklisted_items, "--blacklist-item"),
+ (&self.options.blocklisted_types, "--blocklist-type"),
+ (&self.options.blocklisted_functions, "--blocklist-function"),
+ (&self.options.blocklisted_items, "--blocklist-item"),
(&self.options.opaque_types, "--opaque-type"),
- (&self.options.whitelisted_functions, "--whitelist-function"),
- (&self.options.whitelisted_types, "--whitelist-type"),
- (&self.options.whitelisted_vars, "--whitelist-var"),
+ (&self.options.allowlisted_functions, "--allowlist-function"),
+ (&self.options.allowlisted_types, "--allowlist-type"),
+ (&self.options.allowlisted_vars, "--allowlist-var"),
(&self.options.no_partialeq_types, "--no-partialeq"),
(&self.options.no_copy_types, "--no-copy"),
(&self.options.no_debug_types, "--no-debug"),
@@ -379,8 +379,8 @@ impl Builder {
output_vector.push("--no-doc-comments".into());
}
- if !self.options.whitelist_recursively {
- output_vector.push("--no-recursive-whitelist".into());
+ if !self.options.allowlist_recursively {
+ output_vector.push("--no-recursive-allowlist".into());
}
if self.options.objc_extern_crate {
@@ -545,10 +545,18 @@ impl Builder {
output_vector.push(name.clone());
}
+ if self.options.dynamic_link_require_all {
+ output_vector.push("--dynamic-link-require-all".into());
+ }
+
if self.options.respect_cxx_access_specs {
output_vector.push("--respect-cxx-access-specs".into());
}
+ if self.options.translate_enum_integer_types {
+ output_vector.push("--translate-enum-integer-types".into());
+ }
+
// Add clang arguments
output_vector.push("--".into());
@@ -642,12 +650,7 @@ impl Builder {
}
/// Whether the generated bindings should contain documentation comments
- /// (docstrings) or not.
- ///
- /// This ideally will always be true, but it may need to be false until we
- /// implement some processing on comments to work around issues as described
- /// in [rust-bindgen issue
- /// #426](https://github.com/rust-lang/rust-bindgen/issues/426).
+ /// (docstrings) or not. This is set to true by default.
///
/// Note that clang by default excludes comments from system headers, pass
/// `-fretain-comments-from-system-headers` as
@@ -661,9 +664,9 @@ impl Builder {
self
}
- /// Whether to whitelist recursively or not. Defaults to true.
+ /// Whether to allowlist recursively or not. Defaults to true.
///
- /// Given that we have explicitly whitelisted the "initiate_dance_party"
+ /// Given that we have explicitly allowlisted the "initiate_dance_party"
/// function in this C header:
///
/// ```c
@@ -676,23 +679,29 @@ impl Builder {
///
/// We would normally generate bindings to both the `initiate_dance_party`
/// function and the `MoonBoots` struct that it transitively references. By
- /// configuring with `whitelist_recursively(false)`, `bindgen` will not emit
- /// bindings for anything except the explicitly whitelisted items, and there
+ /// configuring with `allowlist_recursively(false)`, `bindgen` will not emit
+ /// bindings for anything except the explicitly allowlisted items, and there
/// would be no emitted struct definition for `MoonBoots`. However, the
/// `initiate_dance_party` function would still reference `MoonBoots`!
///
/// **Disabling this feature will almost certainly cause `bindgen` to emit
/// bindings that will not compile!** If you disable this feature, then it
/// is *your* responsibility to provide definitions for every type that is
- /// referenced from an explicitly whitelisted item. One way to provide the
+ /// referenced from an explicitly allowlisted item. One way to provide the
/// definitions is by using the [`Builder::raw_line`](#method.raw_line)
/// method, another would be to define them in Rust and then `include!(...)`
/// the bindings immediately afterwards.
- pub fn whitelist_recursively(mut self, doit: bool) -> Self {
- self.options.whitelist_recursively = doit;
+ pub fn allowlist_recursively(mut self, doit: bool) -> Self {
+ self.options.allowlist_recursively = doit;
self
}
+ /// Deprecated alias for allowlist_recursively.
+ #[deprecated(note = "Use allowlist_recursively instead")]
+ pub fn whitelist_recursively(self, doit: bool) -> Self {
+ self.allowlist_recursively(doit)
+ }
+
/// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
/// in the prologue of the files generated from objective-c files
pub fn objc_extern_crate(mut self, doit: bool) -> Self {
@@ -727,30 +736,53 @@ impl Builder {
/// Hide the given type from the generated bindings. Regular expressions are
/// supported.
- #[deprecated(note = "Use blacklist_type instead")]
+ #[deprecated(note = "Use blocklist_type instead")]
pub fn hide_type<T: AsRef<str>>(self, arg: T) -> Builder {
- self.blacklist_type(arg)
+ self.blocklist_type(arg)
+ }
+
+ /// Hide the given type from the generated bindings. Regular expressions are
+ /// supported.
+ #[deprecated(note = "Use blocklist_type instead")]
+ pub fn blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder {
+ self.blocklist_type(arg)
}
/// Hide the given type from the generated bindings. Regular expressions are
/// supported.
///
- /// To blacklist types prefixed with "mylib" use `"mylib_.*"`.
+ /// To blocklist types prefixed with "mylib" use `"mylib_.*"`.
/// For more complicated expressions check
/// [regex](https://docs.rs/regex/*/regex/) docs
- pub fn blacklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
- self.options.blacklisted_types.insert(arg);
+ pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.blocklisted_types.insert(arg);
self
}
/// Hide the given function from the generated bindings. Regular expressions
/// are supported.
+ #[deprecated(note = "Use blocklist_function instead")]
+ pub fn blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder {
+ self.blocklist_function(arg)
+ }
+
+ /// Hide the given function from the generated bindings. Regular expressions
+ /// are supported.
///
- /// To blacklist functions prefixed with "mylib" use `"mylib_.*"`.
+ /// To blocklist functions prefixed with "mylib" use `"mylib_.*"`.
/// For more complicated expressions check
/// [regex](https://docs.rs/regex/*/regex/) docs
- pub fn blacklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
- self.options.blacklisted_functions.insert(arg);
+ pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.blocklisted_functions.insert(arg);
+ self
+ }
+
+ /// Hide the given item from the generated bindings, regardless of
+ /// whether it's a type, function, module, etc. Regular
+ /// expressions are supported.
+ #[deprecated(note = "Use blocklist_item instead")]
+ pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.blocklisted_items.insert(arg);
self
}
@@ -758,11 +790,11 @@ impl Builder {
/// whether it's a type, function, module, etc. Regular
/// expressions are supported.
///
- /// To blacklist items prefixed with "mylib" use `"mylib_.*"`.
+ /// To blocklist items prefixed with "mylib" use `"mylib_.*"`.
/// For more complicated expressions check
/// [regex](https://docs.rs/regex/*/regex/) docs
- pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
- self.options.blacklisted_items.insert(arg);
+ pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.blocklisted_items.insert(arg);
self
}
@@ -777,64 +809,86 @@ impl Builder {
self
}
- /// Whitelist the given type so that it (and all types that it transitively
+ /// Allowlist the given type so that it (and all types that it transitively
/// refers to) appears in the generated bindings. Regular expressions are
/// supported.
- #[deprecated(note = "use whitelist_type instead")]
+ #[deprecated(note = "use allowlist_type instead")]
pub fn whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder {
- self.whitelist_type(arg)
+ self.allowlist_type(arg)
+ }
+
+ /// Allowlist the given type so that it (and all types that it transitively
+ /// refers to) appears in the generated bindings. Regular expressions are
+ /// supported.
+ #[deprecated(note = "use allowlist_type instead")]
+ pub fn whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder {
+ self.allowlist_type(arg)
}
- /// Whitelist the given type so that it (and all types that it transitively
+ /// Allowlist the given type so that it (and all types that it transitively
/// refers to) appears in the generated bindings. Regular expressions are
/// supported.
///
- /// To whitelist types prefixed with "mylib" use `"mylib_.*"`.
+ /// To allowlist types prefixed with "mylib" use `"mylib_.*"`.
/// For more complicated expressions check
/// [regex](https://docs.rs/regex/*/regex/) docs
- pub fn whitelist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
- self.options.whitelisted_types.insert(arg);
+ pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.allowlisted_types.insert(arg);
self
}
- /// Whitelist the given function so that it (and all types that it
+ /// Allowlist the given function so that it (and all types that it
/// transitively refers to) appears in the generated bindings. Regular
/// expressions are supported.
///
- /// To whitelist functions prefixed with "mylib" use `"mylib_.*"`.
+ /// To allowlist functions prefixed with "mylib" use `"mylib_.*"`.
/// For more complicated expressions check
/// [regex](https://docs.rs/regex/*/regex/) docs
- pub fn whitelist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
- self.options.whitelisted_functions.insert(arg);
+ pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.allowlisted_functions.insert(arg);
self
}
- /// Whitelist the given function.
+ /// Allowlist the given function.
///
- /// Deprecated: use whitelist_function instead.
- #[deprecated(note = "use whitelist_function instead")]
+ /// Deprecated: use allowlist_function instead.
+ #[deprecated(note = "use allowlist_function instead")]
+ pub fn whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder {
+ self.allowlist_function(arg)
+ }
+
+ /// Allowlist the given function.
+ ///
+ /// Deprecated: use allowlist_function instead.
+ #[deprecated(note = "use allowlist_function instead")]
pub fn whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder {
- self.whitelist_function(arg)
+ self.allowlist_function(arg)
}
- /// Whitelist the given variable so that it (and all types that it
+ /// Allowlist the given variable so that it (and all types that it
/// transitively refers to) appears in the generated bindings. Regular
/// expressions are supported.
///
- /// To whitelist variables prefixed with "mylib" use `"mylib_.*"`.
+ /// To allowlist variables prefixed with "mylib" use `"mylib_.*"`.
/// For more complicated expressions check
/// [regex](https://docs.rs/regex/*/regex/) docs
- pub fn whitelist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
- self.options.whitelisted_vars.insert(arg);
+ pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
+ self.options.allowlisted_vars.insert(arg);
self
}
- /// Whitelist the given variable.
+ /// Deprecated: use allowlist_var instead.
+ #[deprecated(note = "use allowlist_var instead")]
+ pub fn whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder {
+ self.allowlist_var(arg)
+ }
+
+ /// Allowlist the given variable.
///
- /// Deprecated: use whitelist_var instead.
- #[deprecated(note = "use whitelist_var instead")]
+ /// Deprecated: use allowlist_var instead.
+ #[deprecated(note = "use allowlist_var instead")]
pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
- self.whitelist_var(arg)
+ self.allowlist_var(arg)
}
/// Set the default style of code to generate for enums
@@ -1163,7 +1217,7 @@ impl Builder {
/// This method disables that behavior.
///
/// Note that this intentionally does not change the names used for
- /// whitelisting and blacklisting, which should still be mangled with the
+ /// allowlisting and blocklisting, which should still be mangled with the
/// namespaces.
///
/// Note, also, that this option may cause bindgen to generate duplicate
@@ -1523,27 +1577,45 @@ impl Builder {
self
}
+ /// Require successful linkage for all routines in a shared library.
+ /// This allows us to optimize function calls by being able to safely assume function pointers
+ /// are valid.
+ pub fn dynamic_link_require_all(mut self, req: bool) -> Self {
+ self.options.dynamic_link_require_all = req;
+ self
+ }
+
/// Generate bindings as `pub` only if the bound item is publically accessible by C++.
pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self {
self.options.respect_cxx_access_specs = doit;
self
}
+
+ /// Always translate enum integer types to native Rust integer types.
+ ///
+ /// This will result in enums having types such as `u32` and `i16` instead
+ /// of `c_uint` and `c_short`. Types for Rustified enums are always
+ /// translated.
+ pub fn translate_enum_integer_types(mut self, doit: bool) -> Self {
+ self.options.translate_enum_integer_types = doit;
+ self
+ }
}
/// Configuration options for generated bindings.
#[derive(Debug)]
struct BindgenOptions {
- /// The set of types that have been blacklisted and should not appear
+ /// The set of types that have been blocklisted and should not appear
/// anywhere in the generated code.
- blacklisted_types: RegexSet,
+ blocklisted_types: RegexSet,
- /// The set of functions that have been blacklisted and should not appear
+ /// The set of functions that have been blocklisted and should not appear
/// in the generated code.
- blacklisted_functions: RegexSet,
+ blocklisted_functions: RegexSet,
/// The set of items, regardless of item-type, that have been
- /// blacklisted and should not appear in the generated code.
- blacklisted_items: RegexSet,
+ /// blocklisted and should not appear in the generated code.
+ blocklisted_items: RegexSet,
/// The set of types that should be treated as opaque structures in the
/// generated code.
@@ -1556,15 +1628,15 @@ struct BindgenOptions {
/// code.
///
/// This includes all types transitively reachable from any type in this
- /// set. One might think of whitelisted types/vars/functions as GC roots,
+ /// set. One might think of allowlisted types/vars/functions as GC roots,
/// and the generated Rust code as including everything that gets marked.
- whitelisted_types: RegexSet,
+ allowlisted_types: RegexSet,
- /// Whitelisted functions. See docs for `whitelisted_types` for more.
- whitelisted_functions: RegexSet,
+ /// Allowlisted functions. See docs for `allowlisted_types` for more.
+ allowlisted_functions: RegexSet,
- /// Whitelisted variables. See docs for `whitelisted_types` for more.
- whitelisted_vars: RegexSet,
+ /// Allowlisted variables. See docs for `allowlisted_types` for more.
+ allowlisted_vars: RegexSet,
/// The default style of code to generate for enums
default_enum_style: codegen::EnumVariation,
@@ -1730,14 +1802,14 @@ struct BindgenOptions {
conservative_inline_namespaces: bool,
/// Whether to keep documentation comments in the generated output. See the
- /// documentation for more details.
+ /// documentation for more details. Defaults to true.
generate_comments: bool,
/// Whether to generate inline functions. Defaults to false.
generate_inline_functions: bool,
- /// Whether to whitelist types recursively. Defaults to true.
- whitelist_recursively: bool,
+ /// Whether to allowlist types recursively. Defaults to true.
+ allowlist_recursively: bool,
/// Instead of emitting 'use objc;' to files generated from objective c files,
/// generate '#[macro_use] extern crate objc;'
@@ -1777,7 +1849,7 @@ struct BindgenOptions {
/// Whether we should record which items in the regex sets ever matched.
///
- /// This may be a bit slower, but will enable reporting of unused whitelist
+ /// This may be a bit slower, but will enable reporting of unused allowlist
/// items via the `error!` log.
record_matches: bool,
@@ -1816,9 +1888,17 @@ struct BindgenOptions {
/// this is None, no dynamic bindings are created.
dynamic_library_name: Option<String>,
+ /// Require successful linkage for all routines in a shared library.
+ /// This allows us to optimize function calls by being able to safely assume function pointers
+ /// are valid. No effect if `dynamic_library_name` is None.
+ dynamic_link_require_all: bool,
+
/// Only make generated bindings `pub` if the items would be publically accessible
/// by C++.
respect_cxx_access_specs: bool,
+
+ /// Always translate enum integer types to native Rust integer types.
+ translate_enum_integer_types: bool,
}
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1829,12 +1909,12 @@ impl ::std::panic::UnwindSafe for BindgenOptions {}
impl BindgenOptions {
fn build(&mut self) {
let mut regex_sets = [
- &mut self.whitelisted_vars,
- &mut self.whitelisted_types,
- &mut self.whitelisted_functions,
- &mut self.blacklisted_types,
- &mut self.blacklisted_functions,
- &mut self.blacklisted_items,
+ &mut self.allowlisted_vars,
+ &mut self.allowlisted_types,
+ &mut self.allowlisted_functions,
+ &mut self.blocklisted_types,
+ &mut self.blocklisted_functions,
+ &mut self.blocklisted_items,
&mut self.opaque_types,
&mut self.bitfield_enums,
&mut self.constified_enums,
@@ -1878,14 +1958,14 @@ impl Default for BindgenOptions {
BindgenOptions {
rust_target,
rust_features: rust_target.into(),
- blacklisted_types: Default::default(),
- blacklisted_functions: Default::default(),
- blacklisted_items: Default::default(),
+ blocklisted_types: Default::default(),
+ blocklisted_functions: Default::default(),
+ blocklisted_items: Default::default(),
opaque_types: Default::default(),
rustfmt_path: Default::default(),
- whitelisted_types: Default::default(),
- whitelisted_functions: Default::default(),
- whitelisted_vars: Default::default(),
+ allowlisted_types: Default::default(),
+ allowlisted_functions: Default::default(),
+ allowlisted_vars: Default::default(),
default_enum_style: Default::default(),
bitfield_enums: Default::default(),
newtype_enums: Default::default(),
@@ -1934,7 +2014,7 @@ impl Default for BindgenOptions {
conservative_inline_namespaces: false,
generate_comments: true,
generate_inline_functions: false,
- whitelist_recursively: true,
+ allowlist_recursively: true,
generate_block: false,
objc_extern_crate: false,
block_extern_crate: false,
@@ -1955,7 +2035,9 @@ impl Default for BindgenOptions {
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,
}
}
}
@@ -2237,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.57.0");
+ let version = Some("0.58.1");
let header = format!(
"/* automatically generated by rust-bindgen {} */\n\n",
version.unwrap_or("(unknown version)")
@@ -2444,10 +2526,12 @@ pub struct ClangVersion {
pub fn clang_version() -> ClangVersion {
ensure_libclang_is_loaded();
+ //Debian clang version 11.0.1-2
let raw_v: String = clang::extract_clang_version();
let split_v: Option<Vec<&str>> = raw_v
.split_whitespace()
- .nth(2)
+ .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
+ .next()
.map(|v| v.split('.').collect());
match split_v {
Some(v) => {
@@ -2518,8 +2602,8 @@ fn commandline_flag_unit_test_function() {
//Test 2
let bindings = crate::builder()
.header("input_header")
- .whitelist_type("Distinct_Type")
- .whitelist_function("safe_function");
+ .allowlist_type("Distinct_Type")
+ .allowlist_function("safe_function");
let command_line_flags = bindings.command_line_flags();
let test_cases = vec![
@@ -2528,9 +2612,9 @@ fn commandline_flag_unit_test_function() {
"--no-derive-default",
"--generate",
"functions,types,vars,methods,constructors,destructors",
- "--whitelist-type",
+ "--allowlist-type",
"Distinct_Type",
- "--whitelist-function",
+ "--allowlist-function",
"safe_function",
]
.iter()
diff --git a/src/options.rs b/src/options.rs
index f5c61e2..70b7990 100644
--- a/src/options.rs
+++ b/src/options.rs
@@ -23,7 +23,7 @@ where
);
let matches = App::new("bindgen")
- .version(Some("0.57.0").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(&[
@@ -136,22 +136,25 @@ where
.takes_value(true)
.multiple(true)
.number_of_values(1),
- Arg::with_name("blacklist-type")
- .long("blacklist-type")
+ Arg::with_name("blocklist-type")
+ .alias("blacklist-type")
+ .long("blocklist-type")
.help("Mark <type> as hidden.")
.value_name("type")
.takes_value(true)
.multiple(true)
.number_of_values(1),
- Arg::with_name("blacklist-function")
- .long("blacklist-function")
+ Arg::with_name("blocklist-function")
+ .alias("blacklist-function")
+ .long("blocklist-function")
.help("Mark <function> as hidden.")
.value_name("function")
.takes_value(true)
.multiple(true)
.number_of_values(1),
- Arg::with_name("blacklist-item")
- .long("blacklist-item")
+ Arg::with_name("blocklist-item")
+ .alias("blacklist-item")
+ .long("blocklist-item")
.help("Mark <item> as hidden.")
.value_name("item")
.takes_value(true)
@@ -210,12 +213,13 @@ where
"Avoid including doc comments in the output, see: \
https://github.com/rust-lang/rust-bindgen/issues/426",
),
- Arg::with_name("no-recursive-whitelist")
- .long("no-recursive-whitelist")
+ Arg::with_name("no-recursive-allowlist")
+ .long("no-recursive-allowlist")
+ .alias("no-recursive-whitelist")
.help(
- "Disable whitelisting types recursively. This will cause \
+ "Disable allowlisting types recursively. This will cause \
bindgen to emit Rust code that won't compile! See the \
- `bindgen::Builder::whitelist_recursively` method's \
+ `bindgen::Builder::allowlist_recursively` method's \
documentation for details.",
),
Arg::with_name("objc-extern-crate")
@@ -364,11 +368,12 @@ where
Arg::with_name("use-msvc-mangling")
.long("use-msvc-mangling")
.help("MSVC C++ ABI mangling. DEPRECATED: Has no effect."),
- Arg::with_name("whitelist-function")
- .long("whitelist-function")
+ Arg::with_name("allowlist-function")
+ .long("allowlist-function")
+ .alias("whitelist-function")
.help(
- "Whitelist all the free-standing functions matching \
- <regex>. Other non-whitelisted functions will not be \
+ "Allowlist all the free-standing functions matching \
+ <regex>. Other non-allowlisted functions will not be \
generated.",
)
.value_name("regex")
@@ -378,21 +383,23 @@ where
Arg::with_name("generate-inline-functions")
.long("generate-inline-functions")
.help("Generate inline functions."),
- Arg::with_name("whitelist-type")
- .long("whitelist-type")
+ Arg::with_name("allowlist-type")
+ .long("allowlist-type")
+ .alias("whitelist-type")
.help(
- "Only generate types matching <regex>. Other non-whitelisted types will \
+ "Only generate types matching <regex>. Other non-allowlisted types will \
not be generated.",
)
.value_name("regex")
.takes_value(true)
.multiple(true)
.number_of_values(1),
- Arg::with_name("whitelist-var")
- .long("whitelist-var")
+ Arg::with_name("allowlist-var")
+ .long("allowlist-var")
+ .alias("whitelist-var")
.help(
- "Whitelist all the free-standing variables matching \
- <regex>. Other non-whitelisted variables will not be \
+ "Allowlist all the free-standing variables matching \
+ <regex>. Other non-allowlisted variables will not be \
generated.",
)
.value_name("regex")
@@ -493,9 +500,15 @@ where
.long("dynamic-loading")
.takes_value(true)
.help("Use dynamic loading mode with the given library name."),
+ Arg::with_name("dynamic-link-require-all")
+ .long("dynamic-link-require-all")
+ .help("Require successful linkage to all functions in the library."),
Arg::with_name("respect-cxx-access-specs")
.long("respect-cxx-access-specs")
.help("Makes generated bindings `pub` only for items if the items are publically accessible in C++."),
+ Arg::with_name("translate-enum-integer-types")
+ .long("translate-enum-integer-types")
+ .help("Always translate enum integer types to native Rust integer types."),
]) // .args()
.get_matches_from(args);
@@ -582,21 +595,21 @@ where
}
}
- if let Some(hidden_types) = matches.values_of("blacklist-type") {
+ if let Some(hidden_types) = matches.values_of("blocklist-type") {
for ty in hidden_types {
- builder = builder.blacklist_type(ty);
+ builder = builder.blocklist_type(ty);
}
}
- if let Some(hidden_functions) = matches.values_of("blacklist-function") {
+ if let Some(hidden_functions) = matches.values_of("blocklist-function") {
for fun in hidden_functions {
- builder = builder.blacklist_function(fun);
+ builder = builder.blocklist_function(fun);
}
}
- if let Some(hidden_identifiers) = matches.values_of("blacklist-item") {
+ if let Some(hidden_identifiers) = matches.values_of("blocklist-item") {
for id in hidden_identifiers {
- builder = builder.blacklist_item(id);
+ builder = builder.blocklist_item(id);
}
}
@@ -758,8 +771,8 @@ where
builder = builder.generate_comments(false);
}
- if matches.is_present("no-recursive-whitelist") {
- builder = builder.whitelist_recursively(false);
+ if matches.is_present("no-recursive-allowlist") {
+ builder = builder.allowlist_recursively(false);
}
if matches.is_present("objc-extern-crate") {
@@ -809,21 +822,21 @@ where
builder = builder.generate_inline_functions(true);
}
- if let Some(whitelist) = matches.values_of("whitelist-function") {
- for regex in whitelist {
- builder = builder.whitelist_function(regex);
+ if let Some(allowlist) = matches.values_of("allowlist-function") {
+ for regex in allowlist {
+ builder = builder.allowlist_function(regex);
}
}
- if let Some(whitelist) = matches.values_of("whitelist-type") {
- for regex in whitelist {
- builder = builder.whitelist_type(regex);
+ if let Some(allowlist) = matches.values_of("allowlist-type") {
+ for regex in allowlist {
+ builder = builder.allowlist_type(regex);
}
}
- if let Some(whitelist) = matches.values_of("whitelist-var") {
- for regex in whitelist {
- builder = builder.whitelist_var(regex);
+ if let Some(allowlist) = matches.values_of("allowlist-var") {
+ for regex in allowlist {
+ builder = builder.allowlist_var(regex);
}
}
@@ -918,10 +931,18 @@ where
builder = builder.dynamic_library_name(dynamic_library_name);
}
+ if matches.is_present("dynamic-link-require-all") {
+ builder = builder.dynamic_link_require_all(true);
+ }
+
if matches.is_present("respect-cxx-access-specs") {
builder = builder.respect_cxx_access_specs(true);
}
+ if matches.is_present("translate-enum-integer-types") {
+ builder = builder.translate_enum_integer_types(true);
+ }
+
let verbose = matches.is_present("verbose");
Ok((builder, output, verbose))