Merge "Upgrade bindgen-cli to 0.69.1" into main am: a6df3a8724 am: 06cd9cc00b am: 0d6da09a59

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

Change-Id: I2872988a829b69a27cfb59113f96d39bdcd193f5
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 1c73fbf..5c01817 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "7d243056d335fdc4537f7bca73c06d01aae24ddc"
+    "sha1": "4f9fa49ca907b831fdc3aecdfaec36b16d03c8d8"
   },
   "path_in_vcs": "bindgen-cli"
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index ecf1a84..ca59252 100644
--- a/Android.bp
+++ b/Android.bp
@@ -22,13 +22,11 @@
     name: "bindgen",
     crate_name: "bindgen",
     cargo_env_compat: true,
-    cargo_pkg_version: "0.65.1",
+    cargo_pkg_version: "0.69.1",
     srcs: ["main.rs"],
     edition: "2018",
     features: [
         "default",
-        "env_logger",
-        "log",
         "logging",
         "runtime",
         "which-rustfmt",
@@ -36,6 +34,7 @@
     rustlibs: [
         "libbindgen",
         "libclap",
+        "libclap_complete",
         "libenv_logger",
         "liblog_rust",
         "libshlex",
@@ -51,6 +50,7 @@
     rustlibs: [
         "libbindgen",
         "libclap",
+        "libclap_complete",
         "libenv_logger",
     ],
     compile_multilib: "first",
diff --git a/Cargo.lock b/Cargo.lock
index cdff447..bc02bba 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -22,75 +22,35 @@
 ]
 
 [[package]]
-name = "anstream"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f"
-dependencies = [
- "anstyle",
- "anstyle-parse",
- "anstyle-wincon",
- "concolor-override",
- "concolor-query",
- "is-terminal",
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle"
-version = "0.3.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
-
-[[package]]
-name = "anstyle-parse"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116"
-dependencies = [
- "utf8parse",
-]
-
-[[package]]
-name = "anstyle-wincon"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa"
-dependencies = [
- "anstyle",
- "windows-sys 0.45.0",
-]
-
-[[package]]
 name = "bindgen"
-version = "0.65.1"
+version = "0.69.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5"
+checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2"
 dependencies = [
  "annotate-snippets",
- "bitflags",
+ "bitflags 2.2.1",
  "cexpr",
  "clang-sys",
  "lazy_static",
  "lazycell",
  "log",
  "peeking_take_while",
- "prettyplease",
  "proc-macro2",
  "quote",
  "regex",
  "rustc-hash",
  "shlex",
- "syn",
+ "syn 2.0.18",
  "which",
 ]
 
 [[package]]
 name = "bindgen-cli"
-version = "0.65.1"
+version = "0.69.1"
 dependencies = [
  "bindgen",
  "clap",
+ "clap_complete",
  "env_logger",
  "log",
  "shlex",
@@ -103,10 +63,16 @@
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
-name = "cc"
-version = "1.0.79"
+name = "bitflags"
+version = "2.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
+
+[[package]]
+name = "cc"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
 
 [[package]]
 name = "cexpr"
@@ -125,9 +91,9 @@
 
 [[package]]
 name = "clang-sys"
-version = "1.6.1"
+version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
+checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3"
 dependencies = [
  "glob",
  "libc",
@@ -136,59 +102,48 @@
 
 [[package]]
 name = "clap"
-version = "4.2.1"
+version = "4.1.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "046ae530c528f252094e4a77886ee1374437744b2bff1497aa898bbddbbb29b3"
+checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76"
 dependencies = [
- "clap_builder",
+ "bitflags 1.3.2",
  "clap_derive",
+ "clap_lex",
+ "is-terminal",
  "once_cell",
+ "strsim",
+ "termcolor",
 ]
 
 [[package]]
-name = "clap_builder"
-version = "4.2.1"
+name = "clap_complete"
+version = "4.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "223163f58c9a40c3b0a43e1c4b50a9ce09f007ea2cb1ec258a687945b4b7929f"
+checksum = "01c22dcfb410883764b29953103d9ef7bb8fe21b3fa1158bc99986c2067294bd"
 dependencies = [
- "anstream",
- "anstyle",
- "bitflags",
- "clap_lex",
- "strsim",
+ "clap",
 ]
 
 [[package]]
 name = "clap_derive"
-version = "4.2.0"
+version = "4.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4"
+checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
 dependencies = [
  "heck",
+ "proc-macro-error",
  "proc-macro2",
  "quote",
- "syn",
+ "syn 1.0.107",
 ]
 
 [[package]]
 name = "clap_lex"
-version = "0.4.1"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1"
-
-[[package]]
-name = "concolor-override"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f"
-
-[[package]]
-name = "concolor-query"
-version = "0.3.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf"
+checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade"
 dependencies = [
- "windows-sys 0.45.0",
+ "os_str_bytes",
 ]
 
 [[package]]
@@ -239,15 +194,15 @@
 
 [[package]]
 name = "heck"
-version = "0.4.1"
+version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
 
 [[package]]
 name = "hermit-abi"
-version = "0.3.1"
+version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
 
 [[package]]
 name = "humantime"
@@ -257,13 +212,12 @@
 
 [[package]]
 name = "io-lifetimes"
-version = "1.0.10"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
+checksum = "e7d6c6f8c91b4b9ed43484ad1a938e393caf35960fce7f82a040497207bd8e9e"
 dependencies = [
- "hermit-abi",
  "libc",
- "windows-sys 0.48.0",
+ "windows-sys 0.42.0",
 ]
 
 [[package]]
@@ -292,9 +246,9 @@
 
 [[package]]
 name = "libc"
-version = "0.2.141"
+version = "0.2.139"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3304a64d199bb964be99741b7a14d26972741915b3649639149b2479bb46f4b5"
+checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
 
 [[package]]
 name = "libloading"
@@ -308,9 +262,9 @@
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.3.1"
+version = "0.3.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f"
+checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
 
 [[package]]
 name = "log"
@@ -345,9 +299,15 @@
 
 [[package]]
 name = "once_cell"
-version = "1.17.1"
+version = "1.17.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
+checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
+
+[[package]]
+name = "os_str_bytes"
+version = "6.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
 
 [[package]]
 name = "peeking_take_while"
@@ -356,38 +316,52 @@
 checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 
 [[package]]
-name = "prettyplease"
-version = "0.2.4"
+name = "proc-macro-error"
+version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ceca8aaf45b5c46ec7ed39fff75f57290368c1846d33d24a122ca81416ab058"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.107",
+ "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",
- "syn",
+ "quote",
+ "version_check",
 ]
 
 [[package]]
 name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.60"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406"
 dependencies = [
  "unicode-ident",
 ]
 
 [[package]]
 name = "quote"
-version = "1.0.26"
+version = "1.0.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
+checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488"
 dependencies = [
  "proc-macro2",
 ]
 
 [[package]]
 name = "regex"
-version = "1.7.3"
+version = "1.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d"
+checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
 dependencies = [
  "aho-corasick",
  "memchr",
@@ -396,9 +370,9 @@
 
 [[package]]
 name = "regex-syntax"
-version = "0.6.29"
+version = "0.6.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
 
 [[package]]
 name = "rustc-hash"
@@ -408,16 +382,16 @@
 
 [[package]]
 name = "rustix"
-version = "0.37.11"
+version = "0.37.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85597d61f83914ddeba6a47b3b8ffe7365107221c2e557ed94426489fefb5f77"
+checksum = "62b24138615de35e32031d041a09032ef3487a616d901ca4db224e7d557efae2"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
  "errno",
  "io-lifetimes",
  "libc",
  "linux-raw-sys",
- "windows-sys 0.48.0",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -434,9 +408,20 @@
 
 [[package]]
 name = "syn"
-version = "2.0.13"
+version = "1.0.107"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec"
+checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "syn"
+version = "2.0.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -454,9 +439,9 @@
 
 [[package]]
 name = "unicode-ident"
-version = "1.0.8"
+version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
+checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc"
 
 [[package]]
 name = "unicode-width"
@@ -465,10 +450,10 @@
 checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 
 [[package]]
-name = "utf8parse"
-version = "0.2.1"
+name = "version_check"
+version = "0.9.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
 
 [[package]]
 name = "which"
@@ -514,6 +499,21 @@
 
 [[package]]
 name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm 0.42.2",
+ "windows_aarch64_msvc 0.42.2",
+ "windows_i686_gnu 0.42.2",
+ "windows_i686_msvc 0.42.2",
+ "windows_x86_64_gnu 0.42.2",
+ "windows_x86_64_gnullvm 0.42.2",
+ "windows_x86_64_msvc 0.42.2",
+]
+
+[[package]]
+name = "windows-sys"
 version = "0.45.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
@@ -527,7 +527,7 @@
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
 dependencies = [
- "windows-targets 0.48.0",
+ "windows-targets 0.48.1",
 ]
 
 [[package]]
@@ -547,9 +547,9 @@
 
 [[package]]
 name = "windows-targets"
-version = "0.48.0"
+version = "0.48.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
+checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
 dependencies = [
  "windows_aarch64_gnullvm 0.48.0",
  "windows_aarch64_msvc 0.48.0",
diff --git a/Cargo.toml b/Cargo.toml
index 4b5f308..07ad1a9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2018"
 rust-version = "1.64.0"
 name = "bindgen-cli"
-version = "0.65.1"
+version = "0.69.1"
 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/"
@@ -31,21 +31,31 @@
 license = "BSD-3-Clause"
 repository = "https://github.com/rust-lang/rust-bindgen"
 
+[package.metadata.dist]
+dist = true
+
+[package.metadata.release]
+release = true
+
 [[bin]]
 name = "bindgen"
 path = "main.rs"
 
 [dependencies.bindgen]
-version = "=0.65.1"
+version = "=0.69.1"
 features = [
     "__cli",
     "experimental",
 ]
+default-features = false
 
 [dependencies.clap]
 version = "4"
 features = ["derive"]
 
+[dependencies.clap_complete]
+version = "4"
+
 [dependencies.env_logger]
 version = "0.10.0"
 optional = true
@@ -58,6 +68,9 @@
 version = "1"
 
 [features]
+__testing_only_extra_assertions = ["bindgen/__testing_only_extra_assertions"]
+__testing_only_libclang_5 = ["bindgen/__testing_only_libclang_5"]
+__testing_only_libclang_9 = ["bindgen/__testing_only_libclang_9"]
 default = [
     "logging",
     "runtime",
@@ -65,8 +78,8 @@
 ]
 logging = [
     "bindgen/logging",
-    "env_logger",
-    "log",
+    "dep:env_logger",
+    "dep:log",
 ]
 runtime = ["bindgen/runtime"]
 static = ["bindgen/static"]
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 731f1be..2738952 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -11,7 +11,7 @@
 repository = "https://github.com/rust-lang/rust-bindgen"
 documentation = "https://docs.rs/bindgen"
 homepage = "https://rust-lang.github.io/rust-bindgen/"
-version = "0.65.1"
+version = "0.69.1"
 edition = "2018"
 rust-version = "1.64.0"
 
@@ -20,16 +20,30 @@
 name = "bindgen"
 
 [dependencies]
-bindgen = { path = "../bindgen", version = "=0.65.1", features = ["__cli", "experimental"] }
-shlex = "1"
+bindgen = { path = "../bindgen", version = "=0.69.1",  default-features = false, features = ["__cli", "experimental"] }
 clap = { version = "4", features = ["derive"] }
+clap_complete = "4"
 env_logger = { version = "0.10.0", optional = true }
 log = { version = "0.4", optional = true }
+shlex = "1"
 
 [features]
 default = ["logging", "runtime", "which-rustfmt"]
-logging = ["bindgen/logging", "env_logger", "log"]
+logging = ["bindgen/logging", "dep:env_logger", "dep:log"]
 static = ["bindgen/static"]
 runtime = ["bindgen/runtime"]
 # Dynamically discover a `rustfmt` binary using the `which` crate
 which-rustfmt = ["bindgen/which-rustfmt"]
+
+## The following features are for internal use and they shouldn't be used if
+## you're not hacking on bindgen
+# Features used for CI testing 
+__testing_only_extra_assertions = ["bindgen/__testing_only_extra_assertions"]
+__testing_only_libclang_9 = ["bindgen/__testing_only_libclang_9"]
+__testing_only_libclang_5 = ["bindgen/__testing_only_libclang_5"]
+
+[package.metadata.release]
+release = true
+
+[package.metadata.dist]
+dist = true
diff --git a/METADATA b/METADATA
index 87b6252..74a1201 100644
--- a/METADATA
+++ b/METADATA
@@ -1,6 +1,6 @@
 # This project was upgraded with external_updater.
 # Usage: tools/external_updater/updater.sh update rust/crates/bindgen-cli
-# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "bindgen-cli"
 description: "Automatically generates Rust FFI bindings to C and C++ libraries."
@@ -11,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/bindgen-cli/bindgen-cli-0.65.1.crate"
+    value: "https://static.crates.io/crates/bindgen-cli/bindgen-cli-0.69.1.crate"
   }
-  version: "0.65.1"
+  version: "0.69.1"
   license_type: NOTICE
   last_upgrade_date {
     year: 2023
-    month: 6
-    day: 13
+    month: 11
+    day: 20
   }
 }
diff --git a/README.md b/README.md
index 67f227c..620ad0a 100644
--- a/README.md
+++ b/README.md
@@ -39,11 +39,15 @@
 
 ## MSRV
 
-The minimum supported Rust version is **1.60.0**.
+The `bindgen` minimum supported Rust version is **1.60.0**.
+
+The `bindgen-cli` minimum supported Rust version is **1.64.0**.
 
 No MSRV bump policy has been established yet, so MSRV may increase in any release.
 
-The MSRV is the minimum Rust version that can be used to *compile* `bindgen`. However, `bindgen` can generate bindings that are compatible with Rust versions below the current MSRV.
+The MSRV is the minimum Rust version that can be used to *compile* each crate. However, `bindgen` and `bindgen-cli` can generate bindings that are compatible with Rust versions below the current MSRV.
+
+Most of the time, the `bindgen-cli` crate will have a more recent MSRV than `bindgen` as crates such as `clap` require it. 
 
 ## API Reference
 
diff --git a/cargo2android-extra-module.bp b/cargo2android-extra-module.bp
index e9a914c..0148c22 100644
--- a/cargo2android-extra-module.bp
+++ b/cargo2android-extra-module.bp
@@ -6,6 +6,7 @@
     rustlibs: [
         "libbindgen",
         "libclap",
+        "libclap_complete",
         "libenv_logger",
     ],
     compile_multilib: "first",
diff --git a/main.rs b/main.rs
index a3b3612..a340723 100644
--- a/main.rs
+++ b/main.rs
@@ -13,9 +13,9 @@
 #[cfg(feature = "logging")]
 fn clang_version_check() {
     let version = bindgen::clang_version();
-    let expected_version = if cfg!(feature = "testing_only_libclang_9") {
+    let expected_version = if cfg!(feature = "__testing_only_libclang_9") {
         Some((9, 0))
-    } else if cfg!(feature = "testing_only_libclang_5") {
+    } else if cfg!(feature = "__testing_only_libclang_5") {
         Some((5, 0))
     } else {
         None
diff --git a/options.rs b/options.rs
index 1e592ce..b4b22dc 100644
--- a/options.rs
+++ b/options.rs
@@ -1,23 +1,27 @@
 use bindgen::callbacks::TypeKind;
 use bindgen::{
-    builder, AliasVariation, Builder, CodegenConfig, EnumVariation,
+    builder, Abi, AliasVariation, Builder, CodegenConfig, EnumVariation,
     FieldVisibilityKind, Formatter, MacroTypeVariation, NonCopyUnionStyle,
     RegexSet, RustTarget, DEFAULT_ANON_FIELDS_PREFIX, RUST_TARGET_STRINGS,
 };
-use clap::Parser;
+use clap::error::{Error, ErrorKind};
+use clap::{CommandFactory, Parser};
 use std::fs::File;
-use std::io::{self, Error, ErrorKind};
-use std::path::PathBuf;
+use std::io;
+use std::path::{Path, PathBuf};
+use std::process::exit;
 
 fn rust_target_help() -> String {
     format!(
-        "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {:?}.",
+        "Version of the Rust compiler to target. Valid options are: {:?}. Defaults to {}.",
         RUST_TARGET_STRINGS,
-        String::from(RustTarget::default())
+        RustTarget::default()
     )
 }
 
-fn parse_codegen_config(what_to_generate: &str) -> io::Result<CodegenConfig> {
+fn parse_codegen_config(
+    what_to_generate: &str,
+) -> Result<CodegenConfig, Error> {
     let mut config = CodegenConfig::empty();
     for what in what_to_generate.split(',') {
         match what {
@@ -28,9 +32,9 @@
             "constructors" => config.insert(CodegenConfig::CONSTRUCTORS),
             "destructors" => config.insert(CodegenConfig::DESTRUCTORS),
             otherwise => {
-                return Err(Error::new(
-                    ErrorKind::Other,
-                    format!("Unknown generate item: {}", otherwise),
+                return Err(Error::raw(
+                    ErrorKind::InvalidValue,
+                    format!("Unknown codegen item kind: {}", otherwise),
                 ));
             }
         }
@@ -39,10 +43,54 @@
     Ok(config)
 }
 
+fn parse_rustfmt_config_path(path_str: &str) -> Result<PathBuf, Error> {
+    let path = Path::new(path_str);
+
+    if !path.is_absolute() {
+        return Err(Error::raw(
+            ErrorKind::InvalidValue,
+            "--rustfmt-configuration-file needs to be an absolute path!",
+        ));
+    }
+
+    if path.to_str().is_none() {
+        return Err(Error::raw(
+            ErrorKind::InvalidUtf8,
+            "--rustfmt-configuration-file contains non-valid UTF8 characters.",
+        ));
+    }
+
+    Ok(path.to_path_buf())
+}
+
+fn parse_abi_override(abi_override: &str) -> Result<(Abi, String), Error> {
+    let (regex, abi_str) = abi_override
+        .rsplit_once('=')
+        .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?;
+
+    let abi = abi_str
+        .parse()
+        .map_err(|err| Error::raw(ErrorKind::InvalidValue, err))?;
+
+    Ok((abi, regex.to_owned()))
+}
+
+fn parse_custom_derive(
+    custom_derive: &str,
+) -> Result<(Vec<String>, String), Error> {
+    let (regex, derives) = custom_derive
+        .rsplit_once('=')
+        .ok_or_else(|| Error::raw(ErrorKind::InvalidValue, "Missing `=`"))?;
+
+    let derives = derives.split(',').map(|s| s.to_owned()).collect();
+
+    Ok((derives, regex.to_owned()))
+}
+
 #[derive(Parser, Debug)]
 #[clap(
     about = "Generates Rust bindings from C/C++ headers.",
-    override_usage = "bindgen [FLAGS] [OPTIONS] [HEADER] -- [CLANG_ARGS]...",
+    override_usage = "bindgen <FLAGS> <OPTIONS> <HEADER> -- <CLANG_ARGS>...",
     trailing_var_arg = true
 )]
 struct BindgenCommand {
@@ -51,8 +99,8 @@
     /// Path to write depfile to.
     #[arg(long)]
     depfile: Option<String>,
-    /// The default style of code used to generate enums.
-    #[arg(long, value_name = "VARIANT")]
+    /// The default STYLE of code used to generate enums.
+    #[arg(long, value_name = "STYLE")]
     default_enum_style: Option<EnumVariation>,
     /// Mark any enum whose name matches REGEX as a set of bitfield flags.
     #[arg(long, value_name = "REGEX")]
@@ -72,11 +120,11 @@
     /// 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")]
+    /// The default signed/unsigned TYPE for C macro constants.
+    #[arg(long, value_name = "TYPE")]
     default_macro_constant_type: Option<MacroTypeVariation>,
-    /// The default style of code used to generate typedefs.
-    #[arg(long, value_name = "VARIANT")]
+    /// The default STYLE of code used to generate typedefs.
+    #[arg(long, value_name = "STYLE")]
     default_alias_style: Option<AliasVariation>,
     /// Mark any typedef alias whose name matches REGEX to use normal type aliasing.
     #[arg(long, value_name = "REGEX")]
@@ -87,7 +135,7 @@
     /// 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.
+    /// 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.
@@ -156,6 +204,9 @@
     /// Generate block signatures instead of void pointers.
     #[arg(long)]
     generate_block: bool,
+    /// Generate string constants as `&CStr` instead of `&[u8]`.
+    #[arg(long)]
+    generate_cstr: bool,
     /// Use extern crate instead of use for block.
     #[arg(long)]
     block_extern_crate: bool,
@@ -165,10 +216,10 @@
     /// 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.
+    /// 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.
+    /// 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
@@ -180,7 +231,7 @@
     /// Output our internal IR for debugging purposes.
     #[arg(long)]
     emit_ir: bool,
-    /// Dump graphviz dot file.
+    /// Dump a graphviz dot file to PATH.
     #[arg(long, value_name = "PATH")]
     emit_ir_graphviz: Option<String>,
     /// Enable support for C++ namespaces.
@@ -228,8 +279,8 @@
     /// 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"])]
+    /// Add a RAW_LINE of Rust code to a given module with name MODULE_NAME.
+    #[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>,
@@ -254,6 +305,9 @@
     /// Allowlist all contents of PATH.
     #[arg(long, value_name = "PATH")]
     allowlist_file: Vec<String>,
+    /// Allowlist all items matching REGEX. Other non-allowlisted items will not be generated.
+    #[arg(long, value_name = "REGEX")]
+    allowlist_item: Vec<String>,
     /// Print verbose error messages.
     #[arg(long)]
     verbose: bool,
@@ -270,16 +324,16 @@
     /// `--formatter=none` instead.
     #[arg(long)]
     no_rustfmt_bindings: bool,
-    /// Which tool should be used to format the bindings
+    /// Which FORMATTER should be used for the bindings
     #[arg(
         long,
         value_name = "FORMATTER",
         conflicts_with = "no_rustfmt_bindings"
     )]
     formatter: Option<Formatter>,
-    /// The absolute path to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter sets `formatter` to `rustfmt`.
-    #[arg(long, value_name = "PATH", conflicts_with = "no_rustfmt_bindings")]
-    rustfmt_configuration_file: Option<String>,
+    /// The absolute PATH to the rustfmt configuration file. The configuration file will be used for formatting the bindings. This parameter sets `formatter` to `rustfmt`.
+    #[arg(long, value_name = "PATH", conflicts_with = "no_rustfmt_bindings", value_parser=parse_rustfmt_config_path)]
+    rustfmt_configuration_file: Option<PathBuf>,
     /// Avoid deriving PartialEq for types matching REGEX.
     #[arg(long, value_name = "REGEX")]
     no_partialeq: Vec<String>,
@@ -304,10 +358,10 @@
     /// 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
+    /// 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.
+    /// 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.
@@ -337,42 +391,45 @@
     /// 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, efiapi, fastcall, thiscall, aapcs, win64 or C-unwind.
-    #[arg(long, value_name = "OVERRIDE")]
-    override_abi: Vec<String>,
+    /// 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, efiapi, fastcall, thiscall, aapcs, win64 or C-unwind<.>
+    #[arg(long, value_name = "OVERRIDE", value_parser = parse_abi_override)]
+    override_abi: Vec<(Abi, 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>,
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom: Vec<(Vec<String>, 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>,
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom_struct: Vec<(Vec<String>, 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>,
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom_enum: Vec<(Vec<String>, 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>,
+    #[arg(long, value_name = "CUSTOM", value_parser = parse_custom_derive)]
+    with_derive_custom_union: Vec<(Vec<String>, 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
+    /// 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
+    /// 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>,
-    /// Set the default visibility of fields, including bitfields and accessor methods for
+    /// Set the default VISIBILITY of fields, including bitfields and accessor methods for
     /// bitfields. This flag is ignored if the `--respect-cxx-access-specs` flag is used.
     #[arg(long, value_name = "VISIBILITY")]
     default_visibility: Option<FieldVisibilityKind>,
     /// Whether to emit diagnostics or not.
     #[arg(long, requires = "experimental")]
     emit_diagnostics: bool,
+    /// Generates completions for the specified SHELL, sends them to `stdout` and exits.
+    #[arg(long, value_name = "SHELL")]
+    generate_shell_completions: Option<clap_complete::Shell>,
     /// Enables experimental features.
     #[arg(long)]
     experimental: bool,
@@ -430,6 +487,7 @@
         no_recursive_allowlist,
         objc_extern_crate,
         generate_block,
+        generate_cstr,
         block_extern_crate,
         distrust_clang_mangling,
         builtins,
@@ -463,6 +521,7 @@
         allowlist_type,
         allowlist_var,
         allowlist_file,
+        allowlist_item,
         verbose,
         dump_preprocessed_input,
         no_record_matches,
@@ -500,15 +559,27 @@
         wrap_static_fns_suffix,
         default_visibility,
         emit_diagnostics,
+        generate_shell_completions,
         experimental: _,
         version,
         clang_args,
     } = command;
 
+    if let Some(shell) = generate_shell_completions {
+        clap_complete::generate(
+            shell,
+            &mut BindgenCommand::command(),
+            "bindgen",
+            &mut std::io::stdout(),
+        );
+
+        exit(0);
+    }
+
     if version {
         println!(
             "bindgen {}",
-            Some("0.65.1").unwrap_or("unknown")
+            Some("0.69.1").unwrap_or("unknown")
         );
         if verbose {
             println!("Clang: {}", bindgen::clang_version().full);
@@ -521,7 +592,7 @@
     if let Some(header) = header {
         builder = builder.header(header);
     } else {
-        return Err(Error::new(ErrorKind::Other, "Header not found"));
+        return Err(io::Error::new(io::ErrorKind::Other, "Header not found"));
     }
 
     if let Some(rust_target) = rust_target {
@@ -755,6 +826,10 @@
         builder = builder.generate_block(true);
     }
 
+    if generate_cstr {
+        builder = builder.generate_cstr(true);
+    }
+
     if block_extern_crate {
         builder = builder.block_extern_crate(true);
     }
@@ -805,6 +880,10 @@
         builder = builder.allowlist_file(file);
     }
 
+    for item in allowlist_item {
+        builder = builder.allowlist_item(item);
+    }
+
     for arg in clang_args {
         builder = builder.clang_arg(arg);
     }
@@ -842,23 +921,7 @@
         builder = builder.formatter(formatter);
     }
 
-    if let Some(path_str) = rustfmt_configuration_file {
-        let path = PathBuf::from(path_str);
-
-        if !path.is_absolute() {
-            return Err(Error::new(
-                ErrorKind::Other,
-                "--rustfmt-configuration--file needs to be an absolute path!",
-            ));
-        }
-
-        if path.to_str().is_none() {
-            return Err(Error::new(
-                ErrorKind::Other,
-                "--rustfmt-configuration-file contains non-valid UTF8 characters.",
-            ));
-        }
-
+    if let Some(path) = rustfmt_configuration_file {
         builder = builder.rustfmt_configuration_file(Some(path));
     }
 
@@ -944,13 +1007,7 @@
         builder = builder.merge_extern_blocks(true);
     }
 
-    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));
+    for (abi, regex) in override_abi {
         builder = builder.override_abi(abi, regex);
     }
 
@@ -1020,12 +1077,7 @@
         ),
     ] {
         let name = emit_diagnostics.then_some(name);
-        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();
-
+        for (derives, regex) in custom_derives {
             let mut regex_set = RegexSet::new();
             regex_set.insert(regex);
             regex_set.build_with_diagnostics(false, name);