Update to 0.64.0 am: 66de3445e4 am: 188f148791 am: 25cad4c67f am: c30c4f6530

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/bindgen-cli/+/2440232

Change-Id: I1b06d1c2cb20322fbe7fb1086f69f71dee25709c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 7f618cd..1af6373 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,8 +1,6 @@
 // This file is generated by cargo2android.py --config cargo2android.json.
 // Do not modify this file as changes will be overridden on upgrade.
 
-
-
 package {
     default_applicable_licenses: ["external_rust_crates_bindgen-cli_license"],
 }
@@ -24,7 +22,7 @@
     name: "bindgen",
     crate_name: "bindgen",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.63.0",
+    cargo_pkg_version: "0.64.0",
     srcs: ["main.rs"],
     edition: "2018",
     features: [
diff --git a/Cargo.lock b/Cargo.lock
index 5fcda0c..c09ce78 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -17,22 +17,16 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
 dependencies = [
- "hermit-abi",
+ "hermit-abi 0.1.19",
  "libc",
  "winapi",
 ]
 
 [[package]]
-name = "autocfg"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
-
-[[package]]
 name = "bindgen"
-version = "0.63.0"
+version = "0.64.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885"
+checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
 dependencies = [
  "bitflags",
  "cexpr",
@@ -52,7 +46,7 @@
 
 [[package]]
 name = "bindgen-cli"
-version = "0.63.0"
+version = "0.64.0"
 dependencies = [
  "bindgen",
  "clap",
@@ -68,6 +62,12 @@
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
+name = "cc"
+version = "1.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+
+[[package]]
 name = "cexpr"
 version = "0.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -95,33 +95,46 @@
 
 [[package]]
 name = "clap"
-version = "3.2.23"
+version = "4.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5"
+checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
 dependencies = [
- "atty",
  "bitflags",
+ "clap_derive",
  "clap_lex",
- "indexmap",
+ "is-terminal",
+ "once_cell",
  "strsim",
  "termcolor",
- "textwrap",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
 ]
 
 [[package]]
 name = "clap_lex"
-version = "0.2.4"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
+checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
 dependencies = [
  "os_str_bytes",
 ]
 
 [[package]]
 name = "either"
-version = "1.8.0"
+version = "1.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
+checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
 
 [[package]]
 name = "env_logger"
@@ -137,16 +150,37 @@
 ]
 
 [[package]]
-name = "glob"
-version = "0.3.0"
+name = "errno"
+version = "0.2.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
+checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
+dependencies = [
+ "errno-dragonfly",
+ "libc",
+ "winapi",
+]
 
 [[package]]
-name = "hashbrown"
-version = "0.12.3"
+name = "errno-dragonfly"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
 
 [[package]]
 name = "hermit-abi"
@@ -158,19 +192,37 @@
 ]
 
 [[package]]
+name = "hermit-abi"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "856b5cb0902c2b6d65d5fd97dfa30f9b70c7538e770b98eab5ed52d8db923e01"
+
+[[package]]
 name = "humantime"
 version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
 
 [[package]]
-name = "indexmap"
-version = "1.9.2"
+name = "io-lifetimes"
+version = "1.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
+checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3"
 dependencies = [
- "autocfg",
- "hashbrown",
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "is-terminal"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef"
+dependencies = [
+ "hermit-abi 0.3.0",
+ "io-lifetimes",
+ "rustix",
+ "windows-sys",
 ]
 
 [[package]]
@@ -187,9 +239,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.137"
+version = "0.2.139"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
 
 [[package]]
 name = "libloading"
@@ -202,6 +254,12 @@
 ]
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4"
+
+[[package]]
 name = "log"
 version = "0.4.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -224,9 +282,9 @@
 
 [[package]]
 name = "nom"
-version = "7.1.1"
+version = "7.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
 dependencies = [
  "memchr",
  "minimal-lexical",
@@ -234,9 +292,9 @@
 
 [[package]]
 name = "once_cell"
-version = "1.16.0"
+version = "1.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
 
 [[package]]
 name = "os_str_bytes"
@@ -251,28 +309,52 @@
 checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 
 [[package]]
-name = "proc-macro2"
-version = "1.0.47"
+name = "proc-macro-error"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.51"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.21"
+version = "1.0.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
 name = "regex"
-version = "1.7.0"
+version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
+checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -292,6 +374,20 @@
 checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
 
 [[package]]
+name = "rustix"
+version = "0.36.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644"
+dependencies = [
+ "bitflags",
+ "errno",
+ "io-lifetimes",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
 name = "shlex"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -305,9 +401,9 @@
 
 [[package]]
 name = "syn"
-version = "1.0.103"
+version = "1.0.107"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
+checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -316,30 +412,30 @@
 
 [[package]]
 name = "termcolor"
-version = "1.1.3"
+version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
 dependencies = [
  "winapi-util",
 ]
 
 [[package]]
-name = "textwrap"
-version = "0.16.0"
+name = "unicode-ident"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
+checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
 
 [[package]]
-name = "unicode-ident"
-version = "1.0.5"
+name = "version_check"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "which"
-version = "4.3.0"
+version = "4.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1c831fbbee9e129a8cf93e7747a82da9d95ba8e16621cae60ec2cdc849bacb7b"
+checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
 dependencies = [
  "either",
  "libc",
@@ -376,3 +472,69 @@
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.45.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
diff --git a/Cargo.toml b/Cargo.toml
index 2e9ccad..19624ef 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,9 @@
 
 [package]
 edition = "2018"
-rust-version = "1.57.0"
+rust-version = "1.60.0"
 name = "bindgen-cli"
-version = "0.63.0"
+version = "0.64.0"
 authors = ["The rust-bindgen project contributors"]
 description = "Automatically generates Rust FFI bindings to C and C++ libraries."
 homepage = "https://rust-lang.github.io/rust-bindgen/"
@@ -36,10 +36,15 @@
 path = "main.rs"
 
 [dependencies.bindgen]
-version = "=0.63.0"
+version = "=0.64.0"
+features = [
+    "cli",
+    "experimental",
+]
 
 [dependencies.clap]
-version = "3"
+version = "4"
+features = ["derive"]
 
 [dependencies.env_logger]
 version = "0.9.0"
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index a8436a4..1399456 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -11,19 +11,19 @@
 repository = "https://github.com/rust-lang/rust-bindgen"
 documentation = "https://docs.rs/bindgen"
 homepage = "https://rust-lang.github.io/rust-bindgen/"
-version = "0.63.0"
+version = "0.64.0"
 edition = "2018"
 # If you change this, also update README.md and msrv in .github/workflows/bindgen.yml
-rust-version = "1.57.0"
+rust-version = "1.60.0"
 
 [[bin]]
 path = "main.rs"
 name = "bindgen"
 
 [dependencies]
-bindgen = { path = "../bindgen", version = "=0.63.0" }
+bindgen = { path = "../bindgen", version = "=0.64.0", features = ["cli", "experimental"] }
 shlex = "1"
-clap = "4"
+clap = { version = "4", features = ["derive"] }
 env_logger = { version = "0.9.0", optional = true }
 log = { version = "0.4", optional = true }
 
diff --git a/METADATA b/METADATA
index 7e0568e..b07a3c8 100644
--- a/METADATA
+++ b/METADATA
@@ -7,13 +7,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/bindgen-cli/bindgen-cli-0.63.0.crate"
+    value: "https://static.crates.io/crates/bindgen-cli/bindgen-cli-0.64.0.crate"
   }
-  version: "0.63.0"
+  version: "0.64.0"
   license_type: NOTICE
   last_upgrade_date {
     year: 2023
-    month: 1
-    day: 2
+    month: 2
+    day: 16
   }
 }
diff --git a/README.md b/README.md
index c78f00d..67f227c 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@
 
 ## MSRV
 
-The minimum supported Rust version is **1.57.0**.
+The minimum supported Rust version is **1.60.0**.
 
 No MSRV bump policy has been established yet, so MSRV may increase in any release.
 
diff --git a/options.rs b/options.rs
index f04d726..458c7ba 100644
--- a/options.rs
+++ b/options.rs
@@ -1,13 +1,378 @@
+use bindgen::callbacks::TypeKind;
 use bindgen::{
     builder, AliasVariation, Builder, CodegenConfig, EnumVariation,
-    MacroTypeVariation, NonCopyUnionStyle, RustTarget,
+    MacroTypeVariation, NonCopyUnionStyle, RegexSet, RustTarget,
     DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS,
 };
-use clap::{builder::PossibleValuesParser, Arg, ArgAction, Command};
+use clap::Parser;
 use std::fs::File;
 use std::io::{self, Error, ErrorKind};
 use std::path::PathBuf;
-use std::str::FromStr;
+
+fn rust_target_help() -> String {
+    format!(
+        "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {:?}.",
+        RUST_TARGET_STRINGS,
+        String::from(RustTarget::default())
+    )
+}
+
+fn parse_codegen_config(what_to_generate: &str) -> io::Result<CodegenConfig> {
+    let mut config = CodegenConfig::empty();
+    for what in what_to_generate.split(',') {
+        match what {
+            "functions" => config.insert(CodegenConfig::FUNCTIONS),
+            "types" => config.insert(CodegenConfig::TYPES),
+            "vars" => config.insert(CodegenConfig::VARS),
+            "methods" => config.insert(CodegenConfig::METHODS),
+            "constructors" => config.insert(CodegenConfig::CONSTRUCTORS),
+            "destructors" => config.insert(CodegenConfig::DESTRUCTORS),
+            otherwise => {
+                return Err(Error::new(
+                    ErrorKind::Other,
+                    format!("Unknown generate item: {}", otherwise),
+                ));
+            }
+        }
+    }
+
+    Ok(config)
+}
+
+#[derive(Parser, Debug)]
+#[clap(
+    about = "Generates Rust bindings from C/C++ headers.",
+    override_usage = "bindgen [FLAGS] [OPTIONS] [HEADER] -- [CLANG_ARGS]...",
+    trailing_var_arg = true
+)]
+struct BindgenCommand {
+    /// C or C++ header file.
+    header: Option<String>,
+    /// Path to write depfile to.
+    #[arg(long)]
+    depfile: Option<String>,
+    /// The default style of code used to generate enums.
+    #[arg(long, value_name = "VARIANT")]
+    default_enum_style: Option<EnumVariation>,
+    /// Mark any enum whose name matches <REGEX> as a set of bitfield flags.
+    #[arg(long, value_name = "REGEX")]
+    bitfield_enum: Vec<String>,
+    /// Mark any enum whose name matches <REGEX> as a newtype.
+    #[arg(long, value_name = "REGEX")]
+    newtype_enum: Vec<String>,
+    /// Mark any enum whose name matches <REGEX> as a global newtype.
+    #[arg(long, value_name = "REGEX")]
+    newtype_global_enum: Vec<String>,
+    /// Mark any enum whose name matches <REGEX> as a Rust enum.
+    #[arg(long, value_name = "REGEX")]
+    rustified_enum: Vec<String>,
+    /// Mark any enum whose name matches <REGEX> as a series of constants.
+    #[arg(long, value_name = "REGEX")]
+    constified_enum: Vec<String>,
+    /// Mark any enum whose name matches <regex> as a module of constants.
+    #[arg(long, value_name = "REGEX")]
+    constified_enum_module: Vec<String>,
+    /// The default signed/unsigned type for C macro constants.
+    #[arg(long, value_name = "VARIANT")]
+    default_macro_constant_type: Option<MacroTypeVariation>,
+    /// The default style of code used to generate typedefs.
+    #[arg(long, value_name = "VARIANT")]
+    default_alias_style: Option<AliasVariation>,
+    /// Mark any typedef alias whose name matches <REGEX> to use normal type aliasing.
+    #[arg(long, value_name = "REGEX")]
+    normal_alias: Vec<String>,
+    /// Mark any typedef alias whose name matches <REGEX> to have a new type generated for it.
+    #[arg(long, value_name = "REGEX")]
+    new_type_alias: Vec<String>,
+    /// Mark any typedef alias whose name matches <REGEX> to have a new type with Deref and DerefMut to the inner type.
+    #[arg(long, value_name = "REGEX")]
+    new_type_alias_deref: Vec<String>,
+    /// The default style of code used to generate unions with non-Copy members. Note that ManuallyDrop was first stabilized in Rust 1.20.0.
+    #[arg(long, value_name = "STYLE")]
+    default_non_copy_union_style: Option<NonCopyUnionStyle>,
+    /// Mark any union whose name matches <REGEX> and who has a non-Copy member to use a bindgen-generated wrapper for fields.
+    #[arg(long, value_name = "REGEX")]
+    bindgen_wrapper_union: Vec<String>,
+    /// Mark any union whose name matches <REGEX> and who has a non-Copy member to use ManuallyDrop (stabilized in Rust 1.20.0) for fields.
+    #[arg(long, value_name = "REGEX")]
+    manually_drop_union: Vec<String>,
+    /// Mark <TYPE> as hidden.
+    #[arg(long, value_name = "TYPE")]
+    blocklist_type: Vec<String>,
+    /// Mark <FUNCTION> as hidden.
+    #[arg(long, value_name = "FUNCTION")]
+    blocklist_function: Vec<String>,
+    /// Mark <ITEM> as hidden.
+    #[arg(long, value_name = "ITEM")]
+    blocklist_item: Vec<String>,
+    /// Mark <FILE> as hidden.
+    #[arg(long, value_name = "FILE")]
+    blocklist_file: Vec<String>,
+    /// Avoid generating layout tests for any type.
+    #[arg(long)]
+    no_layout_tests: bool,
+    /// Avoid deriving Copy on any type.
+    #[arg(long)]
+    no_derive_copy: bool,
+    /// Avoid deriving Debug on any type.
+    #[arg(long)]
+    no_derive_debug: bool,
+    /// Avoid deriving Default on any type.
+    #[arg(long, hide = true)]
+    no_derive_default: bool,
+    /// Create a Debug implementation if it cannot be derived automatically.
+    #[arg(long)]
+    impl_debug: bool,
+    /// Create a PartialEq implementation if it cannot be derived automatically.
+    #[arg(long)]
+    impl_partialeq: bool,
+    /// Derive Default on any type.
+    #[arg(long)]
+    with_derive_default: bool,
+    /// Derive Hash on any type.docstring
+    #[arg(long)]
+    with_derive_hash: bool,
+    /// Derive PartialEq on any type.
+    #[arg(long)]
+    with_derive_partialeq: bool,
+    /// Derive PartialOrd on any type.
+    #[arg(long)]
+    with_derive_partialord: bool,
+    /// Derive Eq on any type.
+    #[arg(long)]
+    with_derive_eq: bool,
+    /// Derive Ord on any type.
+    #[arg(long)]
+    with_derive_ord: bool,
+    /// Avoid including doc comments in the output, see: https://github.com/rust-lang/rust-bindgen/issues/426
+    #[arg(long)]
+    no_doc_comments: bool,
+    /// Disable allowlisting types recursively. This will cause bindgen to emit Rust code that won't compile! See the `bindgen::Builder::allowlist_recursively` method's documentation for details.
+    #[arg(long)]
+    no_recursive_allowlist: bool,
+    /// Use extern crate instead of use for objc.
+    #[arg(long)]
+    objc_extern_crate: bool,
+    /// Generate block signatures instead of void pointers.
+    #[arg(long)]
+    generate_block: bool,
+    /// Use extern crate instead of use for block.
+    #[arg(long)]
+    block_extern_crate: bool,
+    /// Do not trust the libclang-provided mangling
+    #[arg(long)]
+    distrust_clang_mangling: bool,
+    /// Output bindings for builtin definitions, e.g. __builtin_va_list.
+    #[arg(long)]
+    builtins: bool,
+    /// Use the given prefix before raw types instead of ::std::os::raw.
+    #[arg(long, value_name = "PREFIX")]
+    ctypes_prefix: Option<String>,
+    /// Use the given prefix for anonymous fields.
+    #[arg(long, default_value = DEFAULT_ANON_FIELDS_PREFIX, value_name = "PREFIX")]
+    anon_fields_prefix: String,
+    /// Time the different bindgen phases and print to stderr
+    #[arg(long)]
+    time_phases: bool,
+    /// Output the Clang AST for debugging purposes.
+    #[arg(long)]
+    emit_clang_ast: bool,
+    /// Output our internal IR for debugging purposes.
+    #[arg(long)]
+    emit_ir: bool,
+    /// Dump graphviz dot file.
+    #[arg(long, value_name = "PATH")]
+    emit_ir_graphviz: Option<String>,
+    /// Enable support for C++ namespaces.
+    #[arg(long)]
+    enable_cxx_namespaces: bool,
+    /// Disable namespacing via mangling, causing bindgen to generate names like `Baz` instead of `foo_bar_Baz` for an input name `foo::bar::Baz`.
+    #[arg(long)]
+    disable_name_namespacing: bool,
+    /// Disable nested struct naming, causing bindgen to generate names like `bar` instead of `foo_bar` for a nested definition `struct foo { struct bar { } b; };`.
+    #[arg(long)]
+    disable_nested_struct_naming: bool,
+    /// Disable support for native Rust unions.
+    #[arg(long)]
+    disable_untagged_union: bool,
+    /// Suppress insertion of bindgen's version identifier into generated bindings.
+    #[arg(long)]
+    disable_header_comment: bool,
+    /// Do not generate bindings for functions or methods. This is useful when you only care about struct layouts.docstring
+    #[arg(long)]
+    ignore_functions: bool,
+    /// Generate only given items, split by commas. Valid values are `functions`,`types`, `vars`, `methods`, `constructors` and `destructors`.
+    #[arg(long, value_parser = parse_codegen_config)]
+    generate: Option<CodegenConfig>,
+    /// Do not generate bindings for methods.
+    #[arg(long)]
+    ignore_methods: bool,
+    /// Do not automatically convert floats to f32/f64.
+    #[arg(long)]
+    no_convert_floats: bool,
+    /// Do not prepend the enum name to constant or newtype variants.
+    #[arg(long)]
+    no_prepend_enum_name: bool,
+    /// Do not try to detect default include paths
+    #[arg(long)]
+    no_include_path_detection: bool,
+    /// Try to fit macro constants into types smaller than u32/i32
+    #[arg(long)]
+    fit_macro_constant_types: bool,
+    /// Mark <TYPE> as opaque.
+    #[arg(long, value_name = "TYPE")]
+    opaque_type: Vec<String>,
+    ///  Write Rust bindings to <OUTPUT>.
+    #[arg(long, short, value_name = "OUTPUT")]
+    output: Option<String>,
+    /// Add a raw line of Rust code at the beginning of output.
+    #[arg(long)]
+    raw_line: Vec<String>,
+    /// Add a raw line of Rust code to a given module.
+    #[arg(long, number_of_values = 2, value_names = ["MODULE-NAME", "RAW-LINE"])]
+    module_raw_line: Vec<String>,
+    #[arg(long, help = rust_target_help())]
+    rust_target: Option<RustTarget>,
+    /// Use types from Rust core instead of std.
+    #[arg(long)]
+    use_core: bool,
+    /// Conservatively generate inline namespaces to avoid name conflicts.
+    #[arg(long)]
+    conservative_inline_namespaces: bool,
+    /// MSVC C++ ABI mangling. DEPRECATED: Has no effect.
+    #[arg(long)]
+    use_msvc_mangling: bool,
+    /// Allowlist all the free-standing functions matching <REGEX>. Other non-allowlisted functions will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_function: Vec<String>,
+    /// Generate inline functions.
+    #[arg(long)]
+    generate_inline_functions: bool,
+    /// Only generate types matching <REGEX>. Other non-allowlisted types will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_type: Vec<String>,
+    /// Allowlist all the free-standing variables matching <REGEX>. Other non-allowlisted variables will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_var: Vec<String>,
+    /// Allowlist all contents of <PATH>.
+    #[arg(long, value_name = "PATH")]
+    allowlist_file: Vec<String>,
+    /// Print verbose error messages.
+    #[arg(long)]
+    verbose: bool,
+    /// Preprocess and dump the input header files to disk. Useful when debugging bindgen, using C-Reduce, or when filing issues. The resulting file will be named something like `__bindgen.i` or `__bindgen.ii`.
+    #[arg(long)]
+    dump_preprocessed_input: bool,
+    /// Do not record matching items in the regex sets. This disables reporting of unused items.
+    #[arg(long)]
+    no_record_matches: bool,
+    /// Ignored - this is enabled by default.
+    #[arg(long = "size_t-is-usize")]
+    size_t_is_usize: bool,
+    /// Do not bind size_t as usize (useful on platforms where those types are incompatible).
+    #[arg(long = "no-size_t-is-usize")]
+    no_size_t_is_usize: bool,
+    /// Do not format the generated bindings with rustfmt.
+    #[arg(long)]
+    no_rustfmt_bindings: bool,
+    /// Format the generated bindings with rustfmt. DEPRECATED: --rustfmt-bindings is now enabled by default. Disable with --no-rustfmt-bindings.
+    #[arg(long)]
+    rustfmt_bindings: bool,
+    /// The absolute path to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter is incompatible with --no-rustfmt-bindings.
+    #[arg(long, value_name = "PATH")]
+    rustfmt_configuration_file: Option<String>,
+    /// Avoid deriving PartialEq for types matching <REGEX>.
+    #[arg(long, value_name = "REGEX")]
+    no_partialeq: Vec<String>,
+    /// Avoid deriving Copy for types matching <REGEX>.
+    #[arg(long, value_name = "REGEX")]
+    no_copy: Vec<String>,
+    /// Avoid deriving Debug for types matching <REGEX>.
+    #[arg(long, value_name = "REGEX")]
+    no_debug: Vec<String>,
+    /// Avoid deriving/implementing Default for types matching <REGEX>.
+    #[arg(long, value_name = "REGEX")]
+    no_default: Vec<String>,
+    /// Avoid deriving Hash for types matching <REGEX>.
+    #[arg(long, value_name = "REGEX")]
+    no_hash: Vec<String>,
+    /// Add #[must_use] annotation to types matching <REGEX>.
+    #[arg(long, value_name = "REGEX")]
+    must_use_type: Vec<String>,
+    /// Enables detecting unexposed attributes in functions (slow). Used to generate #[must_use] annotations.
+    #[arg(long)]
+    enable_function_attribute_detection: bool,
+    /// Use `*const [T; size]` instead of `*const T` for C arrays
+    #[arg(long)]
+    use_array_pointers_in_arguments: bool,
+    /// The name to be used in a #[link(wasm_import_module = ...)] statement
+    #[arg(long, value_name = "NAME")]
+    wasm_import_module_name: Option<String>,
+    /// Use dynamic loading mode with the given library name.
+    #[arg(long, value_name = "NAME")]
+    dynamic_loading: Option<String>,
+    /// Require successful linkage to all functions in the library.
+    #[arg(long)]
+    dynamic_link_require_all: bool,
+    /// Makes generated bindings `pub` only for items if the items are publically accessible in C++.
+    #[arg(long)]
+    respect_cxx_access_specs: bool,
+    /// Always translate enum integer types to native Rust integer types.
+    #[arg(long)]
+    translate_enum_integer_types: bool,
+    /// Generate types with C style naming.
+    #[arg(long)]
+    c_naming: bool,
+    /// Always output explicit padding fields.
+    #[arg(long)]
+    explicit_padding: bool,
+    /// Enables generation of vtable functions.
+    #[arg(long)]
+    vtable_generation: bool,
+    /// Enables sorting of code generation in a predefined manner.
+    #[arg(long)]
+    sort_semantically: bool,
+    /// Deduplicates extern blocks.
+    #[arg(long)]
+    merge_extern_blocks: bool,
+    /// Overrides the ABI of functions matching <regex>. The <OVERRIDE> value must be of the shape <REGEX>=<ABI> where <ABI> can be one of C, stdcall, fastcall, thiscall, aapcs, win64 or C-unwind.
+    #[arg(long, value_name = "OVERRIDE")]
+    override_abi: Vec<String>,
+    /// Wrap unsafe operations in unsafe blocks.
+    #[arg(long)]
+    wrap_unsafe_ops: bool,
+    /// Derive custom traits on any kind of type. The <CUSTOM> value must be of the shape <REGEX>=<DERIVE> where <DERIVE> is a coma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM")]
+    with_derive_custom: Vec<String>,
+    /// Derive custom traits on a `struct`. The <CUSTOM> value must be of the shape <REGEX>=<DERIVE> where <DERIVE> is a coma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM")]
+    with_derive_custom_struct: Vec<String>,
+    /// Derive custom traits on an `enum. The <CUSTOM> value must be of the shape <REGEX>=<DERIVE> where <DERIVE> is a coma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM")]
+    with_derive_custom_enum: Vec<String>,
+    /// Derive custom traits on a `union`. The <CUSTOM> value must be of the shape <REGEX>=<DERIVE> where <DERIVE> is a coma-separated list of derive macros.
+    #[arg(long, value_name = "CUSTOM")]
+    with_derive_custom_union: Vec<String>,
+    /// Generate wrappers for `static` and `static inline` functions.
+    #[arg(long, requires = "experimental")]
+    wrap_static_fns: bool,
+    /// Sets the path for the source file that must be created due to the presence of `static` and
+    /// `static inline` functions.
+    #[arg(long, requires = "experimental", value_name = "PATH")]
+    wrap_static_fns_path: Option<PathBuf>,
+    /// Sets the suffix added to the extern wrapper functions generated for `static` and `static
+    /// inline` functions.
+    #[arg(long, requires = "experimental", value_name = "SUFFIX")]
+    wrap_static_fns_suffix: Option<String>,
+    /// Enables experimental features.
+    #[arg(long)]
+    experimental: bool,
+    /// Prints the version, and exits
+    #[arg(short = 'V', long)]
+    version: bool,
+    /// Arguments to be passed straight through to clang.
+    clang_args: Vec<String>,
+}
 
 /// Construct a new [`Builder`](./struct.Builder.html) from command line flags.
 pub fn builder_from_flags<I>(
@@ -16,615 +381,121 @@
 where
     I: Iterator<Item = String>,
 {
-    let rust_target_help = format!(
-        "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {:?}.",
-        RUST_TARGET_STRINGS,
-        String::from(RustTarget::default())
-    );
+    let command = BindgenCommand::parse_from(args);
 
-    let matches = Command::new("bindgen")
-        .about("Generates Rust bindings from C/C++ headers.")
-        .disable_version_flag(true)
-        .override_usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...")
-        .args(&[
-            Arg::new("header")
-                .help("C or C++ header file")
-                .required_unless_present("V"),
-            Arg::new("depfile")
-                .long("depfile")
-                .action(ArgAction::Set)
-                .help("Path to write depfile to"),
-            Arg::new("default-enum-style")
-                .long("default-enum-style")
-                .help("The default style of code used to generate enums.")
-                .value_name("variant")
-                .default_value("consts")
-                .value_parser(PossibleValuesParser::new([
-                    "consts",
-                    "moduleconsts",
-                    "bitfield",
-                    "newtype",
-                    "rust",
-                    "rust_non_exhaustive",
-                ]))
-                .action(ArgAction::Set),
-            Arg::new("bitfield-enum")
-                .long("bitfield-enum")
-                .help(
-                    "Mark any enum whose name matches <regex> as a set of \
-                     bitfield flags.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("newtype-enum")
-                .long("newtype-enum")
-                .help("Mark any enum whose name matches <regex> as a newtype.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("newtype-global-enum")
-                .long("newtype-global-enum")
-                .help("Mark any enum whose name matches <regex> as a global newtype.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("rustified-enum")
-                .long("rustified-enum")
-                .help("Mark any enum whose name matches <regex> as a Rust enum.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("constified-enum")
-                .long("constified-enum")
-                .help(
-                    "Mark any enum whose name matches <regex> as a series of \
-                     constants.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("constified-enum-module")
-                .long("constified-enum-module")
-                .help(
-                    "Mark any enum whose name matches <regex> as a module of \
-                     constants.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("default-macro-constant-type")
-                .long("default-macro-constant-type")
-                .help("The default signed/unsigned type for C macro constants.")
-                .value_name("variant")
-                .default_value("unsigned")
-                .value_parser(PossibleValuesParser::new(["signed", "unsigned"]))
-                .action(ArgAction::Set),
-            Arg::new("default-alias-style")
-                .long("default-alias-style")
-                .help("The default style of code used to generate typedefs.")
-                .value_name("variant")
-                .default_value("type_alias")
-                .value_parser(PossibleValuesParser::new([
-                    "type_alias",
-                    "new_type",
-                    "new_type_deref",
-                ]))
-                .action(ArgAction::Set),
-            Arg::new("normal-alias")
-                .long("normal-alias")
-                .help(
-                    "Mark any typedef alias whose name matches <regex> to use \
-                     normal type aliasing.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-             Arg::new("new-type-alias")
-                .long("new-type-alias")
-                .help(
-                    "Mark any typedef alias whose name matches <regex> to have \
-                     a new type generated for it.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-             Arg::new("new-type-alias-deref")
-                .long("new-type-alias-deref")
-                .help(
-                    "Mark any typedef alias whose name matches <regex> to have \
-                     a new type with Deref and DerefMut to the inner type.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("default-non-copy-union-style")
-                .long("default-non-copy-union-style")
-                .help(
-                    "The default style of code used to generate unions with \
-                     non-Copy members. Note that ManuallyDrop was first \
-                     stabilized in Rust 1.20.0.",
-                )
-                .value_name("style")
-                .default_value("bindgen_wrapper")
-                .value_parser(PossibleValuesParser::new([
-                    "bindgen_wrapper",
-                    "manually_drop",
-                ]))
-                .action(ArgAction::Set),
-            Arg::new("bindgen-wrapper-union")
-                .long("bindgen-wrapper-union")
-                .help(
-                    "Mark any union whose name matches <regex> and who has a \
-                     non-Copy member to use a bindgen-generated wrapper for \
-                     fields.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("manually-drop-union")
-                .long("manually-drop-union")
-                .help(
-                    "Mark any union whose name matches <regex> and who has a \
-                     non-Copy member to use ManuallyDrop (stabilized in Rust \
-                     1.20.0) for fields.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("blocklist-type")
-                .long("blocklist-type")
-                .help("Mark <type> as hidden.")
-                .value_name("type")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("blocklist-function")
-                .long("blocklist-function")
-                .help("Mark <function> as hidden.")
-                .value_name("function")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("blocklist-item")
-                .long("blocklist-item")
-                .help("Mark <item> as hidden.")
-                .value_name("item")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("blocklist-file")
-                .long("blocklist-file")
-                .help("Mark all contents of <path> as hidden.")
-                .value_name("path")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("no-layout-tests")
-                .long("no-layout-tests")
-                .help("Avoid generating layout tests for any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-derive-copy")
-                .long("no-derive-copy")
-                .help("Avoid deriving Copy on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-derive-debug")
-                .long("no-derive-debug")
-                .help("Avoid deriving Debug on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-derive-default")
-                .long("no-derive-default")
-                .hide(true)
-                .help("Avoid deriving Default on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("impl-debug").long("impl-debug").help(
-                "Create Debug implementation, if it can not be derived \
-                 automatically.",
-            )
-            .action(ArgAction::SetTrue),
-            Arg::new("impl-partialeq")
-                .long("impl-partialeq")
-                .help(
-                    "Create PartialEq implementation, if it can not be derived \
-                     automatically.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("with-derive-default")
-                .long("with-derive-default")
-                .help("Derive Default on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("with-derive-hash")
-                .long("with-derive-hash")
-                .help("Derive hash on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("with-derive-partialeq")
-                .long("with-derive-partialeq")
-                .help("Derive partialeq on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("with-derive-partialord")
-                .long("with-derive-partialord")
-                .help("Derive partialord on any type.")
-                .action(ArgAction::SetTrue),
-            Arg::new("with-derive-eq")
-                .long("with-derive-eq")
-                .help(
-                    "Derive eq on any type. Enable this option also \
-                     enables --with-derive-partialeq",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("with-derive-ord")
-                .long("with-derive-ord")
-                .help(
-                    "Derive ord on any type. Enable this option also \
-                     enables --with-derive-partialord",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("no-doc-comments")
-                .long("no-doc-comments")
-                .help(
-                    "Avoid including doc comments in the output, see: \
-                     https://github.com/rust-lang/rust-bindgen/issues/426",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("no-recursive-allowlist")
-                .long("no-recursive-allowlist")
-                .help(
-                    "Disable allowlisting types recursively. This will cause \
-                     bindgen to emit Rust code that won't compile! See the \
-                     `bindgen::Builder::allowlist_recursively` method's \
-                     documentation for details.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("objc-extern-crate")
-                .long("objc-extern-crate")
-                .help("Use extern crate instead of use for objc.")
-                .action(ArgAction::SetTrue),
-            Arg::new("generate-block")
-                .long("generate-block")
-                .help("Generate block signatures instead of void pointers.")
-                .action(ArgAction::SetTrue),
-            Arg::new("block-extern-crate")
-                .long("block-extern-crate")
-                .help("Use extern crate instead of use for block.")
-                .action(ArgAction::SetTrue),
-            Arg::new("distrust-clang-mangling")
-                .long("distrust-clang-mangling")
-                .help("Do not trust the libclang-provided mangling")
-                .action(ArgAction::SetTrue),
-            Arg::new("builtins").long("builtins").help(
-                "Output bindings for builtin definitions, e.g. \
-                 __builtin_va_list.",
-            )
-            .action(ArgAction::SetTrue),
-            Arg::new("ctypes-prefix")
-                .long("ctypes-prefix")
-                .help(
-                    "Use the given prefix before raw types instead of \
-                     ::std::os::raw.",
-                )
-                .value_name("prefix"),
-            Arg::new("anon-fields-prefix")
-                .long("anon-fields-prefix")
-                .help("Use the given prefix for the anon fields.")
-                .value_name("prefix")
-                .default_value(DEFAULT_ANON_FIELDS_PREFIX),
-            Arg::new("time-phases")
-                .long("time-phases")
-                .help("Time the different bindgen phases and print to stderr")
-                .action(ArgAction::SetTrue),
-            // All positional arguments after the end of options marker, `--`
-            Arg::new("clang-args").last(true).action(ArgAction::Append),
-            Arg::new("emit-clang-ast")
-                .long("emit-clang-ast")
-                .help("Output the Clang AST for debugging purposes.")
-                .action(ArgAction::SetTrue),
-            Arg::new("emit-ir")
-                .long("emit-ir")
-                .help("Output our internal IR for debugging purposes.")
-                .action(ArgAction::SetTrue),
-            Arg::new("emit-ir-graphviz")
-                .long("emit-ir-graphviz")
-                .help("Dump graphviz dot file.")
-                .value_name("path"),
-            Arg::new("enable-cxx-namespaces")
-                .long("enable-cxx-namespaces")
-                .help("Enable support for C++ namespaces.")
-                .action(ArgAction::SetTrue),
-            Arg::new("disable-name-namespacing")
-                .long("disable-name-namespacing")
-                .help(
-                    "Disable namespacing via mangling, causing bindgen to \
-                     generate names like \"Baz\" instead of \"foo_bar_Baz\" \
-                     for an input name \"foo::bar::Baz\".",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("disable-nested-struct-naming")
-                .long("disable-nested-struct-naming")
-                .help(
-                    "Disable nested struct naming, causing bindgen to generate \
-                     names like \"bar\" instead of \"foo_bar\" for a nested \
-                     definition \"struct foo { struct bar { } b; };\"."
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("disable-untagged-union")
-                .long("disable-untagged-union")
-                .help(
-                    "Disable support for native Rust unions.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("disable-header-comment")
-                .long("disable-header-comment")
-                .help("Suppress insertion of bindgen's version identifier into generated bindings.")
-                .action(ArgAction::SetTrue),
-            Arg::new("ignore-functions")
-                .long("ignore-functions")
-                .help(
-                    "Do not generate bindings for functions or methods. This \
-                     is useful when you only care about struct layouts.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("generate")
-                .long("generate")
-                .help(
-                    "Generate only given items, split by commas. \
-                     Valid values are \"functions\",\"types\", \"vars\", \
-                     \"methods\", \"constructors\" and \"destructors\".",
-                )
-                .action(ArgAction::Set),
-            Arg::new("ignore-methods")
-                .long("ignore-methods")
-                .help("Do not generate bindings for methods.")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-convert-floats")
-                .long("no-convert-floats")
-                .help("Do not automatically convert floats to f32/f64.")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-prepend-enum-name")
-                .long("no-prepend-enum-name")
-                .help("Do not prepend the enum name to constant or newtype variants.")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-include-path-detection")
-                .long("no-include-path-detection")
-                .help("Do not try to detect default include paths")
-                .action(ArgAction::SetTrue),
-            Arg::new("fit-macro-constant-types")
-                .long("fit-macro-constant-types")
-                .help("Try to fit macro constants into types smaller than u32/i32")
-                .action(ArgAction::SetTrue),
-            Arg::new("opaque-type")
-                .long("opaque-type")
-                .help("Mark <type> as opaque.")
-                .value_name("type")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("output")
-                .short('o')
-                .long("output")
-                .help("Write Rust bindings to <output>.")
-                .action(ArgAction::Set),
-            Arg::new("raw-line")
-                .long("raw-line")
-                .help("Add a raw line of Rust code at the beginning of output.")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("module-raw-line")
-                .long("module-raw-line")
-                .help("Add a raw line of Rust code to a given module.")
-                .action(ArgAction::Append)
-                .number_of_values(2)
-                .value_names(&["module-name", "raw-line"]),
-            Arg::new("rust-target")
-                .long("rust-target")
-                .help(&rust_target_help)
-                .action(ArgAction::Set),
-            Arg::new("use-core")
-                .long("use-core")
-                .help("Use types from Rust core instead of std.")
-                .action(ArgAction::SetTrue),
-            Arg::new("conservative-inline-namespaces")
-                .long("conservative-inline-namespaces")
-                .help(
-                    "Conservatively generate inline namespaces to avoid name \
-                     conflicts.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("use-msvc-mangling")
-                .long("use-msvc-mangling")
-                .help("MSVC C++ ABI mangling. DEPRECATED: Has no effect.")
-                .action(ArgAction::SetTrue),
-            Arg::new("allowlist-function")
-                .long("allowlist-function")
-                .help(
-                    "Allowlist all the free-standing functions matching \
-                     <regex>. Other non-allowlisted functions will not be \
-                     generated.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("generate-inline-functions")
-                .long("generate-inline-functions")
-                .help("Generate inline functions.")
-                .action(ArgAction::SetTrue),
-            Arg::new("allowlist-type")
-                .long("allowlist-type")
-                .help(
-                    "Only generate types matching <regex>. Other non-allowlisted types will \
-                     not be generated.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("allowlist-var")
-                .long("allowlist-var")
-                .help(
-                    "Allowlist all the free-standing variables matching \
-                     <regex>. Other non-allowlisted variables will not be \
-                     generated.",
-                )
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("allowlist-file")
-                .alias("allowlist-file")
-                .long("allowlist-file")
-                .help("Allowlist all contents of <path>.")
-                .value_name("path")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("verbose")
-                .long("verbose")
-                .help("Print verbose error messages.")
-                .action(ArgAction::SetTrue),
-            Arg::new("dump-preprocessed-input")
-                .long("dump-preprocessed-input")
-                .help(
-                    "Preprocess and dump the input header files to disk. \
-                     Useful when debugging bindgen, using C-Reduce, or when \
-                     filing issues. The resulting file will be named \
-                     something like `__bindgen.i` or `__bindgen.ii`.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("no-record-matches")
-                .long("no-record-matches")
-                .help(
-                    "Do not record matching items in the regex sets. \
-                     This disables reporting of unused items.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("size_t-is-usize")
-                .long("size_t-is-usize")
-                .help("Ignored - this is enabled by default.")
-                .hide(true)
-                .action(ArgAction::SetTrue),
-            Arg::new("no-size_t-is-usize")
-                .long("no-size_t-is-usize")
-                .help("Do not bind size_t as usize (useful on platforms \
-                       where those types are incompatible).")
-                .action(ArgAction::SetTrue),
-            Arg::new("no-rustfmt-bindings")
-                .long("no-rustfmt-bindings")
-                .help("Do not format the generated bindings with rustfmt.")
-                .action(ArgAction::SetTrue),
-            Arg::new("rustfmt-bindings")
-                .long("rustfmt-bindings")
-                .help(
-                    "Format the generated bindings with rustfmt. DEPRECATED: \
-                     --rustfmt-bindings is now enabled by default. Disable \
-                     with --no-rustfmt-bindings.",
-                ),
-            Arg::new("rustfmt-configuration-file")
-                .long("rustfmt-configuration-file")
-                .help(
-                    "The absolute path to the rustfmt configuration file. \
-                     The configuration file will be used for formatting the bindings. \
-                     This parameter is incompatible with --no-rustfmt-bindings.",
-                )
-                .value_name("path")
-                .action(ArgAction::Set)
-                .number_of_values(1),
-            Arg::new("no-partialeq")
-                .long("no-partialeq")
-                .help("Avoid deriving PartialEq for types matching <regex>.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("no-copy")
-                .long("no-copy")
-                .help("Avoid deriving Copy for types matching <regex>.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("no-debug")
-                .long("no-debug")
-                .help("Avoid deriving Debug for types matching <regex>.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("no-default")
-                .long("no-default")
-                .help("Avoid deriving/implement Default for types matching <regex>.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("no-hash")
-                .long("no-hash")
-                .help("Avoid deriving Hash for types matching <regex>.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("must-use-type")
-                .long("must-use-type")
-                .help("Add #[must_use] annotation to types matching <regex>.")
-                .value_name("regex")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("enable-function-attribute-detection")
-                .long("enable-function-attribute-detection")
-                .help(
-                    "Enables detecting unexposed attributes in functions (slow).
-                       Used to generate #[must_use] annotations.",
-                )
-                .action(ArgAction::SetTrue),
-            Arg::new("use-array-pointers-in-arguments")
-                .long("use-array-pointers-in-arguments")
-                .help("Use `*const [T; size]` instead of `*const T` for C arrays")
-                .action(ArgAction::SetTrue),
-            Arg::new("wasm-import-module-name")
-                .long("wasm-import-module-name")
-                .value_name("name")
-                .help("The name to be used in a #[link(wasm_import_module = ...)] statement"),
-            Arg::new("dynamic-loading")
-                .long("dynamic-loading")
-                .action(ArgAction::Set)
-                .help("Use dynamic loading mode with the given library name."),
-            Arg::new("dynamic-link-require-all")
-                .long("dynamic-link-require-all")
-                .help("Require successful linkage to all functions in the library.")
-                .action(ArgAction::SetTrue),
-            Arg::new("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++.")
-                .action(ArgAction::SetTrue),
-            Arg::new("translate-enum-integer-types")
-                .long("translate-enum-integer-types")
-                .help("Always translate enum integer types to native Rust integer types.")
-                .action(ArgAction::SetTrue),
-            Arg::new("c-naming")
-                .long("c-naming")
-                .help("Generate types with C style naming.")
-                .action(ArgAction::SetTrue),
-            Arg::new("explicit-padding")
-                .long("explicit-padding")
-                .help("Always output explicit padding fields.")
-                .action(ArgAction::SetTrue),
-            Arg::new("vtable-generation")
-                .long("vtable-generation")
-                .help("Enables generation of vtable functions.")
-                .action(ArgAction::SetTrue),
-            Arg::new("sort-semantically")
-                .long("sort-semantically")
-                .help("Enables sorting of code generation in a predefined manner.")
-                .action(ArgAction::SetTrue),
-            Arg::new("merge-extern-blocks")
-                .long("merge-extern-blocks")
-                .help("Deduplicates extern blocks.")
-                .action(ArgAction::SetTrue),
-            Arg::new("override-abi")
-                .long("override-abi")
-                .help("Overrides the ABI of functions matching <regex>. The <override> value must be of the shape <regex>=<abi> where <abi> can be one of C, stdcall, fastcall, thiscall, aapcs, win64 or C-unwind.")
-                .value_name("override")
-                .action(ArgAction::Append)
-                .number_of_values(1),
-            Arg::new("wrap-unsafe-ops")
-                .long("wrap-unsafe-ops")
-                .help("Wrap unsafe operations in unsafe blocks.")
-                .action(ArgAction::SetTrue),
-            Arg::new("V")
-                .long("version")
-                .help("Prints the version, and exits")
-                .action(ArgAction::SetTrue),
-        ]) // .args()
-        .get_matches_from(args);
+    let BindgenCommand {
+        header,
+        depfile,
+        default_enum_style,
+        bitfield_enum,
+        newtype_enum,
+        newtype_global_enum,
+        rustified_enum,
+        constified_enum,
+        constified_enum_module,
+        default_macro_constant_type,
+        default_alias_style,
+        normal_alias,
+        new_type_alias,
+        new_type_alias_deref,
+        default_non_copy_union_style,
+        bindgen_wrapper_union,
+        manually_drop_union,
+        blocklist_type,
+        blocklist_function,
+        blocklist_item,
+        blocklist_file,
+        no_layout_tests,
+        no_derive_copy,
+        no_derive_debug,
+        no_derive_default,
+        impl_debug,
+        impl_partialeq,
+        with_derive_default,
+        with_derive_hash,
+        with_derive_partialeq,
+        with_derive_partialord,
+        with_derive_eq,
+        with_derive_ord,
+        no_doc_comments,
+        no_recursive_allowlist,
+        objc_extern_crate,
+        generate_block,
+        block_extern_crate,
+        distrust_clang_mangling,
+        builtins,
+        ctypes_prefix,
+        anon_fields_prefix,
+        time_phases,
+        emit_clang_ast,
+        emit_ir,
+        emit_ir_graphviz,
+        enable_cxx_namespaces,
+        disable_name_namespacing,
+        disable_nested_struct_naming,
+        disable_untagged_union,
+        disable_header_comment,
+        ignore_functions,
+        generate,
+        ignore_methods,
+        no_convert_floats,
+        no_prepend_enum_name,
+        no_include_path_detection,
+        fit_macro_constant_types,
+        opaque_type,
+        output,
+        raw_line,
+        module_raw_line,
+        rust_target,
+        use_core,
+        conservative_inline_namespaces,
+        use_msvc_mangling: _,
+        allowlist_function,
+        generate_inline_functions,
+        allowlist_type,
+        allowlist_var,
+        allowlist_file,
+        verbose,
+        dump_preprocessed_input,
+        no_record_matches,
+        size_t_is_usize: _,
+        no_size_t_is_usize,
+        no_rustfmt_bindings,
+        rustfmt_bindings: _,
+        rustfmt_configuration_file,
+        no_partialeq,
+        no_copy,
+        no_debug,
+        no_default,
+        no_hash,
+        must_use_type,
+        enable_function_attribute_detection,
+        use_array_pointers_in_arguments,
+        wasm_import_module_name,
+        dynamic_loading,
+        dynamic_link_require_all,
+        respect_cxx_access_specs,
+        translate_enum_integer_types,
+        c_naming,
+        explicit_padding,
+        vtable_generation,
+        sort_semantically,
+        merge_extern_blocks,
+        override_abi,
+        wrap_unsafe_ops,
+        with_derive_custom,
+        with_derive_custom_struct,
+        with_derive_custom_enum,
+        with_derive_custom_union,
+        wrap_static_fns,
+        wrap_static_fns_path,
+        wrap_static_fns_suffix,
+        experimental: _,
+        version,
+        clang_args,
+    } = command;
 
-    let verbose = matches.get_flag("verbose");
-    if matches.get_flag("V") {
+    if version {
         println!(
             "bindgen {}",
             option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")
@@ -637,415 +508,327 @@
 
     let mut builder = builder();
 
-    if let Some(header) = matches.get_one::<String>("header") {
+    if let Some(header) = header {
         builder = builder.header(header);
     } else {
         return Err(Error::new(ErrorKind::Other, "Header not found"));
     }
 
-    if let Some(rust_target) = matches.get_one::<String>("rust-target") {
-        builder = builder.rust_target(RustTarget::from_str(rust_target)?);
+    if let Some(rust_target) = rust_target {
+        builder = builder.rust_target(rust_target);
     }
 
-    if let Some(variant) = matches.get_one::<String>("default-enum-style") {
-        builder = builder.default_enum_style(EnumVariation::from_str(variant)?)
+    if let Some(variant) = default_enum_style {
+        builder = builder.default_enum_style(variant);
     }
 
-    if let Some(bitfields) = matches.get_many::<String>("bitfield-enum") {
-        for regex in bitfields {
-            builder = builder.bitfield_enum(regex);
-        }
+    for regex in bitfield_enum {
+        builder = builder.bitfield_enum(regex);
     }
 
-    if let Some(newtypes) = matches.get_many::<String>("newtype-enum") {
-        for regex in newtypes {
-            builder = builder.newtype_enum(regex);
-        }
+    for regex in newtype_enum {
+        builder = builder.newtype_enum(regex);
     }
 
-    if let Some(newtypes) = matches.get_many::<String>("newtype-global-enum") {
-        for regex in newtypes {
-            builder = builder.newtype_global_enum(regex);
-        }
+    for regex in newtype_global_enum {
+        builder = builder.newtype_global_enum(regex);
     }
 
-    if let Some(rustifieds) = matches.get_many::<String>("rustified-enum") {
-        for regex in rustifieds {
-            builder = builder.rustified_enum(regex);
-        }
+    for regex in rustified_enum {
+        builder = builder.rustified_enum(regex);
     }
 
-    if let Some(const_enums) = matches.get_many::<String>("constified-enum") {
-        for regex in const_enums {
-            builder = builder.constified_enum(regex);
-        }
+    for regex in constified_enum {
+        builder = builder.constified_enum(regex);
     }
 
-    if let Some(constified_mods) =
-        matches.get_many::<String>("constified-enum-module")
-    {
-        for regex in constified_mods {
-            builder = builder.constified_enum_module(regex);
-        }
+    for regex in constified_enum_module {
+        builder = builder.constified_enum_module(regex);
     }
 
-    if let Some(variant) =
-        matches.get_one::<String>("default-macro-constant-type")
-    {
-        builder = builder
-            .default_macro_constant_type(MacroTypeVariation::from_str(variant)?)
-    }
-
-    if let Some(variant) = matches.get_one::<String>("default-alias-style") {
+    if let Some(default_macro_constant_type) = default_macro_constant_type {
         builder =
-            builder.default_alias_style(AliasVariation::from_str(variant)?);
+            builder.default_macro_constant_type(default_macro_constant_type)
     }
 
-    if let Some(type_alias) = matches.get_many::<String>("normal-alias") {
-        for regex in type_alias {
-            builder = builder.type_alias(regex);
-        }
+    if let Some(variant) = default_alias_style {
+        builder = builder.default_alias_style(variant);
     }
 
-    if let Some(new_type) = matches.get_many::<String>("new-type-alias") {
-        for regex in new_type {
-            builder = builder.new_type_alias(regex);
-        }
+    for regex in normal_alias {
+        builder = builder.type_alias(regex);
     }
 
-    if let Some(new_type_deref) =
-        matches.get_many::<String>("new-type-alias-deref")
-    {
-        for regex in new_type_deref {
-            builder = builder.new_type_alias_deref(regex);
-        }
+    for regex in new_type_alias {
+        builder = builder.new_type_alias(regex);
     }
 
-    if let Some(variant) =
-        matches.get_one::<String>("default-non-copy-union-style")
-    {
-        builder = builder.default_non_copy_union_style(
-            NonCopyUnionStyle::from_str(variant)?,
-        );
+    for regex in new_type_alias_deref {
+        builder = builder.new_type_alias_deref(regex);
     }
 
-    if let Some(bindgen_wrapper_union) =
-        matches.get_many::<String>("bindgen-wrapper-union")
-    {
-        for regex in bindgen_wrapper_union {
-            builder = builder.bindgen_wrapper_union(regex);
-        }
+    if let Some(variant) = default_non_copy_union_style {
+        builder = builder.default_non_copy_union_style(variant);
     }
 
-    if let Some(manually_drop_union) =
-        matches.get_many::<String>("manually-drop-union")
-    {
-        for regex in manually_drop_union {
-            builder = builder.manually_drop_union(regex);
-        }
+    for regex in bindgen_wrapper_union {
+        builder = builder.bindgen_wrapper_union(regex);
     }
 
-    if let Some(hidden_types) = matches.get_many::<String>("blocklist-type") {
-        for ty in hidden_types {
-            builder = builder.blocklist_type(ty);
-        }
+    for regex in manually_drop_union {
+        builder = builder.manually_drop_union(regex);
     }
 
-    if let Some(hidden_functions) =
-        matches.get_many::<String>("blocklist-function")
-    {
-        for fun in hidden_functions {
-            builder = builder.blocklist_function(fun);
-        }
+    for ty in blocklist_type {
+        builder = builder.blocklist_type(ty);
     }
 
-    if let Some(hidden_identifiers) =
-        matches.get_many::<String>("blocklist-item")
-    {
-        for id in hidden_identifiers {
-            builder = builder.blocklist_item(id);
-        }
+    for fun in blocklist_function {
+        builder = builder.blocklist_function(fun);
     }
 
-    if let Some(hidden_files) = matches.get_many::<String>("blocklist-file") {
-        for file in hidden_files {
-            builder = builder.blocklist_file(file);
-        }
+    for id in blocklist_item {
+        builder = builder.blocklist_item(id);
     }
 
-    if matches.get_flag("builtins") {
+    for file in blocklist_file {
+        builder = builder.blocklist_file(file);
+    }
+
+    if builtins {
         builder = builder.emit_builtins();
     }
 
-    if matches.get_flag("no-layout-tests") {
+    if no_layout_tests {
         builder = builder.layout_tests(false);
     }
 
-    if matches.get_flag("no-derive-copy") {
+    if no_derive_copy {
         builder = builder.derive_copy(false);
     }
 
-    if matches.get_flag("no-derive-debug") {
+    if no_derive_debug {
         builder = builder.derive_debug(false);
     }
 
-    if matches.get_flag("impl-debug") {
+    if impl_debug {
         builder = builder.impl_debug(true);
     }
 
-    if matches.get_flag("impl-partialeq") {
+    if impl_partialeq {
         builder = builder.impl_partialeq(true);
     }
 
-    if matches.get_flag("with-derive-default") {
+    if with_derive_default {
         builder = builder.derive_default(true);
     }
 
-    if matches.get_flag("with-derive-hash") {
+    if with_derive_hash {
         builder = builder.derive_hash(true);
     }
 
-    if matches.get_flag("with-derive-partialeq") {
+    if with_derive_partialeq {
         builder = builder.derive_partialeq(true);
     }
 
-    if matches.get_flag("with-derive-partialord") {
+    if with_derive_partialord {
         builder = builder.derive_partialord(true);
     }
 
-    if matches.get_flag("with-derive-eq") {
+    if with_derive_eq {
         builder = builder.derive_eq(true);
     }
 
-    if matches.get_flag("with-derive-ord") {
+    if with_derive_ord {
         builder = builder.derive_ord(true);
     }
 
-    if matches.get_flag("no-derive-default") {
+    if no_derive_default {
         builder = builder.derive_default(false);
     }
 
-    if matches.get_flag("no-prepend-enum-name") {
+    if no_prepend_enum_name {
         builder = builder.prepend_enum_name(false);
     }
 
-    if matches.get_flag("no-include-path-detection") {
+    if no_include_path_detection {
         builder = builder.detect_include_paths(false);
     }
 
-    if matches.get_flag("fit-macro-constant-types") {
+    if fit_macro_constant_types {
         builder = builder.fit_macro_constants(true);
     }
 
-    if matches.get_flag("time-phases") {
+    if time_phases {
         builder = builder.time_phases(true);
     }
 
-    if matches.get_flag("use-array-pointers-in-arguments") {
+    if use_array_pointers_in_arguments {
         builder = builder.array_pointers_in_arguments(true);
     }
 
-    if let Some(wasm_import_name) =
-        matches.get_one::<String>("wasm-import-module-name")
-    {
+    if let Some(wasm_import_name) = wasm_import_module_name {
         builder = builder.wasm_import_module_name(wasm_import_name);
     }
 
-    if let Some(prefix) = matches.get_one::<String>("ctypes-prefix") {
+    if let Some(prefix) = ctypes_prefix {
         builder = builder.ctypes_prefix(prefix);
     }
 
-    if let Some(prefix) = matches.get_one::<String>("anon-fields-prefix") {
-        builder = builder.anon_fields_prefix(prefix);
-    }
+    builder = builder.anon_fields_prefix(anon_fields_prefix);
 
-    if let Some(what_to_generate) = matches.get_one::<String>("generate") {
-        let mut config = CodegenConfig::empty();
-        for what in what_to_generate.split(',') {
-            match what {
-                "functions" => config.insert(CodegenConfig::FUNCTIONS),
-                "types" => config.insert(CodegenConfig::TYPES),
-                "vars" => config.insert(CodegenConfig::VARS),
-                "methods" => config.insert(CodegenConfig::METHODS),
-                "constructors" => config.insert(CodegenConfig::CONSTRUCTORS),
-                "destructors" => config.insert(CodegenConfig::DESTRUCTORS),
-                otherwise => {
-                    return Err(Error::new(
-                        ErrorKind::Other,
-                        format!("Unknown generate item: {}", otherwise),
-                    ));
-                }
-            }
-        }
+    if let Some(config) = generate {
         builder = builder.with_codegen_config(config);
     }
 
-    if matches.get_flag("emit-clang-ast") {
+    if emit_clang_ast {
         builder = builder.emit_clang_ast();
     }
 
-    if matches.get_flag("emit-ir") {
+    if emit_ir {
         builder = builder.emit_ir();
     }
 
-    if let Some(path) = matches.get_one::<String>("emit-ir-graphviz") {
+    if let Some(path) = emit_ir_graphviz {
         builder = builder.emit_ir_graphviz(path);
     }
 
-    if matches.get_flag("enable-cxx-namespaces") {
+    if enable_cxx_namespaces {
         builder = builder.enable_cxx_namespaces();
     }
 
-    if matches.get_flag("enable-function-attribute-detection") {
+    if enable_function_attribute_detection {
         builder = builder.enable_function_attribute_detection();
     }
 
-    if matches.get_flag("disable-name-namespacing") {
+    if disable_name_namespacing {
         builder = builder.disable_name_namespacing();
     }
 
-    if matches.get_flag("disable-nested-struct-naming") {
+    if disable_nested_struct_naming {
         builder = builder.disable_nested_struct_naming();
     }
 
-    if matches.get_flag("disable-untagged-union") {
+    if disable_untagged_union {
         builder = builder.disable_untagged_union();
     }
 
-    if matches.get_flag("disable-header-comment") {
+    if disable_header_comment {
         builder = builder.disable_header_comment();
     }
 
-    if matches.get_flag("ignore-functions") {
+    if ignore_functions {
         builder = builder.ignore_functions();
     }
 
-    if matches.get_flag("ignore-methods") {
+    if ignore_methods {
         builder = builder.ignore_methods();
     }
 
-    if matches.get_flag("no-convert-floats") {
+    if no_convert_floats {
         builder = builder.no_convert_floats();
     }
 
-    if matches.get_flag("no-doc-comments") {
+    if no_doc_comments {
         builder = builder.generate_comments(false);
     }
 
-    if matches.get_flag("no-recursive-allowlist") {
+    if no_recursive_allowlist {
         builder = builder.allowlist_recursively(false);
     }
 
-    if matches.get_flag("objc-extern-crate") {
+    if objc_extern_crate {
         builder = builder.objc_extern_crate(true);
     }
 
-    if matches.get_flag("generate-block") {
+    if generate_block {
         builder = builder.generate_block(true);
     }
 
-    if matches.get_flag("block-extern-crate") {
+    if block_extern_crate {
         builder = builder.block_extern_crate(true);
     }
 
-    if let Some(opaque_types) = matches.get_many::<String>("opaque-type") {
-        for ty in opaque_types {
-            builder = builder.opaque_type(ty);
-        }
+    for ty in opaque_type {
+        builder = builder.opaque_type(ty);
     }
 
-    if let Some(lines) = matches.get_many::<String>("raw-line") {
-        for line in lines {
-            builder = builder.raw_line(line);
-        }
+    for line in raw_line {
+        builder = builder.raw_line(line);
     }
 
-    if let Some(mut values) = matches.get_many::<String>("module-raw-line") {
-        while let Some(module) = values.next() {
-            let line = values.next().unwrap();
-            builder = builder.module_raw_line(module, line);
-        }
+    let mut values = module_raw_line.into_iter();
+    while let Some(module) = values.next() {
+        let line = values.next().unwrap();
+        builder = builder.module_raw_line(module, line);
     }
 
-    if matches.get_flag("use-core") {
+    if use_core {
         builder = builder.use_core();
     }
 
-    if matches.get_flag("distrust-clang-mangling") {
+    if distrust_clang_mangling {
         builder = builder.trust_clang_mangling(false);
     }
 
-    if matches.get_flag("conservative-inline-namespaces") {
+    if conservative_inline_namespaces {
         builder = builder.conservative_inline_namespaces();
     }
 
-    if matches.get_flag("generate-inline-functions") {
+    if generate_inline_functions {
         builder = builder.generate_inline_functions(true);
     }
 
-    if let Some(allowlist) = matches.get_many::<String>("allowlist-function") {
-        for regex in allowlist {
-            builder = builder.allowlist_function(regex);
-        }
+    for regex in allowlist_function {
+        builder = builder.allowlist_function(regex);
     }
 
-    if let Some(allowlist) = matches.get_many::<String>("allowlist-type") {
-        for regex in allowlist {
-            builder = builder.allowlist_type(regex);
-        }
+    for regex in allowlist_type {
+        builder = builder.allowlist_type(regex);
     }
 
-    if let Some(allowlist) = matches.get_many::<String>("allowlist-var") {
-        for regex in allowlist {
-            builder = builder.allowlist_var(regex);
-        }
+    for regex in allowlist_var {
+        builder = builder.allowlist_var(regex);
     }
 
-    if let Some(hidden_files) = matches.get_many::<String>("allowlist-file") {
-        for file in hidden_files {
-            builder = builder.allowlist_file(file);
-        }
+    for file in allowlist_file {
+        builder = builder.allowlist_file(file);
     }
 
-    if let Some(args) = matches.get_many::<String>("clang-args") {
-        for arg in args {
-            builder = builder.clang_arg(arg);
-        }
+    for arg in clang_args {
+        builder = builder.clang_arg(arg);
     }
 
-    let output = if let Some(path) = matches.get_one::<String>("output") {
+    let output = if let Some(path) = &output {
         let file = File::create(path)?;
-        if let Some(depfile) = matches.get_one::<String>("depfile") {
+        if let Some(depfile) = depfile {
             builder = builder.depfile(path, depfile);
         }
         Box::new(io::BufWriter::new(file)) as Box<dyn io::Write>
     } else {
-        if let Some(depfile) = matches.get_one::<String>("depfile") {
+        if let Some(depfile) = depfile {
             builder = builder.depfile("-", depfile);
         }
         Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write>
     };
 
-    if matches.get_flag("dump-preprocessed-input") {
+    if dump_preprocessed_input {
         builder.dump_preprocessed_input()?;
     }
 
-    if matches.get_flag("no-record-matches") {
+    if no_record_matches {
         builder = builder.record_matches(false);
     }
 
-    if matches.get_flag("no-size_t-is-usize") {
+    if no_size_t_is_usize {
         builder = builder.size_t_is_usize(false);
     }
 
-    let no_rustfmt_bindings = matches.get_flag("no-rustfmt-bindings");
     if no_rustfmt_bindings {
         builder = builder.rustfmt_bindings(false);
     }
 
-    if let Some(path_str) =
-        matches.get_one::<String>("rustfmt-configuration-file")
-    {
+    if let Some(path_str) = rustfmt_configuration_file {
         let path = PathBuf::from(path_str);
 
         if no_rustfmt_bindings {
@@ -1072,94 +855,157 @@
         builder = builder.rustfmt_configuration_file(Some(path));
     }
 
-    if let Some(no_partialeq) = matches.get_many::<String>("no-partialeq") {
-        for regex in no_partialeq {
-            builder = builder.no_partialeq(regex);
-        }
+    for regex in no_partialeq {
+        builder = builder.no_partialeq(regex);
     }
 
-    if let Some(no_copy) = matches.get_many::<String>("no-copy") {
-        for regex in no_copy {
-            builder = builder.no_copy(regex);
-        }
+    for regex in no_copy {
+        builder = builder.no_copy(regex);
     }
 
-    if let Some(no_debug) = matches.get_many::<String>("no-debug") {
-        for regex in no_debug {
-            builder = builder.no_debug(regex);
-        }
+    for regex in no_debug {
+        builder = builder.no_debug(regex);
     }
 
-    if let Some(no_default) = matches.get_many::<String>("no-default") {
-        for regex in no_default {
-            builder = builder.no_default(regex);
-        }
+    for regex in no_default {
+        builder = builder.no_default(regex);
     }
 
-    if let Some(no_hash) = matches.get_many::<String>("no-hash") {
-        for regex in no_hash {
-            builder = builder.no_hash(regex);
-        }
+    for regex in no_hash {
+        builder = builder.no_hash(regex);
     }
 
-    if let Some(must_use_type) = matches.get_many::<String>("must-use-type") {
-        for regex in must_use_type {
-            builder = builder.must_use_type(regex);
-        }
+    for regex in must_use_type {
+        builder = builder.must_use_type(regex);
     }
 
-    if let Some(dynamic_library_name) =
-        matches.get_one::<String>("dynamic-loading")
-    {
+    if let Some(dynamic_library_name) = dynamic_loading {
         builder = builder.dynamic_library_name(dynamic_library_name);
     }
 
-    if matches.get_flag("dynamic-link-require-all") {
+    if dynamic_link_require_all {
         builder = builder.dynamic_link_require_all(true);
     }
 
-    if matches.get_flag("respect-cxx-access-specs") {
+    if respect_cxx_access_specs {
         builder = builder.respect_cxx_access_specs(true);
     }
 
-    if matches.get_flag("translate-enum-integer-types") {
+    if translate_enum_integer_types {
         builder = builder.translate_enum_integer_types(true);
     }
 
-    if matches.get_flag("c-naming") {
+    if c_naming {
         builder = builder.c_naming(true);
     }
 
-    if matches.get_flag("explicit-padding") {
+    if explicit_padding {
         builder = builder.explicit_padding(true);
     }
 
-    if matches.get_flag("vtable-generation") {
+    if vtable_generation {
         builder = builder.vtable_generation(true);
     }
 
-    if matches.get_flag("sort-semantically") {
+    if sort_semantically {
         builder = builder.sort_semantically(true);
     }
 
-    if matches.get_flag("merge-extern-blocks") {
+    if merge_extern_blocks {
         builder = builder.merge_extern_blocks(true);
     }
 
-    if let Some(abi_overrides) = matches.get_many::<String>("override-abi") {
-        for abi_override in abi_overrides {
-            let (regex, abi_str) = abi_override
-                .rsplit_once('=')
-                .expect("Invalid ABI override: Missing `=`");
-            let abi = abi_str
-                .parse()
-                .unwrap_or_else(|err| panic!("Invalid ABI override: {}", err));
-            builder = builder.override_abi(abi, regex);
+    for abi_override in override_abi {
+        let (regex, abi_str) = abi_override
+            .rsplit_once('=')
+            .expect("Invalid ABI override: Missing `=`");
+        let abi = abi_str
+            .parse()
+            .unwrap_or_else(|err| panic!("Invalid ABI override: {}", err));
+        builder = builder.override_abi(abi, regex);
+    }
+
+    if wrap_unsafe_ops {
+        builder = builder.wrap_unsafe_ops(true);
+    }
+
+    #[derive(Debug)]
+    struct CustomDeriveCallback {
+        derives: Vec<String>,
+        kind: Option<TypeKind>,
+        regex_set: bindgen::RegexSet,
+    }
+
+    impl bindgen::callbacks::ParseCallbacks for CustomDeriveCallback {
+        fn cli_args(&self) -> Vec<String> {
+            let mut args = vec![];
+
+            let flag = match &self.kind {
+                None => "--with-derive-custom",
+                Some(TypeKind::Struct) => "--with-derive-custom-struct",
+                Some(TypeKind::Enum) => "--with-derive-custom-enum",
+                Some(TypeKind::Union) => "--with-derive-custom-union",
+            };
+
+            let derives = self.derives.join(",");
+
+            for item in self.regex_set.get_items() {
+                args.extend_from_slice(&[
+                    flag.to_owned(),
+                    format!("{}={}", item, derives),
+                ]);
+            }
+
+            args
+        }
+
+        fn add_derives(
+            &self,
+            info: &bindgen::callbacks::DeriveInfo<'_>,
+        ) -> Vec<String> {
+            if self.kind.map(|kind| kind == info.kind).unwrap_or(true) &&
+                self.regex_set.matches(info.name)
+            {
+                return self.derives.clone();
+            }
+            vec![]
         }
     }
 
-    if matches.get_flag("wrap-unsafe-ops") {
-        builder = builder.wrap_unsafe_ops(true);
+    for (custom_derives, kind) in [
+        (with_derive_custom, None),
+        (with_derive_custom_struct, Some(TypeKind::Struct)),
+        (with_derive_custom_enum, Some(TypeKind::Enum)),
+        (with_derive_custom_union, Some(TypeKind::Union)),
+    ] {
+        for custom_derive in custom_derives {
+            let (regex, derives) = custom_derive
+                .rsplit_once('=')
+                .expect("Invalid custom derive argument: Missing `=`");
+            let derives = derives.split(',').map(|s| s.to_owned()).collect();
+
+            let mut regex_set = RegexSet::new();
+            regex_set.insert(regex);
+            regex_set.build(false);
+
+            builder = builder.parse_callbacks(Box::new(CustomDeriveCallback {
+                derives,
+                kind,
+                regex_set,
+            }));
+        }
+    }
+
+    if wrap_static_fns {
+        builder = builder.wrap_static_fns(true);
+    }
+
+    if let Some(path) = wrap_static_fns_path {
+        builder = builder.wrap_static_fns_path(path);
+    }
+
+    if let Some(suffix) = wrap_static_fns_suffix {
+        builder = builder.wrap_static_fns_suffix(suffix);
     }
 
     Ok((builder, output, verbose))
diff --git a/patches/clap4.diff b/patches/clap4.diff
deleted file mode 100644
index 66cdf3e..0000000
--- a/patches/clap4.diff
+++ /dev/null
@@ -1,1308 +0,0 @@
-diff --git a/Cargo.toml.orig b/Cargo.toml.orig
-index 99a6c622..a8436a42 100644
---- a/Cargo.toml.orig
-+++ b/Cargo.toml.orig
-@@ -23,7 +23,7 @@ name = "bindgen"
- [dependencies]
- bindgen = { path = "../bindgen", version = "=0.63.0" }
- shlex = "1"
--clap = "3"
-+clap = "4"
- env_logger = { version = "0.9.0", optional = true }
- log = { version = "0.4", optional = true }
- 
-diff --git a/options.rs b/options.rs
-index f7fccc4f..f04d7268 100644
---- a/options.rs
-+++ b/options.rs
-@@ -3,7 +3,7 @@ use bindgen::{
-     MacroTypeVariation, NonCopyUnionStyle, RustTarget,
-     DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS,
- };
--use clap::{App, Arg};
-+use clap::{builder::PossibleValuesParser, Arg, ArgAction, Command};
- use std::fs::File;
- use std::io::{self, Error, ErrorKind};
- use std::path::PathBuf;
-@@ -22,9 +22,9 @@ where
-         String::from(RustTarget::default())
-     );
- 
--    let matches = App::new("bindgen")
-+    let matches = Command::new("bindgen")
-         .about("Generates Rust bindings from C/C++ headers.")
--        .setting(clap::AppSettings::NoAutoVersion)
-+        .disable_version_flag(true)
-         .override_usage("bindgen [FLAGS] [OPTIONS] <header> -- <clang-args>...")
-         .args(&[
-             Arg::new("header")
-@@ -32,22 +32,22 @@ where
-                 .required_unless_present("V"),
-             Arg::new("depfile")
-                 .long("depfile")
--                .takes_value(true)
-+                .action(ArgAction::Set)
-                 .help("Path to write depfile to"),
-             Arg::new("default-enum-style")
-                 .long("default-enum-style")
-                 .help("The default style of code used to generate enums.")
-                 .value_name("variant")
-                 .default_value("consts")
--                .possible_values([
-+                .value_parser(PossibleValuesParser::new([
-                     "consts",
-                     "moduleconsts",
-                     "bitfield",
-                     "newtype",
-                     "rust",
-                     "rust_non_exhaustive",
--                ])
--                .multiple_occurrences(false),
-+                ]))
-+                .action(ArgAction::Set),
-             Arg::new("bitfield-enum")
-                 .long("bitfield-enum")
-                 .help(
-@@ -55,25 +55,25 @@ where
-                      bitfield flags.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("newtype-enum")
-                 .long("newtype-enum")
-                 .help("Mark any enum whose name matches <regex> as a newtype.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("newtype-global-enum")
-                 .long("newtype-global-enum")
-                 .help("Mark any enum whose name matches <regex> as a global newtype.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("rustified-enum")
-                 .long("rustified-enum")
-                 .help("Mark any enum whose name matches <regex> as a Rust enum.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("constified-enum")
-                 .long("constified-enum")
-@@ -82,7 +82,7 @@ where
-                      constants.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("constified-enum-module")
-                 .long("constified-enum-module")
-@@ -91,26 +91,26 @@ where
-                      constants.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("default-macro-constant-type")
-                 .long("default-macro-constant-type")
-                 .help("The default signed/unsigned type for C macro constants.")
-                 .value_name("variant")
-                 .default_value("unsigned")
--                .possible_values(["signed", "unsigned"])
--                .multiple_occurrences(false),
-+                .value_parser(PossibleValuesParser::new(["signed", "unsigned"]))
-+                .action(ArgAction::Set),
-             Arg::new("default-alias-style")
-                 .long("default-alias-style")
-                 .help("The default style of code used to generate typedefs.")
-                 .value_name("variant")
-                 .default_value("type_alias")
--                .possible_values([
-+                .value_parser(PossibleValuesParser::new([
-                     "type_alias",
-                     "new_type",
-                     "new_type_deref",
--                ])
--                .multiple_occurrences(false),
-+                ]))
-+                .action(ArgAction::Set),
-             Arg::new("normal-alias")
-                 .long("normal-alias")
-                 .help(
-@@ -118,7 +118,7 @@ where
-                      normal type aliasing.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-              Arg::new("new-type-alias")
-                 .long("new-type-alias")
-@@ -127,7 +127,7 @@ where
-                      a new type generated for it.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-              Arg::new("new-type-alias-deref")
-                 .long("new-type-alias-deref")
-@@ -136,7 +136,7 @@ where
-                      a new type with Deref and DerefMut to the inner type.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("default-non-copy-union-style")
-                 .long("default-non-copy-union-style")
-@@ -147,11 +147,11 @@ where
-                 )
-                 .value_name("style")
-                 .default_value("bindgen_wrapper")
--                .possible_values([
-+                .value_parser(PossibleValuesParser::new([
-                     "bindgen_wrapper",
-                     "manually_drop",
--                ])
--                .multiple_occurrences(false),
-+                ]))
-+                .action(ArgAction::Set),
-             Arg::new("bindgen-wrapper-union")
-                 .long("bindgen-wrapper-union")
-                 .help(
-@@ -160,8 +160,7 @@ where
-                      fields.",
-                 )
-                 .value_name("regex")
--                .takes_value(true)
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("manually-drop-union")
-                 .long("manually-drop-union")
-@@ -171,86 +170,98 @@ where
-                      1.20.0) for fields.",
-                 )
-                 .value_name("regex")
--                .takes_value(true)
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("blocklist-type")
-                 .long("blocklist-type")
-                 .help("Mark <type> as hidden.")
-                 .value_name("type")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("blocklist-function")
-                 .long("blocklist-function")
-                 .help("Mark <function> as hidden.")
-                 .value_name("function")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("blocklist-item")
-                 .long("blocklist-item")
-                 .help("Mark <item> as hidden.")
-                 .value_name("item")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("blocklist-file")
-                 .long("blocklist-file")
-                 .help("Mark all contents of <path> as hidden.")
-                 .value_name("path")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("no-layout-tests")
-                 .long("no-layout-tests")
--                .help("Avoid generating layout tests for any type."),
-+                .help("Avoid generating layout tests for any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-derive-copy")
-                 .long("no-derive-copy")
--                .help("Avoid deriving Copy on any type."),
-+                .help("Avoid deriving Copy on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-derive-debug")
-                 .long("no-derive-debug")
--                .help("Avoid deriving Debug on any type."),
-+                .help("Avoid deriving Debug on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-derive-default")
-                 .long("no-derive-default")
-                 .hide(true)
--                .help("Avoid deriving Default on any type."),
-+                .help("Avoid deriving Default on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("impl-debug").long("impl-debug").help(
-                 "Create Debug implementation, if it can not be derived \
-                  automatically.",
--            ),
-+            )
-+            .action(ArgAction::SetTrue),
-             Arg::new("impl-partialeq")
-                 .long("impl-partialeq")
-                 .help(
-                     "Create PartialEq implementation, if it can not be derived \
-                      automatically.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("with-derive-default")
-                 .long("with-derive-default")
--                .help("Derive Default on any type."),
-+                .help("Derive Default on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("with-derive-hash")
-                 .long("with-derive-hash")
--                .help("Derive hash on any type."),
-+                .help("Derive hash on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("with-derive-partialeq")
-                 .long("with-derive-partialeq")
--                .help("Derive partialeq on any type."),
-+                .help("Derive partialeq on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("with-derive-partialord")
-                 .long("with-derive-partialord")
--                .help("Derive partialord on any type."),
-+                .help("Derive partialord on any type.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("with-derive-eq")
-                 .long("with-derive-eq")
-                 .help(
-                     "Derive eq on any type. Enable this option also \
-                      enables --with-derive-partialeq",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("with-derive-ord")
-                 .long("with-derive-ord")
-                 .help(
-                     "Derive ord on any type. Enable this option also \
-                      enables --with-derive-partialord",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-doc-comments")
-                 .long("no-doc-comments")
-                 .help(
-                     "Avoid including doc comments in the output, see: \
-                      https://github.com/rust-lang/rust-bindgen/issues/426",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-recursive-allowlist")
-                 .long("no-recursive-allowlist")
-                 .help(
-@@ -258,23 +269,29 @@ where
-                      bindgen to emit Rust code that won't compile! See the \
-                      `bindgen::Builder::allowlist_recursively` method's \
-                      documentation for details.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("objc-extern-crate")
-                 .long("objc-extern-crate")
--                .help("Use extern crate instead of use for objc."),
-+                .help("Use extern crate instead of use for objc.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("generate-block")
-                 .long("generate-block")
--                .help("Generate block signatures instead of void pointers."),
-+                .help("Generate block signatures instead of void pointers.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("block-extern-crate")
-                 .long("block-extern-crate")
--                .help("Use extern crate instead of use for block."),
-+                .help("Use extern crate instead of use for block.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("distrust-clang-mangling")
-                 .long("distrust-clang-mangling")
--                .help("Do not trust the libclang-provided mangling"),
-+                .help("Do not trust the libclang-provided mangling")
-+                .action(ArgAction::SetTrue),
-             Arg::new("builtins").long("builtins").help(
-                 "Output bindings for builtin definitions, e.g. \
-                  __builtin_va_list.",
--            ),
-+            )
-+            .action(ArgAction::SetTrue),
-             Arg::new("ctypes-prefix")
-                 .long("ctypes-prefix")
-                 .help(
-@@ -289,51 +306,59 @@ where
-                 .default_value(DEFAULT_ANON_FIELDS_PREFIX),
-             Arg::new("time-phases")
-                 .long("time-phases")
--                .help("Time the different bindgen phases and print to stderr"),
-+                .help("Time the different bindgen phases and print to stderr")
-+                .action(ArgAction::SetTrue),
-             // All positional arguments after the end of options marker, `--`
--            Arg::new("clang-args").last(true).multiple_occurrences(true),
-+            Arg::new("clang-args").last(true).action(ArgAction::Append),
-             Arg::new("emit-clang-ast")
-                 .long("emit-clang-ast")
--                .help("Output the Clang AST for debugging purposes."),
-+                .help("Output the Clang AST for debugging purposes.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("emit-ir")
-                 .long("emit-ir")
--                .help("Output our internal IR for debugging purposes."),
-+                .help("Output our internal IR for debugging purposes.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("emit-ir-graphviz")
-                 .long("emit-ir-graphviz")
-                 .help("Dump graphviz dot file.")
-                 .value_name("path"),
-             Arg::new("enable-cxx-namespaces")
-                 .long("enable-cxx-namespaces")
--                .help("Enable support for C++ namespaces."),
-+                .help("Enable support for C++ namespaces.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("disable-name-namespacing")
-                 .long("disable-name-namespacing")
-                 .help(
-                     "Disable namespacing via mangling, causing bindgen to \
-                      generate names like \"Baz\" instead of \"foo_bar_Baz\" \
-                      for an input name \"foo::bar::Baz\".",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("disable-nested-struct-naming")
-                 .long("disable-nested-struct-naming")
-                 .help(
-                     "Disable nested struct naming, causing bindgen to generate \
-                      names like \"bar\" instead of \"foo_bar\" for a nested \
-                      definition \"struct foo { struct bar { } b; };\"."
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("disable-untagged-union")
-                 .long("disable-untagged-union")
-                 .help(
-                     "Disable support for native Rust unions.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("disable-header-comment")
-                 .long("disable-header-comment")
-                 .help("Suppress insertion of bindgen's version identifier into generated bindings.")
--                .multiple_occurrences(true),
-+                .action(ArgAction::SetTrue),
-             Arg::new("ignore-functions")
-                 .long("ignore-functions")
-                 .help(
-                     "Do not generate bindings for functions or methods. This \
-                      is useful when you only care about struct layouts.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("generate")
-                 .long("generate")
-                 .help(
-@@ -341,60 +366,68 @@ where
-                      Valid values are \"functions\",\"types\", \"vars\", \
-                      \"methods\", \"constructors\" and \"destructors\".",
-                 )
--                .takes_value(true),
-+                .action(ArgAction::Set),
-             Arg::new("ignore-methods")
-                 .long("ignore-methods")
--                .help("Do not generate bindings for methods."),
-+                .help("Do not generate bindings for methods.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-convert-floats")
-                 .long("no-convert-floats")
--                .help("Do not automatically convert floats to f32/f64."),
-+                .help("Do not automatically convert floats to f32/f64.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-prepend-enum-name")
-                 .long("no-prepend-enum-name")
--                .help("Do not prepend the enum name to constant or newtype variants."),
-+                .help("Do not prepend the enum name to constant or newtype variants.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-include-path-detection")
-                 .long("no-include-path-detection")
--                .help("Do not try to detect default include paths"),
-+                .help("Do not try to detect default include paths")
-+                .action(ArgAction::SetTrue),
-             Arg::new("fit-macro-constant-types")
-                 .long("fit-macro-constant-types")
--                .help("Try to fit macro constants into types smaller than u32/i32"),
-+                .help("Try to fit macro constants into types smaller than u32/i32")
-+                .action(ArgAction::SetTrue),
-             Arg::new("opaque-type")
-                 .long("opaque-type")
-                 .help("Mark <type> as opaque.")
-                 .value_name("type")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("output")
-                 .short('o')
-                 .long("output")
-                 .help("Write Rust bindings to <output>.")
--                .takes_value(true),
-+                .action(ArgAction::Set),
-             Arg::new("raw-line")
-                 .long("raw-line")
-                 .help("Add a raw line of Rust code at the beginning of output.")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("module-raw-line")
-                 .long("module-raw-line")
-                 .help("Add a raw line of Rust code to a given module.")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(2)
-                 .value_names(&["module-name", "raw-line"]),
-             Arg::new("rust-target")
-                 .long("rust-target")
--                .help(rust_target_help.as_ref())
--                .takes_value(true),
-+                .help(&rust_target_help)
-+                .action(ArgAction::Set),
-             Arg::new("use-core")
-                 .long("use-core")
--                .help("Use types from Rust core instead of std."),
-+                .help("Use types from Rust core instead of std.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("conservative-inline-namespaces")
-                 .long("conservative-inline-namespaces")
-                 .help(
-                     "Conservatively generate inline namespaces to avoid name \
-                      conflicts.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("use-msvc-mangling")
-                 .long("use-msvc-mangling")
--                .help("MSVC C++ ABI mangling. DEPRECATED: Has no effect."),
-+                .help("MSVC C++ ABI mangling. DEPRECATED: Has no effect.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("allowlist-function")
-                 .long("allowlist-function")
-                 .help(
-@@ -403,11 +436,12 @@ where
-                      generated.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("generate-inline-functions")
-                 .long("generate-inline-functions")
--                .help("Generate inline functions."),
-+                .help("Generate inline functions.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("allowlist-type")
-                 .long("allowlist-type")
-                 .help(
-@@ -415,7 +449,7 @@ where
-                      not be generated.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("allowlist-var")
-                 .long("allowlist-var")
-@@ -425,18 +459,19 @@ where
-                      generated.",
-                 )
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("allowlist-file")
-                 .alias("allowlist-file")
-                 .long("allowlist-file")
-                 .help("Allowlist all contents of <path>.")
-                 .value_name("path")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("verbose")
-                 .long("verbose")
--                .help("Print verbose error messages."),
-+                .help("Print verbose error messages.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("dump-preprocessed-input")
-                 .long("dump-preprocessed-input")
-                 .help(
-@@ -444,24 +479,29 @@ where
-                      Useful when debugging bindgen, using C-Reduce, or when \
-                      filing issues. The resulting file will be named \
-                      something like `__bindgen.i` or `__bindgen.ii`.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-record-matches")
-                 .long("no-record-matches")
-                 .help(
-                     "Do not record matching items in the regex sets. \
-                      This disables reporting of unused items.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("size_t-is-usize")
-                 .long("size_t-is-usize")
-                 .help("Ignored - this is enabled by default.")
--                .hidden(true),
--            Arg::with_name("no-size_t-is-usize")
-+                .hide(true)
-+                .action(ArgAction::SetTrue),
-+            Arg::new("no-size_t-is-usize")
-                 .long("no-size_t-is-usize")
-                 .help("Do not bind size_t as usize (useful on platforms \
--                       where those types are incompatible)."),
-+                       where those types are incompatible).")
-+                .action(ArgAction::SetTrue),
-             Arg::new("no-rustfmt-bindings")
-                 .long("no-rustfmt-bindings")
--                .help("Do not format the generated bindings with rustfmt."),
-+                .help("Do not format the generated bindings with rustfmt.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("rustfmt-bindings")
-                 .long("rustfmt-bindings")
-                 .help(
-@@ -477,102 +517,114 @@ where
-                      This parameter is incompatible with --no-rustfmt-bindings.",
-                 )
-                 .value_name("path")
--                .multiple_occurrences(false)
-+                .action(ArgAction::Set)
-                 .number_of_values(1),
-             Arg::new("no-partialeq")
-                 .long("no-partialeq")
-                 .help("Avoid deriving PartialEq for types matching <regex>.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("no-copy")
-                 .long("no-copy")
-                 .help("Avoid deriving Copy for types matching <regex>.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("no-debug")
-                 .long("no-debug")
-                 .help("Avoid deriving Debug for types matching <regex>.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("no-default")
-                 .long("no-default")
-                 .help("Avoid deriving/implement Default for types matching <regex>.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("no-hash")
-                 .long("no-hash")
-                 .help("Avoid deriving Hash for types matching <regex>.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("must-use-type")
-                 .long("must-use-type")
-                 .help("Add #[must_use] annotation to types matching <regex>.")
-                 .value_name("regex")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("enable-function-attribute-detection")
-                 .long("enable-function-attribute-detection")
-                 .help(
-                     "Enables detecting unexposed attributes in functions (slow).
-                        Used to generate #[must_use] annotations.",
--                ),
-+                )
-+                .action(ArgAction::SetTrue),
-             Arg::new("use-array-pointers-in-arguments")
-                 .long("use-array-pointers-in-arguments")
--                .help("Use `*const [T; size]` instead of `*const T` for C arrays"),
-+                .help("Use `*const [T; size]` instead of `*const T` for C arrays")
-+                .action(ArgAction::SetTrue),
-             Arg::new("wasm-import-module-name")
-                 .long("wasm-import-module-name")
-                 .value_name("name")
-                 .help("The name to be used in a #[link(wasm_import_module = ...)] statement"),
-             Arg::new("dynamic-loading")
-                 .long("dynamic-loading")
--                .takes_value(true)
-+                .action(ArgAction::Set)
-                 .help("Use dynamic loading mode with the given library name."),
-             Arg::new("dynamic-link-require-all")
-                 .long("dynamic-link-require-all")
--                .help("Require successful linkage to all functions in the library."),
-+                .help("Require successful linkage to all functions in the library.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("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++."),
-+                .help("Makes generated bindings `pub` only for items if the items are publically accessible in C++.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("translate-enum-integer-types")
-                 .long("translate-enum-integer-types")
--                .help("Always translate enum integer types to native Rust integer types."),
-+                .help("Always translate enum integer types to native Rust integer types.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("c-naming")
-                 .long("c-naming")
--                .help("Generate types with C style naming."),
-+                .help("Generate types with C style naming.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("explicit-padding")
-                 .long("explicit-padding")
--                .help("Always output explicit padding fields."),
-+                .help("Always output explicit padding fields.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("vtable-generation")
-                 .long("vtable-generation")
--                .help("Enables generation of vtable functions."),
-+                .help("Enables generation of vtable functions.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("sort-semantically")
-                 .long("sort-semantically")
--                .help("Enables sorting of code generation in a predefined manner."),
-+                .help("Enables sorting of code generation in a predefined manner.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("merge-extern-blocks")
-                 .long("merge-extern-blocks")
--                .help("Deduplicates extern blocks."),
-+                .help("Deduplicates extern blocks.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("override-abi")
-                 .long("override-abi")
-                 .help("Overrides the ABI of functions matching <regex>. The <override> value must be of the shape <regex>=<abi> where <abi> can be one of C, stdcall, fastcall, thiscall, aapcs, win64 or C-unwind.")
-                 .value_name("override")
--                .multiple_occurrences(true)
-+                .action(ArgAction::Append)
-                 .number_of_values(1),
-             Arg::new("wrap-unsafe-ops")
-                 .long("wrap-unsafe-ops")
--                .help("Wrap unsafe operations in unsafe blocks."),
-+                .help("Wrap unsafe operations in unsafe blocks.")
-+                .action(ArgAction::SetTrue),
-             Arg::new("V")
-                 .long("version")
--                .help("Prints the version, and exits"),
-+                .help("Prints the version, and exits")
-+                .action(ArgAction::SetTrue),
-         ]) // .args()
-         .get_matches_from(args);
- 
--    let verbose = matches.is_present("verbose");
--    if matches.is_present("V") {
-+    let verbose = matches.get_flag("verbose");
-+    if matches.get_flag("V") {
-         println!(
-             "bindgen {}",
-             option_env!("CARGO_PKG_VERSION").unwrap_or("unknown")
-@@ -585,215 +637,229 @@ where
- 
-     let mut builder = builder();
- 
--    if let Some(header) = matches.value_of("header") {
-+    if let Some(header) = matches.get_one::<String>("header") {
-         builder = builder.header(header);
-     } else {
-         return Err(Error::new(ErrorKind::Other, "Header not found"));
-     }
- 
--    if let Some(rust_target) = matches.value_of("rust-target") {
-+    if let Some(rust_target) = matches.get_one::<String>("rust-target") {
-         builder = builder.rust_target(RustTarget::from_str(rust_target)?);
-     }
- 
--    if let Some(variant) = matches.value_of("default-enum-style") {
-+    if let Some(variant) = matches.get_one::<String>("default-enum-style") {
-         builder = builder.default_enum_style(EnumVariation::from_str(variant)?)
-     }
- 
--    if let Some(bitfields) = matches.values_of("bitfield-enum") {
-+    if let Some(bitfields) = matches.get_many::<String>("bitfield-enum") {
-         for regex in bitfields {
-             builder = builder.bitfield_enum(regex);
-         }
-     }
- 
--    if let Some(newtypes) = matches.values_of("newtype-enum") {
-+    if let Some(newtypes) = matches.get_many::<String>("newtype-enum") {
-         for regex in newtypes {
-             builder = builder.newtype_enum(regex);
-         }
-     }
- 
--    if let Some(newtypes) = matches.values_of("newtype-global-enum") {
-+    if let Some(newtypes) = matches.get_many::<String>("newtype-global-enum") {
-         for regex in newtypes {
-             builder = builder.newtype_global_enum(regex);
-         }
-     }
- 
--    if let Some(rustifieds) = matches.values_of("rustified-enum") {
-+    if let Some(rustifieds) = matches.get_many::<String>("rustified-enum") {
-         for regex in rustifieds {
-             builder = builder.rustified_enum(regex);
-         }
-     }
- 
--    if let Some(const_enums) = matches.values_of("constified-enum") {
-+    if let Some(const_enums) = matches.get_many::<String>("constified-enum") {
-         for regex in const_enums {
-             builder = builder.constified_enum(regex);
-         }
-     }
- 
--    if let Some(constified_mods) = matches.values_of("constified-enum-module") {
-+    if let Some(constified_mods) =
-+        matches.get_many::<String>("constified-enum-module")
-+    {
-         for regex in constified_mods {
-             builder = builder.constified_enum_module(regex);
-         }
-     }
- 
--    if let Some(variant) = matches.value_of("default-macro-constant-type") {
-+    if let Some(variant) =
-+        matches.get_one::<String>("default-macro-constant-type")
-+    {
-         builder = builder
-             .default_macro_constant_type(MacroTypeVariation::from_str(variant)?)
-     }
- 
--    if let Some(variant) = matches.value_of("default-alias-style") {
-+    if let Some(variant) = matches.get_one::<String>("default-alias-style") {
-         builder =
-             builder.default_alias_style(AliasVariation::from_str(variant)?);
-     }
- 
--    if let Some(type_alias) = matches.values_of("normal-alias") {
-+    if let Some(type_alias) = matches.get_many::<String>("normal-alias") {
-         for regex in type_alias {
-             builder = builder.type_alias(regex);
-         }
-     }
- 
--    if let Some(new_type) = matches.values_of("new-type-alias") {
-+    if let Some(new_type) = matches.get_many::<String>("new-type-alias") {
-         for regex in new_type {
-             builder = builder.new_type_alias(regex);
-         }
-     }
- 
--    if let Some(new_type_deref) = matches.values_of("new-type-alias-deref") {
-+    if let Some(new_type_deref) =
-+        matches.get_many::<String>("new-type-alias-deref")
-+    {
-         for regex in new_type_deref {
-             builder = builder.new_type_alias_deref(regex);
-         }
-     }
- 
--    if let Some(variant) = matches.value_of("default-non-copy-union-style") {
-+    if let Some(variant) =
-+        matches.get_one::<String>("default-non-copy-union-style")
-+    {
-         builder = builder.default_non_copy_union_style(
-             NonCopyUnionStyle::from_str(variant)?,
-         );
-     }
- 
-     if let Some(bindgen_wrapper_union) =
--        matches.values_of("bindgen-wrapper-union")
-+        matches.get_many::<String>("bindgen-wrapper-union")
-     {
-         for regex in bindgen_wrapper_union {
-             builder = builder.bindgen_wrapper_union(regex);
-         }
-     }
- 
--    if let Some(manually_drop_union) = matches.values_of("manually-drop-union")
-+    if let Some(manually_drop_union) =
-+        matches.get_many::<String>("manually-drop-union")
-     {
-         for regex in manually_drop_union {
-             builder = builder.manually_drop_union(regex);
-         }
-     }
- 
--    if let Some(hidden_types) = matches.values_of("blocklist-type") {
-+    if let Some(hidden_types) = matches.get_many::<String>("blocklist-type") {
-         for ty in hidden_types {
-             builder = builder.blocklist_type(ty);
-         }
-     }
- 
--    if let Some(hidden_functions) = matches.values_of("blocklist-function") {
-+    if let Some(hidden_functions) =
-+        matches.get_many::<String>("blocklist-function")
-+    {
-         for fun in hidden_functions {
-             builder = builder.blocklist_function(fun);
-         }
-     }
- 
--    if let Some(hidden_identifiers) = matches.values_of("blocklist-item") {
-+    if let Some(hidden_identifiers) =
-+        matches.get_many::<String>("blocklist-item")
-+    {
-         for id in hidden_identifiers {
-             builder = builder.blocklist_item(id);
-         }
-     }
- 
--    if let Some(hidden_files) = matches.values_of("blocklist-file") {
-+    if let Some(hidden_files) = matches.get_many::<String>("blocklist-file") {
-         for file in hidden_files {
-             builder = builder.blocklist_file(file);
-         }
-     }
- 
--    if matches.is_present("builtins") {
-+    if matches.get_flag("builtins") {
-         builder = builder.emit_builtins();
-     }
- 
--    if matches.is_present("no-layout-tests") {
-+    if matches.get_flag("no-layout-tests") {
-         builder = builder.layout_tests(false);
-     }
- 
--    if matches.is_present("no-derive-copy") {
-+    if matches.get_flag("no-derive-copy") {
-         builder = builder.derive_copy(false);
-     }
- 
--    if matches.is_present("no-derive-debug") {
-+    if matches.get_flag("no-derive-debug") {
-         builder = builder.derive_debug(false);
-     }
- 
--    if matches.is_present("impl-debug") {
-+    if matches.get_flag("impl-debug") {
-         builder = builder.impl_debug(true);
-     }
- 
--    if matches.is_present("impl-partialeq") {
-+    if matches.get_flag("impl-partialeq") {
-         builder = builder.impl_partialeq(true);
-     }
- 
--    if matches.is_present("with-derive-default") {
-+    if matches.get_flag("with-derive-default") {
-         builder = builder.derive_default(true);
-     }
- 
--    if matches.is_present("with-derive-hash") {
-+    if matches.get_flag("with-derive-hash") {
-         builder = builder.derive_hash(true);
-     }
- 
--    if matches.is_present("with-derive-partialeq") {
-+    if matches.get_flag("with-derive-partialeq") {
-         builder = builder.derive_partialeq(true);
-     }
- 
--    if matches.is_present("with-derive-partialord") {
-+    if matches.get_flag("with-derive-partialord") {
-         builder = builder.derive_partialord(true);
-     }
- 
--    if matches.is_present("with-derive-eq") {
-+    if matches.get_flag("with-derive-eq") {
-         builder = builder.derive_eq(true);
-     }
- 
--    if matches.is_present("with-derive-ord") {
-+    if matches.get_flag("with-derive-ord") {
-         builder = builder.derive_ord(true);
-     }
- 
--    if matches.is_present("no-derive-default") {
-+    if matches.get_flag("no-derive-default") {
-         builder = builder.derive_default(false);
-     }
- 
--    if matches.is_present("no-prepend-enum-name") {
-+    if matches.get_flag("no-prepend-enum-name") {
-         builder = builder.prepend_enum_name(false);
-     }
- 
--    if matches.is_present("no-include-path-detection") {
-+    if matches.get_flag("no-include-path-detection") {
-         builder = builder.detect_include_paths(false);
-     }
- 
--    if matches.is_present("fit-macro-constant-types") {
-+    if matches.get_flag("fit-macro-constant-types") {
-         builder = builder.fit_macro_constants(true);
-     }
- 
--    if matches.is_present("time-phases") {
-+    if matches.get_flag("time-phases") {
-         builder = builder.time_phases(true);
-     }
- 
--    if matches.is_present("use-array-pointers-in-arguments") {
-+    if matches.get_flag("use-array-pointers-in-arguments") {
-         builder = builder.array_pointers_in_arguments(true);
-     }
- 
--    if let Some(wasm_import_name) = matches.value_of("wasm-import-module-name")
-+    if let Some(wasm_import_name) =
-+        matches.get_one::<String>("wasm-import-module-name")
-     {
-         builder = builder.wasm_import_module_name(wasm_import_name);
-     }
- 
--    if let Some(prefix) = matches.value_of("ctypes-prefix") {
-+    if let Some(prefix) = matches.get_one::<String>("ctypes-prefix") {
-         builder = builder.ctypes_prefix(prefix);
-     }
- 
--    if let Some(prefix) = matches.value_of("anon-fields-prefix") {
-+    if let Some(prefix) = matches.get_one::<String>("anon-fields-prefix") {
-         builder = builder.anon_fields_prefix(prefix);
-     }
- 
--    if let Some(what_to_generate) = matches.value_of("generate") {
-+    if let Some(what_to_generate) = matches.get_one::<String>("generate") {
-         let mut config = CodegenConfig::empty();
-         for what in what_to_generate.split(',') {
-             match what {
-@@ -814,170 +880,172 @@ where
-         builder = builder.with_codegen_config(config);
-     }
- 
--    if matches.is_present("emit-clang-ast") {
-+    if matches.get_flag("emit-clang-ast") {
-         builder = builder.emit_clang_ast();
-     }
- 
--    if matches.is_present("emit-ir") {
-+    if matches.get_flag("emit-ir") {
-         builder = builder.emit_ir();
-     }
- 
--    if let Some(path) = matches.value_of("emit-ir-graphviz") {
-+    if let Some(path) = matches.get_one::<String>("emit-ir-graphviz") {
-         builder = builder.emit_ir_graphviz(path);
-     }
- 
--    if matches.is_present("enable-cxx-namespaces") {
-+    if matches.get_flag("enable-cxx-namespaces") {
-         builder = builder.enable_cxx_namespaces();
-     }
- 
--    if matches.is_present("enable-function-attribute-detection") {
-+    if matches.get_flag("enable-function-attribute-detection") {
-         builder = builder.enable_function_attribute_detection();
-     }
- 
--    if matches.is_present("disable-name-namespacing") {
-+    if matches.get_flag("disable-name-namespacing") {
-         builder = builder.disable_name_namespacing();
-     }
- 
--    if matches.is_present("disable-nested-struct-naming") {
-+    if matches.get_flag("disable-nested-struct-naming") {
-         builder = builder.disable_nested_struct_naming();
-     }
- 
--    if matches.is_present("disable-untagged-union") {
-+    if matches.get_flag("disable-untagged-union") {
-         builder = builder.disable_untagged_union();
-     }
- 
--    if matches.is_present("disable-header-comment") {
-+    if matches.get_flag("disable-header-comment") {
-         builder = builder.disable_header_comment();
-     }
- 
--    if matches.is_present("ignore-functions") {
-+    if matches.get_flag("ignore-functions") {
-         builder = builder.ignore_functions();
-     }
- 
--    if matches.is_present("ignore-methods") {
-+    if matches.get_flag("ignore-methods") {
-         builder = builder.ignore_methods();
-     }
- 
--    if matches.is_present("no-convert-floats") {
-+    if matches.get_flag("no-convert-floats") {
-         builder = builder.no_convert_floats();
-     }
- 
--    if matches.is_present("no-doc-comments") {
-+    if matches.get_flag("no-doc-comments") {
-         builder = builder.generate_comments(false);
-     }
- 
--    if matches.is_present("no-recursive-allowlist") {
-+    if matches.get_flag("no-recursive-allowlist") {
-         builder = builder.allowlist_recursively(false);
-     }
- 
--    if matches.is_present("objc-extern-crate") {
-+    if matches.get_flag("objc-extern-crate") {
-         builder = builder.objc_extern_crate(true);
-     }
- 
--    if matches.is_present("generate-block") {
-+    if matches.get_flag("generate-block") {
-         builder = builder.generate_block(true);
-     }
- 
--    if matches.is_present("block-extern-crate") {
-+    if matches.get_flag("block-extern-crate") {
-         builder = builder.block_extern_crate(true);
-     }
- 
--    if let Some(opaque_types) = matches.values_of("opaque-type") {
-+    if let Some(opaque_types) = matches.get_many::<String>("opaque-type") {
-         for ty in opaque_types {
-             builder = builder.opaque_type(ty);
-         }
-     }
- 
--    if let Some(lines) = matches.values_of("raw-line") {
-+    if let Some(lines) = matches.get_many::<String>("raw-line") {
-         for line in lines {
-             builder = builder.raw_line(line);
-         }
-     }
- 
--    if let Some(mut values) = matches.values_of("module-raw-line") {
-+    if let Some(mut values) = matches.get_many::<String>("module-raw-line") {
-         while let Some(module) = values.next() {
-             let line = values.next().unwrap();
-             builder = builder.module_raw_line(module, line);
-         }
-     }
- 
--    if matches.is_present("use-core") {
-+    if matches.get_flag("use-core") {
-         builder = builder.use_core();
-     }
- 
--    if matches.is_present("distrust-clang-mangling") {
-+    if matches.get_flag("distrust-clang-mangling") {
-         builder = builder.trust_clang_mangling(false);
-     }
- 
--    if matches.is_present("conservative-inline-namespaces") {
-+    if matches.get_flag("conservative-inline-namespaces") {
-         builder = builder.conservative_inline_namespaces();
-     }
- 
--    if matches.is_present("generate-inline-functions") {
-+    if matches.get_flag("generate-inline-functions") {
-         builder = builder.generate_inline_functions(true);
-     }
- 
--    if let Some(allowlist) = matches.values_of("allowlist-function") {
-+    if let Some(allowlist) = matches.get_many::<String>("allowlist-function") {
-         for regex in allowlist {
-             builder = builder.allowlist_function(regex);
-         }
-     }
- 
--    if let Some(allowlist) = matches.values_of("allowlist-type") {
-+    if let Some(allowlist) = matches.get_many::<String>("allowlist-type") {
-         for regex in allowlist {
-             builder = builder.allowlist_type(regex);
-         }
-     }
- 
--    if let Some(allowlist) = matches.values_of("allowlist-var") {
-+    if let Some(allowlist) = matches.get_many::<String>("allowlist-var") {
-         for regex in allowlist {
-             builder = builder.allowlist_var(regex);
-         }
-     }
- 
--    if let Some(hidden_files) = matches.values_of("allowlist-file") {
-+    if let Some(hidden_files) = matches.get_many::<String>("allowlist-file") {
-         for file in hidden_files {
-             builder = builder.allowlist_file(file);
-         }
-     }
- 
--    if let Some(args) = matches.values_of("clang-args") {
-+    if let Some(args) = matches.get_many::<String>("clang-args") {
-         for arg in args {
-             builder = builder.clang_arg(arg);
-         }
-     }
- 
--    let output = if let Some(path) = matches.value_of("output") {
-+    let output = if let Some(path) = matches.get_one::<String>("output") {
-         let file = File::create(path)?;
--        if let Some(depfile) = matches.value_of("depfile") {
-+        if let Some(depfile) = matches.get_one::<String>("depfile") {
-             builder = builder.depfile(path, depfile);
-         }
-         Box::new(io::BufWriter::new(file)) as Box<dyn io::Write>
-     } else {
--        if let Some(depfile) = matches.value_of("depfile") {
-+        if let Some(depfile) = matches.get_one::<String>("depfile") {
-             builder = builder.depfile("-", depfile);
-         }
-         Box::new(io::BufWriter::new(io::stdout())) as Box<dyn io::Write>
-     };
- 
--    if matches.is_present("dump-preprocessed-input") {
-+    if matches.get_flag("dump-preprocessed-input") {
-         builder.dump_preprocessed_input()?;
-     }
- 
--    if matches.is_present("no-record-matches") {
-+    if matches.get_flag("no-record-matches") {
-         builder = builder.record_matches(false);
-     }
- 
--    if matches.is_present("no-size_t-is-usize") {
-+    if matches.get_flag("no-size_t-is-usize") {
-         builder = builder.size_t_is_usize(false);
-     }
- 
--    let no_rustfmt_bindings = matches.is_present("no-rustfmt-bindings");
-+    let no_rustfmt_bindings = matches.get_flag("no-rustfmt-bindings");
-     if no_rustfmt_bindings {
-         builder = builder.rustfmt_bindings(false);
-     }
- 
--    if let Some(path_str) = matches.value_of("rustfmt-configuration-file") {
-+    if let Some(path_str) =
-+        matches.get_one::<String>("rustfmt-configuration-file")
-+    {
-         let path = PathBuf::from(path_str);
- 
-         if no_rustfmt_bindings {
-@@ -1004,79 +1072,81 @@ where
-         builder = builder.rustfmt_configuration_file(Some(path));
-     }
- 
--    if let Some(no_partialeq) = matches.values_of("no-partialeq") {
-+    if let Some(no_partialeq) = matches.get_many::<String>("no-partialeq") {
-         for regex in no_partialeq {
-             builder = builder.no_partialeq(regex);
-         }
-     }
- 
--    if let Some(no_copy) = matches.values_of("no-copy") {
-+    if let Some(no_copy) = matches.get_many::<String>("no-copy") {
-         for regex in no_copy {
-             builder = builder.no_copy(regex);
-         }
-     }
- 
--    if let Some(no_debug) = matches.values_of("no-debug") {
-+    if let Some(no_debug) = matches.get_many::<String>("no-debug") {
-         for regex in no_debug {
-             builder = builder.no_debug(regex);
-         }
-     }
- 
--    if let Some(no_default) = matches.values_of("no-default") {
-+    if let Some(no_default) = matches.get_many::<String>("no-default") {
-         for regex in no_default {
-             builder = builder.no_default(regex);
-         }
-     }
- 
--    if let Some(no_hash) = matches.values_of("no-hash") {
-+    if let Some(no_hash) = matches.get_many::<String>("no-hash") {
-         for regex in no_hash {
-             builder = builder.no_hash(regex);
-         }
-     }
- 
--    if let Some(must_use_type) = matches.values_of("must-use-type") {
-+    if let Some(must_use_type) = matches.get_many::<String>("must-use-type") {
-         for regex in must_use_type {
-             builder = builder.must_use_type(regex);
-         }
-     }
- 
--    if let Some(dynamic_library_name) = matches.value_of("dynamic-loading") {
-+    if let Some(dynamic_library_name) =
-+        matches.get_one::<String>("dynamic-loading")
-+    {
-         builder = builder.dynamic_library_name(dynamic_library_name);
-     }
- 
--    if matches.is_present("dynamic-link-require-all") {
-+    if matches.get_flag("dynamic-link-require-all") {
-         builder = builder.dynamic_link_require_all(true);
-     }
- 
--    if matches.is_present("respect-cxx-access-specs") {
-+    if matches.get_flag("respect-cxx-access-specs") {
-         builder = builder.respect_cxx_access_specs(true);
-     }
- 
--    if matches.is_present("translate-enum-integer-types") {
-+    if matches.get_flag("translate-enum-integer-types") {
-         builder = builder.translate_enum_integer_types(true);
-     }
- 
--    if matches.is_present("c-naming") {
-+    if matches.get_flag("c-naming") {
-         builder = builder.c_naming(true);
-     }
- 
--    if matches.is_present("explicit-padding") {
-+    if matches.get_flag("explicit-padding") {
-         builder = builder.explicit_padding(true);
-     }
- 
--    if matches.is_present("vtable-generation") {
-+    if matches.get_flag("vtable-generation") {
-         builder = builder.vtable_generation(true);
-     }
- 
--    if matches.is_present("sort-semantically") {
-+    if matches.get_flag("sort-semantically") {
-         builder = builder.sort_semantically(true);
-     }
- 
--    if matches.is_present("merge-extern-blocks") {
-+    if matches.get_flag("merge-extern-blocks") {
-         builder = builder.merge_extern_blocks(true);
-     }
- 
--    if let Some(abi_overrides) = matches.values_of("override-abi") {
-+    if let Some(abi_overrides) = matches.get_many::<String>("override-abi") {
-         for abi_override in abi_overrides {
-             let (regex, abi_str) = abi_override
-                 .rsplit_once('=')
-@@ -1088,7 +1158,7 @@ where
-         }
-     }
- 
--    if matches.is_present("wrap-unsafe-ops") {
-+    if matches.get_flag("wrap-unsafe-ops") {
-         builder = builder.wrap_unsafe_ops(true);
-     }
-