From db7949f41bd88796a8c11ae070b4a35f6c8e9a64 Mon Sep 17 00:00:00 2001 From: "Joshua C. Randall" Date: Fri, 10 Dec 2021 00:44:58 +0000 Subject: [PATCH 1/4] derive Clone on Builder and all its fields --- Cargo.lock | 7 +++++++ Cargo.toml | 1 + src/callbacks.rs | 4 +++- src/clang.rs | 1 + src/deps.rs | 2 +- src/lib.rs | 6 +++--- src/regex_set.rs | 2 +- 7 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d79a408e7d..85032aa68f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,6 +40,7 @@ dependencies = [ "clang-sys", "clap", "diff", + "dyn-clone", "env_logger", "lazy_static", "lazycell", @@ -107,6 +108,12 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499" +[[package]] +name = "dyn-clone" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee2626afccd7561a06cf1367e2950c4718ea04565e20fb5029b6c7d8ad09abcf" + [[package]] name = "either" version = "1.6.1" diff --git a/Cargo.toml b/Cargo.toml index ba41a22dbb..83bd514682 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,6 +51,7 @@ cexpr = "0.6" # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 clap = { version = "2", optional = true } clang-sys = { version = "1", features = ["clang_6_0"] } +dyn-clone = "1" lazycell = "1" lazy_static = "1" peeking_take_while = "0.1.2" diff --git a/src/callbacks.rs b/src/callbacks.rs index 9b34544947..d7123c2ddd 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -25,7 +25,7 @@ impl Default for MacroParsingBehavior { /// A trait to allow configuring different kinds of types in different /// situations. -pub trait ParseCallbacks: fmt::Debug + UnwindSafe { +pub trait ParseCallbacks: fmt::Debug + UnwindSafe + dyn_clone::DynClone { /// This function will be run on every macro that is identified. fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { MacroParsingBehavior::Default @@ -104,3 +104,5 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe { vec![] } } + +dyn_clone::clone_trait_object!(ParseCallbacks); diff --git a/src/clang.rs b/src/clang.rs index 074d459ba7..e50028a30b 100644 --- a/src/clang.rs +++ b/src/clang.rs @@ -1687,6 +1687,7 @@ impl Drop for Diagnostic { } /// A file which has not been saved to disk. +#[derive(Clone)] pub struct UnsavedFile { x: CXUnsavedFile, /// The name of the unsaved file. Kept here to avoid leaving dangling pointers in diff --git a/src/deps.rs b/src/deps.rs index 479c396cbb..987225b28e 100644 --- a/src/deps.rs +++ b/src/deps.rs @@ -1,7 +1,7 @@ /// Generating build depfiles from parsed bindings. use std::{collections::BTreeSet, path::PathBuf}; -#[derive(Debug)] +#[derive(Clone, Debug)] pub(crate) struct DepfileSpec { pub output_module: String, pub depfile_path: PathBuf, diff --git a/src/lib.rs b/src/lib.rs index 560370b25a..8a9830a3cd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,7 +219,7 @@ impl Default for CodegenConfig { /// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to /// add additional arguments. For example, to build against a different sysroot a user could set /// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`. -#[derive(Debug, Default)] +#[derive(Clone, Debug, Default)] pub struct Builder { options: BindgenOptions, input_headers: Vec, @@ -1663,7 +1663,7 @@ impl Builder { } /// Configuration options for generated bindings. -#[derive(Debug)] +#[derive(Clone, Debug)] struct BindgenOptions { /// The set of types that have been blocklisted and should not appear /// anywhere in the generated code. @@ -2656,7 +2656,7 @@ fn get_target_dependent_env_var(var: &str) -> Option { /// .parse_callbacks(Box::new(bindgen::CargoCallbacks)) /// .generate(); /// ``` -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct CargoCallbacks; impl callbacks::ParseCallbacks for CargoCallbacks { diff --git a/src/regex_set.rs b/src/regex_set.rs index 127c001829..9262c4eeda 100644 --- a/src/regex_set.rs +++ b/src/regex_set.rs @@ -4,7 +4,7 @@ use regex::RegexSet as RxSet; use std::cell::Cell; /// A dynamic set of regular expressions. -#[derive(Debug, Default)] +#[derive(Clone, Debug, Default)] pub struct RegexSet { items: Vec, /// Whether any of the items in the set was ever matched. The length of this From 97fed5531db5ec2e55426f2fe2262e1c3de0d40c Mon Sep 17 00:00:00 2001 From: "Joshua C. Randall" Date: Fri, 10 Dec 2021 00:54:18 +0000 Subject: [PATCH 2/4] derive Clone for structs in ParseCallbacks tests --- tests/parse_callbacks/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/parse_callbacks/mod.rs b/tests/parse_callbacks/mod.rs index b94b54de0b..51348ac3cb 100644 --- a/tests/parse_callbacks/mod.rs +++ b/tests/parse_callbacks/mod.rs @@ -1,6 +1,6 @@ use bindgen::callbacks::*; -#[derive(Debug)] +#[derive(Clone, Debug)] struct EnumVariantRename; impl ParseCallbacks for EnumVariantRename { @@ -14,7 +14,7 @@ impl ParseCallbacks for EnumVariantRename { } } -#[derive(Debug)] +#[derive(Clone, Debug)] struct BlocklistedTypeImplementsTrait; impl ParseCallbacks for BlocklistedTypeImplementsTrait { From 576cd0fcfc3a1506506150cdbca6cba8fb58f85a Mon Sep 17 00:00:00 2001 From: "Joshua C. Randall" Date: Fri, 10 Dec 2021 01:17:21 +0000 Subject: [PATCH 3/4] fix rustfmt issue in src/callbacks.rs --- src/callbacks.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/callbacks.rs b/src/callbacks.rs index d7123c2ddd..5ecf737bb6 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -25,7 +25,9 @@ impl Default for MacroParsingBehavior { /// A trait to allow configuring different kinds of types in different /// situations. -pub trait ParseCallbacks: fmt::Debug + UnwindSafe + dyn_clone::DynClone { +pub trait ParseCallbacks: + fmt::Debug + UnwindSafe + dyn_clone::DynClone +{ /// This function will be run on every macro that is identified. fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { MacroParsingBehavior::Default From 001c6b5073364429a2bd8f48d356fc2ab6f79315 Mon Sep 17 00:00:00 2001 From: "Joshua C. Randall" Date: Fri, 10 Dec 2021 02:13:37 +0000 Subject: [PATCH 4/4] add `builder-clone` feature to gate whether `Builder` implements `Clone` (and requires `ParseCallbacks` implementors to implement `Clone` as well) --- Cargo.toml | 4 ++- src/callbacks.rs | 88 +++++++++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 6 ++-- 3 files changed, 94 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 83bd514682..c6d4c7a210 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ cexpr = "0.6" # This kinda sucks: https://github.com/rust-lang/cargo/issues/1982 clap = { version = "2", optional = true } clang-sys = { version = "1", features = ["clang_6_0"] } -dyn-clone = "1" +dyn-clone = { version = "1", optional = true } lazycell = "1" lazy_static = "1" peeking_take_while = "0.1.2" @@ -72,6 +72,8 @@ version = "0.4" [features] default = ["logging", "clap", "runtime", "which-rustfmt"] +# Implement the `Clone` trait on `bindgen::Builder` +builder-clone = ["dyn-clone"] logging = ["env_logger", "log"] static = ["clang-sys/static"] runtime = ["clang-sys/runtime"] diff --git a/src/callbacks.rs b/src/callbacks.rs index 5ecf737bb6..051c807cde 100644 --- a/src/callbacks.rs +++ b/src/callbacks.rs @@ -25,8 +25,93 @@ impl Default for MacroParsingBehavior { /// A trait to allow configuring different kinds of types in different /// situations. +#[cfg(not(feature = "builder-clone"))] +pub trait ParseCallbacks: fmt::Debug + UnwindSafe { + /// This function will be run on every macro that is identified. + fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { + MacroParsingBehavior::Default + } + + /// The integer kind an integer macro should have, given a name and the + /// value of that macro, or `None` if you want the default to be chosen. + fn int_macro(&self, _name: &str, _value: i64) -> Option { + None + } + + /// This will be run on every string macro. The callback cannot influence the further + /// treatment of the macro, but may use the value to generate additional code or configuration. + fn str_macro(&self, _name: &str, _value: &[u8]) {} + + /// This will be run on every function-like macro. The callback cannot + /// influence the further treatment of the macro, but may use the value to + /// generate additional code or configuration. + /// + /// The first parameter represents the name and argument list (including the + /// parentheses) of the function-like macro. The second parameter represents + /// the expansion of the macro as a sequence of tokens. + fn func_macro(&self, _name: &str, _value: &[&[u8]]) {} + + /// This function should return whether, given an enum variant + /// name, and value, this enum variant will forcibly be a constant. + fn enum_variant_behavior( + &self, + _enum_name: Option<&str>, + _original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + None + } + + /// Allows to rename an enum variant, replacing `_original_variant_name`. + fn enum_variant_name( + &self, + _enum_name: Option<&str>, + _original_variant_name: &str, + _variant_value: EnumVariantValue, + ) -> Option { + None + } + + /// Allows to rename an item, replacing `_original_item_name`. + fn item_name(&self, _original_item_name: &str) -> Option { + None + } + + /// 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 { + None + } + + /// Provide a list of custom derive attributes. + /// + /// If no additional attributes are wanted, this function should return an + /// empty `Vec`. + fn add_derives(&self, _name: &str) -> Vec { + vec![] + } +} + +/// The same trait as above, but clonable so that it can be included as a +/// field in Builder when the builder-clone feature is enabled such that +/// Builder implements Clone. +#[cfg(feature = "builder-clone")] pub trait ParseCallbacks: - fmt::Debug + UnwindSafe + dyn_clone::DynClone + fmt::Debug + UnwindSafe + dyn_clone::DynClone { /// This function will be run on every macro that is identified. fn will_parse_macro(&self, _name: &str) -> MacroParsingBehavior { @@ -107,4 +192,5 @@ pub trait ParseCallbacks: } } +#[cfg(feature = "builder-clone")] dyn_clone::clone_trait_object!(ParseCallbacks); diff --git a/src/lib.rs b/src/lib.rs index 8a9830a3cd..b52dd2c2fb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -219,7 +219,8 @@ impl Default for CodegenConfig { /// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to /// add additional arguments. For example, to build against a different sysroot a user could set /// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`. -#[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "builder-clone", derive(Clone))] +#[derive(Debug, Default)] pub struct Builder { options: BindgenOptions, input_headers: Vec, @@ -1663,7 +1664,8 @@ impl Builder { } /// Configuration options for generated bindings. -#[derive(Clone, Debug)] +#[cfg_attr(feature = "builder-clone", derive(Clone))] +#[derive(Debug)] struct BindgenOptions { /// The set of types that have been blocklisted and should not appear /// anywhere in the generated code.