//! Generate Rust bindings for C and C++ libraries.
//!
//! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
//! functions and use types defined in the header.
//!
//! See the [`Builder`](./struct.Builder.html) struct for usage.
//!
//! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for
//! additional documentation.
#![deny(missing_docs)]
#![deny(unused_extern_crates)]
// To avoid rather annoying warnings when matching with CXCursor_xxx as a
// constant.
#![allow(non_upper_case_globals)]
// `quote!` nests quite deeply.
#![recursion_limit = "128"]

#[macro_use]
extern crate bitflags;
#[macro_use]
extern crate lazy_static;
#[macro_use]
extern crate quote;

#[cfg(feature = "logging")]
#[macro_use]
extern crate log;

#[cfg(not(feature = "logging"))]
#[macro_use]
mod log_stubs;

#[macro_use]
mod extra_assertions;

// A macro to declare an internal module for which we *must* provide
// documentation for. If we are building with the "testing_only_docs" feature,
// then the module is declared public, and our `#![deny(missing_docs)]` pragma
// applies to it. This feature is used in CI, so we won't let anything slip by
// undocumented. Normal builds, however, will leave the module private, so that
// we don't expose internals to library consumers.
macro_rules! doc_mod {
    ($m:ident, $doc_mod_name:ident) => {
        #[cfg(feature = "testing_only_docs")]
        pub mod $doc_mod_name {
            //! Autogenerated documentation module.
            pub use super::$m::*;
        }
    };
}

mod clang;
mod codegen;
mod deps;
mod features;
mod ir;
mod parse;
mod regex_set;
mod time;

pub mod callbacks;

doc_mod!(clang, clang_docs);
doc_mod!(features, features_docs);
doc_mod!(ir, ir_docs);
doc_mod!(parse, parse_docs);
doc_mod!(regex_set, regex_set_docs);

pub use crate::codegen::{AliasVariation, EnumVariation, MacroTypeVariation};
use crate::features::RustFeatures;
pub use crate::features::{
    RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS,
};
use crate::ir::context::{BindgenContext, ItemId};
use crate::ir::item::Item;
use crate::parse::{ClangItemParser, ParseError};
use crate::regex_set::RegexSet;

use std::borrow::Cow;
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
use std::{env, iter};

// Some convenient typedefs for a fast hash map and hash set.
type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;
type HashSet<K> = ::rustc_hash::FxHashSet<K>;
pub(crate) use std::collections::hash_map::Entry;

/// Default prefix for the anon fields.
pub const DEFAULT_ANON_FIELDS_PREFIX: &str = "__bindgen_anon_";

fn file_is_cpp(name_file: &str) -> bool {
    name_file.ends_with(".hpp") ||
        name_file.ends_with(".hxx") ||
        name_file.ends_with(".hh") ||
        name_file.ends_with(".h++")
}

fn args_are_cpp(clang_args: &[String]) -> bool {
    for w in clang_args.windows(2) {
        if w[0] == "-xc++" || w[1] == "-xc++" {
            return true;
        }
        if w[0] == "-x" && w[1] == "c++" {
            return true;
        }
        if w[0] == "-include" && file_is_cpp(&w[1]) {
            return true;
        }
    }
    false
}

bitflags! {
    /// A type used to indicate which kind of items we have to generate.
    pub struct CodegenConfig: u32 {
        /// Whether to generate functions.
        const FUNCTIONS = 1 << 0;
        /// Whether to generate types.
        const TYPES = 1 << 1;
        /// Whether to generate constants.
        const VARS = 1 << 2;
        /// Whether to generate methods.
        const METHODS = 1 << 3;
        /// Whether to generate constructors
        const CONSTRUCTORS = 1 << 4;
        /// Whether to generate destructors.
        const DESTRUCTORS = 1 << 5;
    }
}

impl CodegenConfig {
    /// Returns true if functions should be generated.
    pub fn functions(self) -> bool {
        self.contains(CodegenConfig::FUNCTIONS)
    }

    /// Returns true if types should be generated.
    pub fn types(self) -> bool {
        self.contains(CodegenConfig::TYPES)
    }

    /// Returns true if constants should be generated.
    pub fn vars(self) -> bool {
        self.contains(CodegenConfig::VARS)
    }

    /// Returns true if methds should be generated.
    pub fn methods(self) -> bool {
        self.contains(CodegenConfig::METHODS)
    }

    /// Returns true if constructors should be generated.
    pub fn constructors(self) -> bool {
        self.contains(CodegenConfig::CONSTRUCTORS)
    }

    /// Returns true if destructors should be generated.
    pub fn destructors(self) -> bool {
        self.contains(CodegenConfig::DESTRUCTORS)
    }
}

impl Default for CodegenConfig {
    fn default() -> Self {
        CodegenConfig::all()
    }
}

/// Configure and generate Rust bindings for a C/C++ header.
///
/// This is the main entry point to the library.
///
/// ```ignore
/// use bindgen::builder;
///
/// // Configure and generate bindings.
/// let bindings = builder().header("path/to/input/header")
///     .allowlist_type("SomeCoolClass")
///     .allowlist_function("do_some_cool_thing")
///     .generate()?;
///
/// // Write the generated bindings to an output file.
/// bindings.write_to_file("path/to/output.rs")?;
/// ```
///
/// # Enums
///
/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
/// the pattern passed to several methods:
///
/// 1. [`constified_enum_module()`](#method.constified_enum_module)
/// 2. [`bitfield_enum()`](#method.bitfield_enum)
/// 3. [`newtype_enum()`](#method.newtype_enum)
/// 4. [`rustified_enum()`](#method.rustified_enum)
///
/// For each C enum, bindgen tries to match the pattern in the following order:
///
/// 1. Constified enum module
/// 2. Bitfield enum
/// 3. Newtype enum
/// 4. Rustified enum
///
/// If none of the above patterns match, then bindgen will generate a set of Rust constants.
///
/// # Clang arguments
///
/// Extra arguments can be passed to with clang:
/// 1. [`clang_arg()`](#method.clang_arg): takes a single argument
/// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments
/// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate
///    environment variable of arguments
///
/// Clang arguments specific to your crate should be added via the
/// `clang_arg()`/`clang_args()` methods.
///
/// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to
/// add additional arguments. For example, to build against a different sysroot a user could set
/// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`.
#[derive(Debug, Default)]
pub struct Builder {
    options: BindgenOptions,
    input_headers: Vec<String>,
    // Tuples of unsaved file contents of the form (name, contents).
    input_header_contents: Vec<(String, String)>,
}

/// Construct a new [`Builder`](./struct.Builder.html).
pub fn builder() -> Builder {
    Default::default()
}

impl Builder {
    /// Generates the command line flags use for creating `Builder`.
    pub fn command_line_flags(&self) -> Vec<String> {
        let mut output_vector: Vec<String> = Vec::new();

        if let Some(header) = self.input_headers.last().cloned() {
            // Positional argument 'header'
            output_vector.push(header);
        }

        output_vector.push("--rust-target".into());
        output_vector.push(self.options.rust_target.into());

        // FIXME(emilio): This is a bit hacky, maybe we should stop re-using the
        // RustFeatures to store the "disable_untagged_union" call, and make it
        // a different flag that we check elsewhere / in generate().
        if !self.options.rust_features.untagged_union &&
            RustFeatures::from(self.options.rust_target).untagged_union
        {
            output_vector.push("--disable-untagged-union".into());
        }

        if self.options.default_enum_style != Default::default() {
            output_vector.push("--default-enum-style".into());
            output_vector.push(
                match self.options.default_enum_style {
                    codegen::EnumVariation::Rust {
                        non_exhaustive: false,
                    } => "rust",
                    codegen::EnumVariation::Rust {
                        non_exhaustive: true,
                    } => "rust_non_exhaustive",
                    codegen::EnumVariation::NewType { is_bitfield: true } => {
                        "bitfield"
                    }
                    codegen::EnumVariation::NewType { is_bitfield: false } => {
                        "newtype"
                    }
                    codegen::EnumVariation::Consts => "consts",
                    codegen::EnumVariation::ModuleConsts => "moduleconsts",
                }
                .into(),
            )
        }

        if self.options.default_macro_constant_type != Default::default() {
            output_vector.push("--default-macro-constant-type".into());
            output_vector
                .push(self.options.default_macro_constant_type.as_str().into());
        }

        if self.options.default_alias_style != Default::default() {
            output_vector.push("--default-alias-style".into());
            output_vector
                .push(self.options.default_alias_style.as_str().into());
        }

        let regex_sets = &[
            (&self.options.bitfield_enums, "--bitfield-enum"),
            (&self.options.newtype_enums, "--newtype-enum"),
            (&self.options.rustified_enums, "--rustified-enum"),
            (
                &self.options.rustified_non_exhaustive_enums,
                "--rustified-enum-non-exhaustive",
            ),
            (
                &self.options.constified_enum_modules,
                "--constified-enum-module",
            ),
            (&self.options.constified_enums, "--constified-enum"),
            (&self.options.type_alias, "--type-alias"),
            (&self.options.new_type_alias, "--new-type-alias"),
            (&self.options.new_type_alias_deref, "--new-type-alias-deref"),
            (&self.options.blocklisted_types, "--blocklist-type"),
            (&self.options.blocklisted_functions, "--blocklist-function"),
            (&self.options.blocklisted_items, "--blocklist-item"),
            (&self.options.blocklisted_files, "--blocklist-file"),
            (&self.options.opaque_types, "--opaque-type"),
            (&self.options.allowlisted_functions, "--allowlist-function"),
            (&self.options.allowlisted_types, "--allowlist-type"),
            (&self.options.allowlisted_vars, "--allowlist-var"),
            (&self.options.no_partialeq_types, "--no-partialeq"),
            (&self.options.no_copy_types, "--no-copy"),
            (&self.options.no_debug_types, "--no-debug"),
            (&self.options.no_default_types, "--no-default"),
            (&self.options.no_hash_types, "--no-hash"),
            (&self.options.must_use_types, "--must-use-type"),
        ];

        for (set, flag) in regex_sets {
            for item in set.get_items() {
                output_vector.push((*flag).to_owned());
                output_vector.push(item.to_owned());
            }
        }

        if !self.options.layout_tests {
            output_vector.push("--no-layout-tests".into());
        }

        if self.options.impl_debug {
            output_vector.push("--impl-debug".into());
        }

        if self.options.impl_partialeq {
            output_vector.push("--impl-partialeq".into());
        }

        if !self.options.derive_copy {
            output_vector.push("--no-derive-copy".into());
        }

        if !self.options.derive_debug {
            output_vector.push("--no-derive-debug".into());
        }

        if !self.options.derive_default {
            output_vector.push("--no-derive-default".into());
        } else {
            output_vector.push("--with-derive-default".into());
        }

        if self.options.derive_hash {
            output_vector.push("--with-derive-hash".into());
        }

        if self.options.derive_partialord {
            output_vector.push("--with-derive-partialord".into());
        }

        if self.options.derive_ord {
            output_vector.push("--with-derive-ord".into());
        }

        if self.options.derive_partialeq {
            output_vector.push("--with-derive-partialeq".into());
        }

        if self.options.derive_eq {
            output_vector.push("--with-derive-eq".into());
        }

        if self.options.time_phases {
            output_vector.push("--time-phases".into());
        }

        if !self.options.generate_comments {
            output_vector.push("--no-doc-comments".into());
        }

        if !self.options.allowlist_recursively {
            output_vector.push("--no-recursive-allowlist".into());
        }

        if self.options.objc_extern_crate {
            output_vector.push("--objc-extern-crate".into());
        }

        if self.options.generate_block {
            output_vector.push("--generate-block".into());
        }

        if self.options.block_extern_crate {
            output_vector.push("--block-extern-crate".into());
        }

        if self.options.builtins {
            output_vector.push("--builtins".into());
        }

        if let Some(ref prefix) = self.options.ctypes_prefix {
            output_vector.push("--ctypes-prefix".into());
            output_vector.push(prefix.clone());
        }

        if self.options.anon_fields_prefix != DEFAULT_ANON_FIELDS_PREFIX {
            output_vector.push("--anon-fields-prefix".into());
            output_vector.push(self.options.anon_fields_prefix.clone());
        }

        if self.options.emit_ast {
            output_vector.push("--emit-clang-ast".into());
        }

        if self.options.emit_ir {
            output_vector.push("--emit-ir".into());
        }
        if let Some(ref graph) = self.options.emit_ir_graphviz {
            output_vector.push("--emit-ir-graphviz".into());
            output_vector.push(graph.clone())
        }
        if self.options.enable_cxx_namespaces {
            output_vector.push("--enable-cxx-namespaces".into());
        }
        if self.options.enable_function_attribute_detection {
            output_vector.push("--enable-function-attribute-detection".into());
        }
        if self.options.disable_name_namespacing {
            output_vector.push("--disable-name-namespacing".into());
        }
        if self.options.disable_nested_struct_naming {
            output_vector.push("--disable-nested-struct-naming".into());
        }

        if self.options.disable_header_comment {
            output_vector.push("--disable-header-comment".into());
        }

        if !self.options.codegen_config.functions() {
            output_vector.push("--ignore-functions".into());
        }

        output_vector.push("--generate".into());

        //Temporary placeholder for below 4 options
        let mut options: Vec<String> = Vec::new();
        if self.options.codegen_config.functions() {
            options.push("functions".into());
        }
        if self.options.codegen_config.types() {
            options.push("types".into());
        }
        if self.options.codegen_config.vars() {
            options.push("vars".into());
        }
        if self.options.codegen_config.methods() {
            options.push("methods".into());
        }
        if self.options.codegen_config.constructors() {
            options.push("constructors".into());
        }
        if self.options.codegen_config.destructors() {
            options.push("destructors".into());
        }

        output_vector.push(options.join(","));

        if !self.options.codegen_config.methods() {
            output_vector.push("--ignore-methods".into());
        }

        if !self.options.convert_floats {
            output_vector.push("--no-convert-floats".into());
        }

        if !self.options.prepend_enum_name {
            output_vector.push("--no-prepend-enum-name".into());
        }

        if self.options.fit_macro_constants {
            output_vector.push("--fit-macro-constant-types".into());
        }

        if self.options.array_pointers_in_arguments {
            output_vector.push("--use-array-pointers-in-arguments".into());
        }

        if let Some(ref wasm_import_module_name) =
            self.options.wasm_import_module_name
        {
            output_vector.push("--wasm-import-module-name".into());
            output_vector.push(wasm_import_module_name.clone());
        }

        for line in &self.options.raw_lines {
            output_vector.push("--raw-line".into());
            output_vector.push(line.clone());
        }

        for (module, lines) in &self.options.module_lines {
            for line in lines.iter() {
                output_vector.push("--module-raw-line".into());
                output_vector.push(module.clone());
                output_vector.push(line.clone());
            }
        }

        if self.options.use_core {
            output_vector.push("--use-core".into());
        }

        if self.options.conservative_inline_namespaces {
            output_vector.push("--conservative-inline-namespaces".into());
        }

        if self.options.generate_inline_functions {
            output_vector.push("--generate-inline-functions".into());
        }

        if !self.options.record_matches {
            output_vector.push("--no-record-matches".into());
        }

        if self.options.size_t_is_usize {
            output_vector.push("--size_t-is-usize".into());
        }

        if !self.options.rustfmt_bindings {
            output_vector.push("--no-rustfmt-bindings".into());
        }

        if let Some(path) = self
            .options
            .rustfmt_configuration_file
            .as_ref()
            .and_then(|f| f.to_str())
        {
            output_vector.push("--rustfmt-configuration-file".into());
            output_vector.push(path.into());
        }

        if let Some(ref name) = self.options.dynamic_library_name {
            output_vector.push("--dynamic-loading".into());
            output_vector.push(name.clone());
        }

        if self.options.dynamic_link_require_all {
            output_vector.push("--dynamic-link-require-all".into());
        }

        if self.options.respect_cxx_access_specs {
            output_vector.push("--respect-cxx-access-specs".into());
        }

        if self.options.translate_enum_integer_types {
            output_vector.push("--translate-enum-integer-types".into());
        }

        if self.options.c_naming {
            output_vector.push("--c-naming".into());
        }

        if self.options.force_explicit_padding {
            output_vector.push("--explicit-padding".into());
        }

        // Add clang arguments

        output_vector.push("--".into());

        if !self.options.clang_args.is_empty() {
            output_vector.extend(self.options.clang_args.iter().cloned());
        }

        if self.input_headers.len() > 1 {
            // To pass more than one header, we need to pass all but the last
            // header via the `-include` clang arg
            for header in &self.input_headers[..self.input_headers.len() - 1] {
                output_vector.push("-include".to_string());
                output_vector.push(header.clone());
            }
        }

        output_vector
    }

    /// Add an input C/C++ header to generate bindings for.
    ///
    /// This can be used to generate bindings to a single header:
    ///
    /// ```ignore
    /// let bindings = bindgen::Builder::default()
    ///     .header("input.h")
    ///     .generate()
    ///     .unwrap();
    /// ```
    ///
    /// Or you can invoke it multiple times to generate bindings to multiple
    /// headers:
    ///
    /// ```ignore
    /// let bindings = bindgen::Builder::default()
    ///     .header("first.h")
    ///     .header("second.h")
    ///     .header("third.h")
    ///     .generate()
    ///     .unwrap();
    /// ```
    pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
        self.input_headers.push(header.into());
        self
    }

    /// Add a depfile output which will be written alongside the generated bindings.
    pub fn depfile<H: Into<String>, D: Into<PathBuf>>(
        mut self,
        output_module: H,
        depfile: D,
    ) -> Builder {
        self.options.depfile = Some(deps::DepfileSpec {
            output_module: output_module.into(),
            depfile_path: depfile.into(),
        });
        self
    }

    /// Add `contents` as an input C/C++ header named `name`.
    ///
    /// The file `name` will be added to the clang arguments.
    pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
        // Apparently clang relies on having virtual FS correspondent to
        // the real one, so we need absolute paths here
        let absolute_path = env::current_dir()
            .expect("Cannot retrieve current directory")
            .join(name)
            .to_str()
            .expect("Cannot convert current directory name to string")
            .to_owned();
        self.input_header_contents
            .push((absolute_path, contents.into()));
        self
    }

    /// Specify the rust target
    ///
    /// The default is the latest stable Rust version
    pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
        self.options.set_rust_target(rust_target);
        self
    }

    /// Disable support for native Rust unions, if supported.
    pub fn disable_untagged_union(mut self) -> Self {
        self.options.rust_features.untagged_union = false;
        self
    }

    /// Disable insertion of bindgen's version identifier into generated
    /// bindings.
    pub fn disable_header_comment(mut self) -> Self {
        self.options.disable_header_comment = true;
        self
    }

    /// Set the output graphviz file.
    pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
        let path = path.into();
        self.options.emit_ir_graphviz = Some(path);
        self
    }

    /// Whether the generated bindings should contain documentation comments
    /// (docstrings) or not. This is set to true by default.
    ///
    /// Note that clang by default excludes comments from system headers, pass
    /// `-fretain-comments-from-system-headers` as
    /// [`clang_arg`][Builder::clang_arg] to include them. It can also be told
    /// to process all comments (not just documentation ones) using the
    /// `-fparse-all-comments` flag. See [slides on clang comment parsing](
    /// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for
    /// background and examples.
    pub fn generate_comments(mut self, doit: bool) -> Self {
        self.options.generate_comments = doit;
        self
    }

    /// Whether to allowlist recursively or not. Defaults to true.
    ///
    /// Given that we have explicitly allowlisted the "initiate_dance_party"
    /// function in this C header:
    ///
    /// ```c
    /// typedef struct MoonBoots {
    ///     int bouncy_level;
    /// } MoonBoots;
    ///
    /// void initiate_dance_party(MoonBoots* boots);
    /// ```
    ///
    /// We would normally generate bindings to both the `initiate_dance_party`
    /// function and the `MoonBoots` struct that it transitively references. By
    /// configuring with `allowlist_recursively(false)`, `bindgen` will not emit
    /// bindings for anything except the explicitly allowlisted items, and there
    /// would be no emitted struct definition for `MoonBoots`. However, the
    /// `initiate_dance_party` function would still reference `MoonBoots`!
    ///
    /// **Disabling this feature will almost certainly cause `bindgen` to emit
    /// bindings that will not compile!** If you disable this feature, then it
    /// is *your* responsibility to provide definitions for every type that is
    /// referenced from an explicitly allowlisted item. One way to provide the
    /// definitions is by using the [`Builder::raw_line`](#method.raw_line)
    /// method, another would be to define them in Rust and then `include!(...)`
    /// the bindings immediately afterwards.
    pub fn allowlist_recursively(mut self, doit: bool) -> Self {
        self.options.allowlist_recursively = doit;
        self
    }

    /// Deprecated alias for allowlist_recursively.
    #[deprecated(note = "Use allowlist_recursively instead")]
    pub fn whitelist_recursively(self, doit: bool) -> Self {
        self.allowlist_recursively(doit)
    }

    /// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
    /// in the prologue of the files generated from objective-c files
    pub fn objc_extern_crate(mut self, doit: bool) -> Self {
        self.options.objc_extern_crate = doit;
        self
    }

    /// Generate proper block signatures instead of void pointers.
    pub fn generate_block(mut self, doit: bool) -> Self {
        self.options.generate_block = doit;
        self
    }

    /// Generate `#[macro_use] extern crate block;` instead of `use block;`
    /// in the prologue of the files generated from apple block files
    pub fn block_extern_crate(mut self, doit: bool) -> Self {
        self.options.block_extern_crate = doit;
        self
    }

    /// Whether to use the clang-provided name mangling. This is true by default
    /// and probably needed for C++ features.
    ///
    /// However, some old libclang versions seem to return incorrect results in
    /// some cases for non-mangled functions, see [1], so we allow disabling it.
    ///
    /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
    pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
        self.options.enable_mangling = doit;
        self
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "Use blocklist_type instead")]
    pub fn hide_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.blocklist_type(arg)
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "Use blocklist_type instead")]
    pub fn blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.blocklist_type(arg)
    }

    /// Hide the given type from the generated bindings. Regular expressions are
    /// supported.
    ///
    /// To blocklist types prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_types.insert(arg);
        self
    }

    /// Hide the given function from the generated bindings. Regular expressions
    /// are supported.
    #[deprecated(note = "Use blocklist_function instead")]
    pub fn blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder {
        self.blocklist_function(arg)
    }

    /// Hide the given function from the generated bindings. Regular expressions
    /// are supported.
    ///
    /// To blocklist functions prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_functions.insert(arg);
        self
    }

    /// Hide the given item from the generated bindings, regardless of
    /// whether it's a type, function, module, etc. Regular
    /// expressions are supported.
    #[deprecated(note = "Use blocklist_item instead")]
    pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_items.insert(arg);
        self
    }

    /// Hide the given item from the generated bindings, regardless of
    /// whether it's a type, function, module, etc. Regular
    /// expressions are supported.
    ///
    /// To blocklist items prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_items.insert(arg);
        self
    }

    /// Hide any contents of the given file from the generated bindings,
    /// regardless of whether it's a type, function, module etc.
    pub fn blocklist_file<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.blocklisted_files.insert(arg);
        self
    }

    /// Treat the given type as opaque in the generated bindings. Regular
    /// expressions are supported.
    ///
    /// To change types prefixed with "mylib" into opaque, use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.opaque_types.insert(arg);
        self
    }

    /// Allowlist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "use allowlist_type instead")]
    pub fn whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_type(arg)
    }

    /// Allowlist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    #[deprecated(note = "use allowlist_type instead")]
    pub fn whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_type(arg)
    }

    /// Allowlist the given type so that it (and all types that it transitively
    /// refers to) appears in the generated bindings. Regular expressions are
    /// supported.
    ///
    /// To allowlist types prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.allowlisted_types.insert(arg);
        self
    }

    /// Allowlist the given function so that it (and all types that it
    /// transitively refers to) appears in the generated bindings. Regular
    /// expressions are supported.
    ///
    /// To allowlist functions prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.allowlisted_functions.insert(arg);
        self
    }

    /// Allowlist the given function.
    ///
    /// Deprecated: use allowlist_function instead.
    #[deprecated(note = "use allowlist_function instead")]
    pub fn whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_function(arg)
    }

    /// Allowlist the given function.
    ///
    /// Deprecated: use allowlist_function instead.
    #[deprecated(note = "use allowlist_function instead")]
    pub fn whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_function(arg)
    }

    /// Allowlist the given variable so that it (and all types that it
    /// transitively refers to) appears in the generated bindings. Regular
    /// expressions are supported.
    ///
    /// To allowlist variables prefixed with "mylib" use `"mylib_.*"`.
    /// For more complicated expressions check
    /// [regex](https://docs.rs/regex/*/regex/) docs
    pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.allowlisted_vars.insert(arg);
        self
    }

    /// Deprecated: use allowlist_var instead.
    #[deprecated(note = "use allowlist_var instead")]
    pub fn whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_var(arg)
    }

    /// Allowlist the given variable.
    ///
    /// Deprecated: use allowlist_var instead.
    #[deprecated(note = "use allowlist_var instead")]
    pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
        self.allowlist_var(arg)
    }

    /// Set the default style of code to generate for enums
    pub fn default_enum_style(
        mut self,
        arg: codegen::EnumVariation,
    ) -> Builder {
        self.options.default_enum_style = arg;
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as being
    /// bitfield-like. Regular expressions are supported.
    ///
    /// This makes bindgen generate a type that isn't a rust `enum`. Regular
    /// expressions are supported.
    ///
    /// This is similar to the newtype enum style, but with the bitwise
    /// operators implemented.
    pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.bitfield_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a newtype.
    /// Regular expressions are supported.
    ///
    /// This makes bindgen generate a type that isn't a Rust `enum`. Regular
    /// expressions are supported.
    pub fn newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.newtype_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a Rust
    /// enum.
    ///
    /// This makes bindgen generate enums instead of constants. Regular
    /// expressions are supported.
    ///
    /// **Use this with caution**, creating this in unsafe code
    /// (including FFI) with an invalid value will invoke undefined behaviour.
    /// You may want to use the newtype enum style instead.
    pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.rustified_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a Rust
    /// enum with the `#[non_exhaustive]` attribute.
    ///
    /// This makes bindgen generate enums instead of constants. Regular
    /// expressions are supported.
    ///
    /// **Use this with caution**, creating this in unsafe code
    /// (including FFI) with an invalid value will invoke undefined behaviour.
    /// You may want to use the newtype enum style instead.
    pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(
        mut self,
        arg: T,
    ) -> Builder {
        self.options.rustified_non_exhaustive_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a set of
    /// constants that are not to be put into a module.
    pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.constified_enums.insert(arg);
        self
    }

    /// Mark the given enum (or set of enums, if using a pattern) as a set of
    /// constants that should be put into a module.
    ///
    /// This makes bindgen generate modules containing constants instead of
    /// just constants. Regular expressions are supported.
    pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.constified_enum_modules.insert(arg);
        self
    }

    /// Set the default type for macro constants
    pub fn default_macro_constant_type(
        mut self,
        arg: codegen::MacroTypeVariation,
    ) -> Builder {
        self.options.default_macro_constant_type = arg;
        self
    }

    /// Set the default style of code to generate for typedefs
    pub fn default_alias_style(
        mut self,
        arg: codegen::AliasVariation,
    ) -> Builder {
        self.options.default_alias_style = arg;
        self
    }

    /// Mark the given typedef alias (or set of aliases, if using a pattern) to
    /// use regular Rust type aliasing.
    ///
    /// This is the default behavior and should be used if `default_alias_style`
    /// was set to NewType or NewTypeDeref and you want to override it for a
    /// set of typedefs.
    pub fn type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.type_alias.insert(arg);
        self
    }

    /// Mark the given typedef alias (or set of aliases, if using a pattern) to
    /// be generated as a new type by having the aliased type be wrapped in a
    /// #[repr(transparent)] struct.
    ///
    /// Used to enforce stricter type checking.
    pub fn new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.new_type_alias.insert(arg);
        self
    }

    /// Mark the given typedef alias (or set of aliases, if using a pattern) to
    /// be generated as a new type by having the aliased type be wrapped in a
    /// #[repr(transparent)] struct and also have an automatically generated
    /// impl's of `Deref` and `DerefMut` to their aliased type.
    pub fn new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder {
        self.options.new_type_alias_deref.insert(arg);
        self
    }

    /// Add a string to prepend to the generated bindings. The string is passed
    /// through without any modification.
    pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.raw_lines.push(arg.into());
        self
    }

    /// Add a given line to the beginning of module `mod`.
    pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
    where
        T: Into<String>,
        U: Into<String>,
    {
        self.options
            .module_lines
            .entry(mod_.into())
            .or_insert_with(Vec::new)
            .push(line.into());
        self
    }

    /// Add a given set of lines to the beginning of module `mod`.
    pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
    where
        T: Into<String>,
        I: IntoIterator,
        I::Item: Into<String>,
    {
        self.options
            .module_lines
            .entry(mod_.into())
            .or_insert_with(Vec::new)
            .extend(lines.into_iter().map(Into::into));
        self
    }

    /// Add an argument to be passed straight through to clang.
    pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.clang_args.push(arg.into());
        self
    }

    /// Add arguments to be passed straight through to clang.
    pub fn clang_args<I>(mut self, iter: I) -> Builder
    where
        I: IntoIterator,
        I::Item: AsRef<str>,
    {
        for arg in iter {
            self = self.clang_arg(arg.as_ref())
        }
        self
    }

    /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
    /// in the generated Rust.
    pub fn emit_builtins(mut self) -> Builder {
        self.options.builtins = true;
        self
    }

    /// Avoid converting floats to `f32`/`f64` by default.
    pub fn no_convert_floats(mut self) -> Self {
        self.options.convert_floats = false;
        self
    }

    /// Set whether layout tests should be generated.
    pub fn layout_tests(mut self, doit: bool) -> Self {
        self.options.layout_tests = doit;
        self
    }

    /// Set whether `Debug` should be implemented, if it can not be derived automatically.
    pub fn impl_debug(mut self, doit: bool) -> Self {
        self.options.impl_debug = doit;
        self
    }

    /// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
    pub fn impl_partialeq(mut self, doit: bool) -> Self {
        self.options.impl_partialeq = doit;
        self
    }

    /// Set whether `Copy` should be derived by default.
    pub fn derive_copy(mut self, doit: bool) -> Self {
        self.options.derive_copy = doit;
        self
    }

    /// Set whether `Debug` should be derived by default.
    pub fn derive_debug(mut self, doit: bool) -> Self {
        self.options.derive_debug = doit;
        self
    }

    /// Set whether `Default` should be derived by default.
    pub fn derive_default(mut self, doit: bool) -> Self {
        self.options.derive_default = doit;
        self
    }

    /// Set whether `Hash` should be derived by default.
    pub fn derive_hash(mut self, doit: bool) -> Self {
        self.options.derive_hash = doit;
        self
    }

    /// Set whether `PartialOrd` should be derived by default.
    /// If we don't compute partialord, we also cannot compute
    /// ord. Set the derive_ord to `false` when doit is `false`.
    pub fn derive_partialord(mut self, doit: bool) -> Self {
        self.options.derive_partialord = doit;
        if !doit {
            self.options.derive_ord = false;
        }
        self
    }

    /// Set whether `Ord` should be derived by default.
    /// We can't compute `Ord` without computing `PartialOrd`,
    /// so we set the same option to derive_partialord.
    pub fn derive_ord(mut self, doit: bool) -> Self {
        self.options.derive_ord = doit;
        self.options.derive_partialord = doit;
        self
    }

    /// Set whether `PartialEq` should be derived by default.
    ///
    /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
    /// `Eq` is also disabled when `doit` is `false`.
    pub fn derive_partialeq(mut self, doit: bool) -> Self {
        self.options.derive_partialeq = doit;
        if !doit {
            self.options.derive_eq = false;
        }
        self
    }

    /// Set whether `Eq` should be derived by default.
    ///
    /// We can't derive `Eq` without also deriving `PartialEq`, so we also
    /// enable deriving `PartialEq` when `doit` is `true`.
    pub fn derive_eq(mut self, doit: bool) -> Self {
        self.options.derive_eq = doit;
        if doit {
            self.options.derive_partialeq = doit;
        }
        self
    }

    /// Set whether or not to time bindgen phases, and print information to
    /// stderr.
    pub fn time_phases(mut self, doit: bool) -> Self {
        self.options.time_phases = doit;
        self
    }

    /// Emit Clang AST.
    pub fn emit_clang_ast(mut self) -> Builder {
        self.options.emit_ast = true;
        self
    }

    /// Emit IR.
    pub fn emit_ir(mut self) -> Builder {
        self.options.emit_ir = true;
        self
    }

    /// Enable C++ namespaces.
    pub fn enable_cxx_namespaces(mut self) -> Builder {
        self.options.enable_cxx_namespaces = true;
        self
    }

    /// Enable detecting must_use attributes on C functions.
    ///
    /// This is quite slow in some cases (see #1465), so it's disabled by
    /// default.
    ///
    /// Note that for this to do something meaningful for now at least, the rust
    /// target version has to have support for `#[must_use]`.
    pub fn enable_function_attribute_detection(mut self) -> Self {
        self.options.enable_function_attribute_detection = true;
        self
    }

    /// Disable name auto-namespacing.
    ///
    /// By default, bindgen mangles names like `foo::bar::Baz` to look like
    /// `foo_bar_Baz` instead of just `Baz`.
    ///
    /// This method disables that behavior.
    ///
    /// Note that this intentionally does not change the names used for
    /// allowlisting and blocklisting, which should still be mangled with the
    /// namespaces.
    ///
    /// Note, also, that this option may cause bindgen to generate duplicate
    /// names.
    pub fn disable_name_namespacing(mut self) -> Builder {
        self.options.disable_name_namespacing = true;
        self
    }

    /// Disable nested struct naming.
    ///
    /// The following structs have different names for C and C++. In case of C
    /// they are visible as `foo` and `bar`. In case of C++ they are visible as
    /// `foo` and `foo::bar`.
    ///
    /// ```c
    /// struct foo {
    ///     struct bar {
    ///     } b;
    /// };
    /// ```
    ///
    /// Bindgen wants to avoid duplicate names by default so it follows C++ naming
    /// and it generates `foo`/`foo_bar` instead of just `foo`/`bar`.
    ///
    /// This method disables this behavior and it is indented to be used only
    /// for headers that were written for C.
    pub fn disable_nested_struct_naming(mut self) -> Builder {
        self.options.disable_nested_struct_naming = true;
        self
    }

    /// Treat inline namespaces conservatively.
    ///
    /// This is tricky, because in C++ is technically legal to override an item
    /// defined in an inline namespace:
    ///
    /// ```cpp
    /// inline namespace foo {
    ///     using Bar = int;
    /// }
    /// using Bar = long;
    /// ```
    ///
    /// Even though referencing `Bar` is a compiler error.
    ///
    /// We want to support this (arguably esoteric) use case, but we don't want
    /// to make the rest of bindgen users pay an usability penalty for that.
    ///
    /// To support this, we need to keep all the inline namespaces around, but
    /// then bindgen usage is a bit more difficult, because you cannot
    /// reference, e.g., `std::string` (you'd need to use the proper inline
    /// namespace).
    ///
    /// We could complicate a lot of the logic to detect name collisions, and if
    /// not detected generate a `pub use inline_ns::*` or something like that.
    ///
    /// That's probably something we can do if we see this option is needed in a
    /// lot of cases, to improve it's usability, but my guess is that this is
    /// not going to be too useful.
    pub fn conservative_inline_namespaces(mut self) -> Builder {
        self.options.conservative_inline_namespaces = true;
        self
    }

    /// Whether inline functions should be generated or not.
    ///
    /// Note that they will usually not work. However you can use
    /// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
    /// responsible of compiling the library to make them callable.
    pub fn generate_inline_functions(mut self, doit: bool) -> Self {
        self.options.generate_inline_functions = doit;
        self
    }

    /// Ignore functions.
    pub fn ignore_functions(mut self) -> Builder {
        self.options.codegen_config.remove(CodegenConfig::FUNCTIONS);
        self
    }

    /// Ignore methods.
    pub fn ignore_methods(mut self) -> Builder {
        self.options.codegen_config.remove(CodegenConfig::METHODS);
        self
    }

    /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
    #[deprecated(note = "please use `rust_target` instead")]
    pub fn unstable_rust(self, doit: bool) -> Self {
        let rust_target = if doit {
            RustTarget::Nightly
        } else {
            LATEST_STABLE_RUST
        };
        self.rust_target(rust_target)
    }

    /// Use core instead of libstd in the generated bindings.
    pub fn use_core(mut self) -> Builder {
        self.options.use_core = true;
        self
    }

    /// Use the given prefix for the raw types instead of `::std::os::raw`.
    pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
        self.options.ctypes_prefix = Some(prefix.into());
        self
    }

    /// Use the given prefix for the anon fields.
    pub fn anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
        self.options.anon_fields_prefix = prefix.into();
        self
    }

    /// Allows configuring types in different situations, see the
    /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
    pub fn parse_callbacks(
        mut self,
        cb: Box<dyn callbacks::ParseCallbacks>,
    ) -> Self {
        self.options.parse_callbacks = Some(cb);
        self
    }

    /// Choose what to generate using a
    /// [`CodegenConfig`](./struct.CodegenConfig.html).
    pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
        self.options.codegen_config = config;
        self
    }

    /// Whether to detect include paths using clang_sys.
    pub fn detect_include_paths(mut self, doit: bool) -> Self {
        self.options.detect_include_paths = doit;
        self
    }

    /// Whether to try to fit macro constants to types smaller than u32/i32
    pub fn fit_macro_constants(mut self, doit: bool) -> Self {
        self.options.fit_macro_constants = doit;
        self
    }

    /// Prepend the enum name to constant or newtype variants.
    pub fn prepend_enum_name(mut self, doit: bool) -> Self {
        self.options.prepend_enum_name = doit;
        self
    }

    /// Set whether `size_t` should be translated to `usize` automatically.
    pub fn size_t_is_usize(mut self, is: bool) -> Self {
        self.options.size_t_is_usize = is;
        self
    }

    /// Set whether rustfmt should format the generated bindings.
    pub fn rustfmt_bindings(mut self, doit: bool) -> Self {
        self.options.rustfmt_bindings = doit;
        self
    }

    /// Set whether we should record matched items in our regex sets.
    pub fn record_matches(mut self, doit: bool) -> Self {
        self.options.record_matches = doit;
        self
    }

    /// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt
    /// options are used.
    pub fn rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self {
        self = self.rustfmt_bindings(true);
        self.options.rustfmt_configuration_file = path;
        self
    }

    /// Sets an explicit path to rustfmt, to be used when rustfmt is enabled.
    pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
        self.options.rustfmt_path = Some(path.into());
        self
    }

    /// If true, always emit explicit padding fields.
    ///
    /// If a struct needs to be serialized in its native format (padding bytes
    /// and all), for example writing it to a file or sending it on the network,
    /// then this should be enabled, as anything reading the padding bytes of
    /// a struct may lead to Undefined Behavior.
    pub fn explicit_padding(mut self, doit: bool) -> Self {
        self.options.force_explicit_padding = doit;
        self
    }

    /// Generate the Rust bindings using the options built up thus far.
    pub fn generate(mut self) -> Result<Bindings, BindgenError> {
        // Add any extra arguments from the environment to the clang command line.
        if let Some(extra_clang_args) =
            get_target_dependent_env_var("BINDGEN_EXTRA_CLANG_ARGS")
        {
            // Try to parse it with shell quoting. If we fail, make it one single big argument.
            if let Some(strings) = shlex::split(&extra_clang_args) {
                self.options.clang_args.extend(strings);
            } else {
                self.options.clang_args.push(extra_clang_args);
            };
        }

        // Transform input headers to arguments on the clang command line.
        self.options.input_header = self.input_headers.pop();
        self.options.extra_input_headers = self.input_headers;
        self.options.clang_args.extend(
            self.options.extra_input_headers.iter().flat_map(|header| {
                iter::once("-include".into())
                    .chain(iter::once(header.to_string()))
            }),
        );

        self.options.input_unsaved_files.extend(
            self.input_header_contents
                .drain(..)
                .map(|(name, contents)| {
                    clang::UnsavedFile::new(&name, &contents)
                }),
        );

        Bindings::generate(self.options)
    }

    /// Preprocess and dump the input header files to disk.
    ///
    /// This is useful when debugging bindgen, using C-Reduce, or when filing
    /// issues. The resulting file will be named something like `__bindgen.i` or
    /// `__bindgen.ii`
    pub fn dump_preprocessed_input(&self) -> io::Result<()> {
        let clang =
            clang_sys::support::Clang::find(None, &[]).ok_or_else(|| {
                io::Error::new(
                    io::ErrorKind::Other,
                    "Cannot find clang executable",
                )
            })?;

        // The contents of a wrapper file that includes all the input header
        // files.
        let mut wrapper_contents = String::new();

        // Whether we are working with C or C++ inputs.
        let mut is_cpp = args_are_cpp(&self.options.clang_args);

        // For each input header, add `#include "$header"`.
        for header in &self.input_headers {
            is_cpp |= file_is_cpp(header);

            wrapper_contents.push_str("#include \"");
            wrapper_contents.push_str(header);
            wrapper_contents.push_str("\"\n");
        }

        // For each input header content, add a prefix line of `#line 0 "$name"`
        // followed by the contents.
        for &(ref name, ref contents) in &self.input_header_contents {
            is_cpp |= file_is_cpp(name);

            wrapper_contents.push_str("#line 0 \"");
            wrapper_contents.push_str(name);
            wrapper_contents.push_str("\"\n");
            wrapper_contents.push_str(contents);
        }

        let wrapper_path = PathBuf::from(if is_cpp {
            "__bindgen.cpp"
        } else {
            "__bindgen.c"
        });

        {
            let mut wrapper_file = File::create(&wrapper_path)?;
            wrapper_file.write_all(wrapper_contents.as_bytes())?;
        }

        let mut cmd = Command::new(&clang.path);
        cmd.arg("-save-temps")
            .arg("-E")
            .arg("-C")
            .arg("-c")
            .arg(&wrapper_path)
            .stdout(Stdio::piped());

        for a in &self.options.clang_args {
            cmd.arg(a);
        }

        let mut child = cmd.spawn()?;

        let mut preprocessed = child.stdout.take().unwrap();
        let mut file = File::create(if is_cpp {
            "__bindgen.ii"
        } else {
            "__bindgen.i"
        })?;
        io::copy(&mut preprocessed, &mut file)?;

        if child.wait()?.success() {
            Ok(())
        } else {
            Err(io::Error::new(
                io::ErrorKind::Other,
                "clang exited with non-zero status",
            ))
        }
    }

    /// Don't derive `PartialEq` for a given type. Regular
    /// expressions are supported.
    pub fn no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.no_partialeq_types.insert(arg.into());
        self
    }

    /// Don't derive `Copy` for a given type. Regular
    /// expressions are supported.
    pub fn no_copy<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.no_copy_types.insert(arg.into());
        self
    }

    /// Don't derive `Debug` for a given type. Regular
    /// expressions are supported.
    pub fn no_debug<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.no_debug_types.insert(arg.into());
        self
    }

    /// Don't derive/impl `Default` for a given type. Regular
    /// expressions are supported.
    pub fn no_default<T: Into<String>>(mut self, arg: T) -> Self {
        self.options.no_default_types.insert(arg.into());
        self
    }

    /// Don't derive `Hash` for a given type. Regular
    /// expressions are supported.
    pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.no_hash_types.insert(arg.into());
        self
    }

    /// Add `#[must_use]` for the given type. Regular
    /// expressions are supported.
    pub fn must_use_type<T: Into<String>>(mut self, arg: T) -> Builder {
        self.options.must_use_types.insert(arg.into());
        self
    }

    /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut)
    pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
        self.options.array_pointers_in_arguments = doit;
        self
    }

    /// Set the wasm import module name
    pub fn wasm_import_module_name<T: Into<String>>(
        mut self,
        import_name: T,
    ) -> Self {
        self.options.wasm_import_module_name = Some(import_name.into());
        self
    }

    /// Specify the dynamic library name if we are generating bindings for a shared library.
    pub fn dynamic_library_name<T: Into<String>>(
        mut self,
        dynamic_library_name: T,
    ) -> Self {
        self.options.dynamic_library_name = Some(dynamic_library_name.into());
        self
    }

    /// Require successful linkage for all routines in a shared library.
    /// This allows us to optimize function calls by being able to safely assume function pointers
    /// are valid.
    pub fn dynamic_link_require_all(mut self, req: bool) -> Self {
        self.options.dynamic_link_require_all = req;
        self
    }

    /// Generate bindings as `pub` only if the bound item is publically accessible by C++.
    pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self {
        self.options.respect_cxx_access_specs = doit;
        self
    }

    /// Always translate enum integer types to native Rust integer types.
    ///
    /// This will result in enums having types such as `u32` and `i16` instead
    /// of `c_uint` and `c_short`. Types for Rustified enums are always
    /// translated.
    pub fn translate_enum_integer_types(mut self, doit: bool) -> Self {
        self.options.translate_enum_integer_types = doit;
        self
    }

    /// Generate types with C style naming.
    ///
    /// This will add prefixes to the generated type names. For example instead of a struct `A` we
    /// will generate struct `struct_A`. Currently applies to structs, unions, and enums.
    pub fn c_naming(mut self, doit: bool) -> Self {
        self.options.c_naming = doit;
        self
    }
}

/// Configuration options for generated bindings.
#[derive(Debug)]
struct BindgenOptions {
    /// The set of types that have been blocklisted and should not appear
    /// anywhere in the generated code.
    blocklisted_types: RegexSet,

    /// The set of functions that have been blocklisted and should not appear
    /// in the generated code.
    blocklisted_functions: RegexSet,

    /// The set of items, regardless of item-type, that have been
    /// blocklisted and should not appear in the generated code.
    blocklisted_items: RegexSet,

    /// The set of files whose contents should be blocklisted and should not
    /// appear in the generated code.
    blocklisted_files: RegexSet,

    /// The set of types that should be treated as opaque structures in the
    /// generated code.
    opaque_types: RegexSet,

    /// The explicit rustfmt path.
    rustfmt_path: Option<PathBuf>,

    /// The path to which we should write a Makefile-syntax depfile (if any).
    depfile: Option<deps::DepfileSpec>,

    /// The set of types that we should have bindings for in the generated
    /// code.
    ///
    /// This includes all types transitively reachable from any type in this
    /// set. One might think of allowlisted types/vars/functions as GC roots,
    /// and the generated Rust code as including everything that gets marked.
    allowlisted_types: RegexSet,

    /// Allowlisted functions. See docs for `allowlisted_types` for more.
    allowlisted_functions: RegexSet,

    /// Allowlisted variables. See docs for `allowlisted_types` for more.
    allowlisted_vars: RegexSet,

    /// The default style of code to generate for enums
    default_enum_style: codegen::EnumVariation,

    /// The enum patterns to mark an enum as a bitfield
    /// (newtype with bitwise operations).
    bitfield_enums: RegexSet,

    /// The enum patterns to mark an enum as a newtype.
    newtype_enums: RegexSet,

    /// The enum patterns to mark an enum as a Rust enum.
    rustified_enums: RegexSet,

    /// The enum patterns to mark an enum as a non-exhaustive Rust enum.
    rustified_non_exhaustive_enums: RegexSet,

    /// The enum patterns to mark an enum as a module of constants.
    constified_enum_modules: RegexSet,

    /// The enum patterns to mark an enum as a set of constants.
    constified_enums: RegexSet,

    /// The default type for C macro constants.
    default_macro_constant_type: codegen::MacroTypeVariation,

    /// The default style of code to generate for typedefs.
    default_alias_style: codegen::AliasVariation,

    /// Typedef patterns that will use regular type aliasing.
    type_alias: RegexSet,

    /// Typedef patterns that will be aliased by creating a new struct.
    new_type_alias: RegexSet,

    /// Typedef patterns that will be wrapped in a new struct and have
    /// Deref and Deref to their aliased type.
    new_type_alias_deref: RegexSet,

    /// Whether we should generate builtins or not.
    builtins: bool,

    /// True if we should dump the Clang AST for debugging purposes.
    emit_ast: bool,

    /// True if we should dump our internal IR for debugging purposes.
    emit_ir: bool,

    /// Output graphviz dot file.
    emit_ir_graphviz: Option<String>,

    /// True if we should emulate C++ namespaces with Rust modules in the
    /// generated bindings.
    enable_cxx_namespaces: bool,

    /// True if we should try to find unexposed attributes in functions, in
    /// order to be able to generate #[must_use] attributes in Rust.
    enable_function_attribute_detection: bool,

    /// True if we should avoid mangling names with namespaces.
    disable_name_namespacing: bool,

    /// True if we should avoid generating nested struct names.
    disable_nested_struct_naming: bool,

    /// True if we should avoid embedding version identifiers into source code.
    disable_header_comment: bool,

    /// True if we should generate layout tests for generated structures.
    layout_tests: bool,

    /// True if we should implement the Debug trait for C/C++ structures and types
    /// that do not support automatically deriving Debug.
    impl_debug: bool,

    /// True if we should implement the PartialEq trait for C/C++ structures and types
    /// that do not support automatically deriving PartialEq.
    impl_partialeq: bool,

    /// True if we should derive Copy trait implementations for C/C++ structures
    /// and types.
    derive_copy: bool,

    /// True if we should derive Debug trait implementations for C/C++ structures
    /// and types.
    derive_debug: bool,

    /// True if we should derive Default trait implementations for C/C++ structures
    /// and types.
    derive_default: bool,

    /// True if we should derive Hash trait implementations for C/C++ structures
    /// and types.
    derive_hash: bool,

    /// True if we should derive PartialOrd trait implementations for C/C++ structures
    /// and types.
    derive_partialord: bool,

    /// True if we should derive Ord trait implementations for C/C++ structures
    /// and types.
    derive_ord: bool,

    /// True if we should derive PartialEq trait implementations for C/C++ structures
    /// and types.
    derive_partialeq: bool,

    /// True if we should derive Eq trait implementations for C/C++ structures
    /// and types.
    derive_eq: bool,

    /// True if we should avoid using libstd to use libcore instead.
    use_core: bool,

    /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
    ctypes_prefix: Option<String>,

    /// The prefix for the anon fields.
    anon_fields_prefix: String,

    /// Whether to time the bindgen phases.
    time_phases: bool,

    /// Whether we should convert float types to f32/f64 types.
    convert_floats: bool,

    /// The set of raw lines to prepend to the top-level module of generated
    /// Rust code.
    raw_lines: Vec<String>,

    /// The set of raw lines to prepend to each of the modules.
    ///
    /// This only makes sense if the `enable_cxx_namespaces` option is set.
    module_lines: HashMap<String, Vec<String>>,

    /// The set of arguments to pass straight through to Clang.
    clang_args: Vec<String>,

    /// The input header file.
    input_header: Option<String>,

    /// Any additional input header files.
    extra_input_headers: Vec<String>,

    /// Unsaved files for input.
    input_unsaved_files: Vec<clang::UnsavedFile>,

    /// A user-provided visitor to allow customizing different kinds of
    /// situations.
    parse_callbacks: Option<Box<dyn callbacks::ParseCallbacks>>,

    /// Which kind of items should we generate? By default, we'll generate all
    /// of them.
    codegen_config: CodegenConfig,

    /// Whether to treat inline namespaces conservatively.
    ///
    /// See the builder method description for more details.
    conservative_inline_namespaces: bool,

    /// Whether to keep documentation comments in the generated output. See the
    /// documentation for more details. Defaults to true.
    generate_comments: bool,

    /// Whether to generate inline functions. Defaults to false.
    generate_inline_functions: bool,

    /// Whether to allowlist types recursively. Defaults to true.
    allowlist_recursively: bool,

    /// Instead of emitting 'use objc;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate objc;'
    objc_extern_crate: bool,

    /// Instead of emitting 'use block;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate block;'
    generate_block: bool,

    /// Instead of emitting 'use block;' to files generated from objective c files,
    /// generate '#[macro_use] extern crate block;'
    block_extern_crate: bool,

    /// Whether to use the clang-provided name mangling. This is true and
    /// probably needed for C++ features.
    ///
    /// However, some old libclang versions seem to return incorrect results in
    /// some cases for non-mangled functions, see [1], so we allow disabling it.
    ///
    /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
    enable_mangling: bool,

    /// Whether to detect include paths using clang_sys.
    detect_include_paths: bool,

    /// Whether to try to fit macro constants into types smaller than u32/i32
    fit_macro_constants: bool,

    /// Whether to prepend the enum name to constant or newtype variants.
    prepend_enum_name: bool,

    /// Version of the Rust compiler to target
    rust_target: RustTarget,

    /// Features to enable, derived from `rust_target`
    rust_features: RustFeatures,

    /// Whether we should record which items in the regex sets ever matched.
    ///
    /// This may be a bit slower, but will enable reporting of unused allowlist
    /// items via the `error!` log.
    record_matches: bool,

    /// Whether `size_t` should be translated to `usize` automatically.
    size_t_is_usize: bool,

    /// Whether rustfmt should format the generated bindings.
    rustfmt_bindings: bool,

    /// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
    /// options are used.
    rustfmt_configuration_file: Option<PathBuf>,

    /// The set of types that we should not derive `PartialEq` for.
    no_partialeq_types: RegexSet,

    /// The set of types that we should not derive `Copy` for.
    no_copy_types: RegexSet,

    /// The set of types that we should not derive `Debug` for.
    no_debug_types: RegexSet,

    /// The set of types that we should not derive/impl `Default` for.
    no_default_types: RegexSet,

    /// The set of types that we should not derive `Hash` for.
    no_hash_types: RegexSet,

    /// The set of types that we should be annotated with `#[must_use]`.
    must_use_types: RegexSet,

    /// Decide if C arrays should be regular pointers in rust or array pointers
    array_pointers_in_arguments: bool,

    /// Wasm import module name.
    wasm_import_module_name: Option<String>,

    /// The name of the dynamic library (if we are generating bindings for a shared library). If
    /// this is None, no dynamic bindings are created.
    dynamic_library_name: Option<String>,

    /// Require successful linkage for all routines in a shared library.
    /// This allows us to optimize function calls by being able to safely assume function pointers
    /// are valid. No effect if `dynamic_library_name` is None.
    dynamic_link_require_all: bool,

    /// Only make generated bindings `pub` if the items would be publically accessible
    /// by C++.
    respect_cxx_access_specs: bool,

    /// Always translate enum integer types to native Rust integer types.
    translate_enum_integer_types: bool,

    /// Generate types with C style naming.
    c_naming: bool,

    /// Always output explicit padding fields
    force_explicit_padding: bool,
}

/// TODO(emilio): This is sort of a lie (see the error message that results from
/// removing this), but since we don't share references across panic boundaries
/// it's ok.
impl ::std::panic::UnwindSafe for BindgenOptions {}

impl BindgenOptions {
    fn build(&mut self) {
        let mut regex_sets = [
            &mut self.allowlisted_vars,
            &mut self.allowlisted_types,
            &mut self.allowlisted_functions,
            &mut self.blocklisted_types,
            &mut self.blocklisted_functions,
            &mut self.blocklisted_items,
            &mut self.blocklisted_files,
            &mut self.opaque_types,
            &mut self.bitfield_enums,
            &mut self.constified_enums,
            &mut self.constified_enum_modules,
            &mut self.newtype_enums,
            &mut self.rustified_enums,
            &mut self.rustified_non_exhaustive_enums,
            &mut self.type_alias,
            &mut self.new_type_alias,
            &mut self.new_type_alias_deref,
            &mut self.no_partialeq_types,
            &mut self.no_copy_types,
            &mut self.no_debug_types,
            &mut self.no_default_types,
            &mut self.no_hash_types,
            &mut self.must_use_types,
        ];
        let record_matches = self.record_matches;
        for regex_set in &mut regex_sets {
            regex_set.build(record_matches);
        }
    }

    /// Update rust target version
    pub fn set_rust_target(&mut self, rust_target: RustTarget) {
        self.rust_target = rust_target;

        // Keep rust_features synced with rust_target
        self.rust_features = rust_target.into();
    }

    /// Get features supported by target Rust version
    pub fn rust_features(&self) -> RustFeatures {
        self.rust_features
    }
}

impl Default for BindgenOptions {
    fn default() -> BindgenOptions {
        let rust_target = RustTarget::default();

        BindgenOptions {
            rust_target,
            rust_features: rust_target.into(),
            blocklisted_types: Default::default(),
            blocklisted_functions: Default::default(),
            blocklisted_items: Default::default(),
            blocklisted_files: Default::default(),
            opaque_types: Default::default(),
            rustfmt_path: Default::default(),
            depfile: Default::default(),
            allowlisted_types: Default::default(),
            allowlisted_functions: Default::default(),
            allowlisted_vars: Default::default(),
            default_enum_style: Default::default(),
            bitfield_enums: Default::default(),
            newtype_enums: Default::default(),
            rustified_enums: Default::default(),
            rustified_non_exhaustive_enums: Default::default(),
            constified_enums: Default::default(),
            constified_enum_modules: Default::default(),
            default_macro_constant_type: Default::default(),
            default_alias_style: Default::default(),
            type_alias: Default::default(),
            new_type_alias: Default::default(),
            new_type_alias_deref: Default::default(),
            builtins: false,
            emit_ast: false,
            emit_ir: false,
            emit_ir_graphviz: None,
            layout_tests: true,
            impl_debug: false,
            impl_partialeq: false,
            derive_copy: true,
            derive_debug: true,
            derive_default: false,
            derive_hash: false,
            derive_partialord: false,
            derive_ord: false,
            derive_partialeq: false,
            derive_eq: false,
            enable_cxx_namespaces: false,
            enable_function_attribute_detection: false,
            disable_name_namespacing: false,
            disable_nested_struct_naming: false,
            disable_header_comment: false,
            use_core: false,
            ctypes_prefix: None,
            anon_fields_prefix: DEFAULT_ANON_FIELDS_PREFIX.into(),
            convert_floats: true,
            raw_lines: vec![],
            module_lines: HashMap::default(),
            clang_args: vec![],
            input_header: None,
            extra_input_headers: vec![],
            input_unsaved_files: vec![],
            parse_callbacks: None,
            codegen_config: CodegenConfig::all(),
            conservative_inline_namespaces: false,
            generate_comments: true,
            generate_inline_functions: false,
            allowlist_recursively: true,
            generate_block: false,
            objc_extern_crate: false,
            block_extern_crate: false,
            enable_mangling: true,
            detect_include_paths: true,
            fit_macro_constants: false,
            prepend_enum_name: true,
            time_phases: false,
            record_matches: true,
            rustfmt_bindings: true,
            size_t_is_usize: false,
            rustfmt_configuration_file: None,
            no_partialeq_types: Default::default(),
            no_copy_types: Default::default(),
            no_debug_types: Default::default(),
            no_default_types: Default::default(),
            no_hash_types: Default::default(),
            must_use_types: Default::default(),
            array_pointers_in_arguments: false,
            wasm_import_module_name: None,
            dynamic_library_name: None,
            dynamic_link_require_all: false,
            respect_cxx_access_specs: false,
            translate_enum_integer_types: false,
            c_naming: false,
            force_explicit_padding: false,
        }
    }
}

#[cfg(feature = "runtime")]
fn ensure_libclang_is_loaded() {
    if clang_sys::is_loaded() {
        return;
    }

    // XXX (issue #350): Ensure that our dynamically loaded `libclang`
    // doesn't get dropped prematurely, nor is loaded multiple times
    // across different threads.

    lazy_static! {
        static ref LIBCLANG: std::sync::Arc<clang_sys::SharedLibrary> = {
            clang_sys::load().expect("Unable to find libclang");
            clang_sys::get_library().expect(
                "We just loaded libclang and it had better still be \
                 here!",
            )
        };
    }

    clang_sys::set_library(Some(LIBCLANG.clone()));
}

#[cfg(not(feature = "runtime"))]
fn ensure_libclang_is_loaded() {}

/// Error type for rust-bindgen.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum BindgenError {
    /// The header was a folder.
    FolderAsHeader(String),
    /// Permissions to read the header is insufficient.
    InsufficientPermissions(String),
    /// The header does not exist.
    NotExist(String),
    /// Clang diagnosed an error.
    ClangDiagnostic(String),
}

impl std::fmt::Display for BindgenError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            BindgenError::FolderAsHeader(h) => write!(f, "'{}' is a folder", h),
            BindgenError::InsufficientPermissions(h) => {
                write!(f, "insufficient permissions to read '{}'", h)
            }
            BindgenError::NotExist(h) => {
                write!(f, "header '{}' does not exist.", h)
            }
            BindgenError::ClangDiagnostic(message) => {
                write!(f, "clang diagnosed error: {}", message)
            }
        }
    }
}

impl std::error::Error for BindgenError {}

/// Generated Rust bindings.
#[derive(Debug)]
pub struct Bindings {
    options: BindgenOptions,
    module: proc_macro2::TokenStream,
}

pub(crate) const HOST_TARGET: &str =
    include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));

// Some architecture triplets are different between rust and libclang, see #1211
// and duplicates.
fn rust_to_clang_target(rust_target: &str) -> String {
    if rust_target.starts_with("aarch64-apple-") {
        let mut clang_target = "arm64-apple-".to_owned();
        clang_target
            .push_str(rust_target.strip_prefix("aarch64-apple-").unwrap());
        return clang_target;
    } else if rust_target.starts_with("riscv64gc-") {
        let mut clang_target = "riscv64-".to_owned();
        clang_target.push_str(rust_target.strip_prefix("riscv64gc-").unwrap());
        return clang_target;
    }
    rust_target.to_owned()
}

/// Returns the effective target, and whether it was explicitly specified on the
/// clang flags.
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
    let mut args = clang_args.iter();
    while let Some(opt) = args.next() {
        if opt.starts_with("--target=") {
            let mut split = opt.split('=');
            split.next();
            return (split.next().unwrap().to_owned(), true);
        }

        if opt == "-target" {
            if let Some(target) = args.next() {
                return (target.clone(), true);
            }
        }
    }

    // If we're running from a build script, try to find the cargo target.
    if let Ok(t) = env::var("TARGET") {
        return (rust_to_clang_target(&t), false);
    }

    (rust_to_clang_target(HOST_TARGET), false)
}

impl Bindings {
    /// Generate bindings for the given options.
    pub(crate) fn generate(
        mut options: BindgenOptions,
    ) -> Result<Bindings, BindgenError> {
        ensure_libclang_is_loaded();

        #[cfg(feature = "runtime")]
        debug!(
            "Generating bindings, libclang at {}",
            clang_sys::get_library().unwrap().path().display()
        );
        #[cfg(not(feature = "runtime"))]
        debug!("Generating bindings, libclang linked");

        options.build();

        let (effective_target, explicit_target) =
            find_effective_target(&options.clang_args);

        let is_host_build =
            rust_to_clang_target(HOST_TARGET) == effective_target;

        // NOTE: The is_host_build check wouldn't be sound normally in some
        // cases if we were to call a binary (if you have a 32-bit clang and are
        // building on a 64-bit system for example).  But since we rely on
        // opening libclang.so, it has to be the same architecture and thus the
        // check is fine.
        if !explicit_target && !is_host_build {
            options
                .clang_args
                .insert(0, format!("--target={}", effective_target));
        };

        fn detect_include_paths(options: &mut BindgenOptions) {
            if !options.detect_include_paths {
                return;
            }

            // Filter out include paths and similar stuff, so we don't incorrectly
            // promote them to `-isystem`.
            let clang_args_for_clang_sys = {
                let mut last_was_include_prefix = false;
                options
                    .clang_args
                    .iter()
                    .filter(|arg| {
                        if last_was_include_prefix {
                            last_was_include_prefix = false;
                            return false;
                        }

                        let arg = &**arg;

                        // https://clang.llvm.org/docs/ClangCommandLineReference.html
                        // -isystem and -isystem-after are harmless.
                        if arg == "-I" || arg == "--include-directory" {
                            last_was_include_prefix = true;
                            return false;
                        }

                        if arg.starts_with("-I") ||
                            arg.starts_with("--include-directory=")
                        {
                            return false;
                        }

                        true
                    })
                    .cloned()
                    .collect::<Vec<_>>()
            };

            debug!(
                "Trying to find clang with flags: {:?}",
                clang_args_for_clang_sys
            );

            let clang = match clang_sys::support::Clang::find(
                None,
                &clang_args_for_clang_sys,
            ) {
                None => return,
                Some(clang) => clang,
            };

            debug!("Found clang: {:?}", clang);

            // Whether we are working with C or C++ inputs.
            let is_cpp = args_are_cpp(&options.clang_args) ||
                options.input_header.as_deref().map_or(false, file_is_cpp);

            let search_paths = if is_cpp {
                clang.cpp_search_paths
            } else {
                clang.c_search_paths
            };

            if let Some(search_paths) = search_paths {
                for path in search_paths.into_iter() {
                    if let Ok(path) = path.into_os_string().into_string() {
                        options.clang_args.push("-isystem".to_owned());
                        options.clang_args.push(path);
                    }
                }
            }
        }

        detect_include_paths(&mut options);

        #[cfg(unix)]
        fn can_read(perms: &std::fs::Permissions) -> bool {
            use std::os::unix::fs::PermissionsExt;
            perms.mode() & 0o444 > 0
        }

        #[cfg(not(unix))]
        fn can_read(_: &std::fs::Permissions) -> bool {
            true
        }

        if let Some(h) = options.input_header.as_ref() {
            if let Ok(md) = std::fs::metadata(h) {
                if md.is_dir() {
                    return Err(BindgenError::FolderAsHeader(h.into()));
                }
                if !can_read(&md.permissions()) {
                    return Err(BindgenError::InsufficientPermissions(
                        h.into(),
                    ));
                }
                options.clang_args.push(h.clone())
            } else {
                return Err(BindgenError::NotExist(h.into()));
            }
        }

        for (idx, f) in options.input_unsaved_files.iter().enumerate() {
            if idx != 0 || options.input_header.is_some() {
                options.clang_args.push("-include".to_owned());
            }
            options.clang_args.push(f.name.to_str().unwrap().to_owned())
        }

        debug!("Fixed-up options: {:?}", options);

        let time_phases = options.time_phases;
        let mut context = BindgenContext::new(options);

        if is_host_build {
            debug_assert_eq!(
                context.target_pointer_size(),
                std::mem::size_of::<*mut ()>(),
                "{:?} {:?}",
                effective_target,
                HOST_TARGET
            );
        }

        {
            let _t = time::Timer::new("parse").with_output(time_phases);
            parse(&mut context)?;
        }

        let (items, options) = codegen::codegen(context);

        Ok(Bindings {
            options,
            module: quote! {
                #( #items )*
            },
        })
    }

    /// Write these bindings as source text to a file.
    pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
        let file = OpenOptions::new()
            .write(true)
            .truncate(true)
            .create(true)
            .open(path.as_ref())?;
        self.write(Box::new(file))?;
        Ok(())
    }

    /// Write these bindings as source text to the given `Write`able.
    pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
        if !self.options.disable_header_comment {
            let version = option_env!("CARGO_PKG_VERSION");
            let header = format!(
                "/* automatically generated by rust-bindgen {} */\n\n",
                version.unwrap_or("(unknown version)")
            );
            writer.write_all(header.as_bytes())?;
        }

        for line in self.options.raw_lines.iter() {
            writer.write_all(line.as_bytes())?;
            writer.write_all("\n".as_bytes())?;
        }

        if !self.options.raw_lines.is_empty() {
            writer.write_all("\n".as_bytes())?;
        }

        let bindings = self.module.to_string();

        match self.rustfmt_generated_string(&bindings) {
            Ok(rustfmt_bindings) => {
                writer.write_all(rustfmt_bindings.as_bytes())?;
            }
            Err(err) => {
                eprintln!(
                    "Failed to run rustfmt: {} (non-fatal, continuing)",
                    err
                );
                writer.write_all(bindings.as_bytes())?;
            }
        }
        Ok(())
    }

    /// Gets the rustfmt path to rustfmt the generated bindings.
    fn rustfmt_path(&self) -> io::Result<Cow<PathBuf>> {
        debug_assert!(self.options.rustfmt_bindings);
        if let Some(ref p) = self.options.rustfmt_path {
            return Ok(Cow::Borrowed(p));
        }
        if let Ok(rustfmt) = env::var("RUSTFMT") {
            return Ok(Cow::Owned(rustfmt.into()));
        }
        #[cfg(feature = "which-rustfmt")]
        match which::which("rustfmt") {
            Ok(p) => Ok(Cow::Owned(p)),
            Err(e) => {
                Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
            }
        }
        #[cfg(not(feature = "which-rustfmt"))]
        // No rustfmt binary was specified, so assume that the binary is called
        // "rustfmt" and that it is in the user's PATH.
        Ok(Cow::Owned("rustfmt".into()))
    }

    /// Checks if rustfmt_bindings is set and runs rustfmt on the string
    fn rustfmt_generated_string<'a>(
        &self,
        source: &'a str,
    ) -> io::Result<Cow<'a, str>> {
        let _t = time::Timer::new("rustfmt_generated_string")
            .with_output(self.options.time_phases);

        if !self.options.rustfmt_bindings {
            return Ok(Cow::Borrowed(source));
        }

        let rustfmt = self.rustfmt_path()?;
        let mut cmd = Command::new(&*rustfmt);

        cmd.stdin(Stdio::piped()).stdout(Stdio::piped());

        if let Some(path) = self
            .options
            .rustfmt_configuration_file
            .as_ref()
            .and_then(|f| f.to_str())
        {
            cmd.args(&["--config-path", path]);
        }

        let mut child = cmd.spawn()?;
        let mut child_stdin = child.stdin.take().unwrap();
        let mut child_stdout = child.stdout.take().unwrap();

        let source = source.to_owned();

        // Write to stdin in a new thread, so that we can read from stdout on this
        // thread. This keeps the child from blocking on writing to its stdout which
        // might block us from writing to its stdin.
        let stdin_handle = ::std::thread::spawn(move || {
            let _ = child_stdin.write_all(source.as_bytes());
            source
        });

        let mut output = vec![];
        io::copy(&mut child_stdout, &mut output)?;

        let status = child.wait()?;
        let source = stdin_handle.join().expect(
            "The thread writing to rustfmt's stdin doesn't do \
             anything that could panic",
        );

        match String::from_utf8(output) {
            Ok(bindings) => match status.code() {
                Some(0) => Ok(Cow::Owned(bindings)),
                Some(2) => Err(io::Error::new(
                    io::ErrorKind::Other,
                    "Rustfmt parsing errors.".to_string(),
                )),
                Some(3) => {
                    warn!("Rustfmt could not format some lines.");
                    Ok(Cow::Owned(bindings))
                }
                _ => Err(io::Error::new(
                    io::ErrorKind::Other,
                    "Internal rustfmt error".to_string(),
                )),
            },
            _ => Ok(Cow::Owned(source)),
        }
    }
}

impl std::fmt::Display for Bindings {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut bytes = vec![];
        self.write(Box::new(&mut bytes) as Box<dyn Write>)
            .expect("writing to a vec cannot fail");
        f.write_str(
            std::str::from_utf8(&bytes)
                .expect("we should only write bindings that are valid utf-8"),
        )
    }
}

/// Determines whether the given cursor is in any of the files matched by the
/// options.
fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
    ctx.options().builtins || !cursor.is_builtin()
}

/// Parse one `Item` from the Clang cursor.
fn parse_one(
    ctx: &mut BindgenContext,
    cursor: clang::Cursor,
    parent: Option<ItemId>,
) -> clang_sys::CXChildVisitResult {
    if !filter_builtins(ctx, &cursor) {
        return CXChildVisit_Continue;
    }

    use clang_sys::CXChildVisit_Continue;
    match Item::parse(cursor, parent, ctx) {
        Ok(..) => {}
        Err(ParseError::Continue) => {}
        Err(ParseError::Recurse) => {
            cursor.visit(|child| parse_one(ctx, child, parent));
        }
    }
    CXChildVisit_Continue
}

/// Parse the Clang AST into our `Item` internal representation.
fn parse(context: &mut BindgenContext) -> Result<(), BindgenError> {
    use clang_sys::*;

    let mut error = None;
    for d in context.translation_unit().diags().iter() {
        let msg = d.format();
        let is_err = d.severity() >= CXDiagnostic_Error;
        if is_err {
            let error = error.get_or_insert_with(String::new);
            error.push_str(&msg);
            error.push('\n');
        } else {
            eprintln!("clang diag: {}", msg);
        }
    }

    if let Some(message) = error {
        return Err(BindgenError::ClangDiagnostic(message));
    }

    let cursor = context.translation_unit().cursor();

    if context.options().emit_ast {
        fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
            if !cur.is_builtin() {
                clang::ast_dump(cur, 0)
            } else {
                CXChildVisit_Continue
            }
        }
        cursor.visit(|cur| dump_if_not_builtin(&cur));
    }

    let root = context.root_module();
    context.with_module(root, |context| {
        cursor.visit(|cursor| parse_one(context, cursor, None))
    });

    assert!(
        context.current_module() == context.root_module(),
        "How did this happen?"
    );
    Ok(())
}

/// Extracted Clang version data
#[derive(Debug)]
pub struct ClangVersion {
    /// Major and minor semver, if parsing was successful
    pub parsed: Option<(u32, u32)>,
    /// full version string
    pub full: String,
}

/// Get the major and the minor semver numbers of Clang's version
pub fn clang_version() -> ClangVersion {
    ensure_libclang_is_loaded();

    //Debian clang version 11.0.1-2
    let raw_v: String = clang::extract_clang_version();
    let split_v: Option<Vec<&str>> = raw_v
        .split_whitespace()
        .find(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
        .map(|v| v.split('.').collect());
    if let Some(v) = split_v {
        if v.len() >= 2 {
            let maybe_major = v[0].parse::<u32>();
            let maybe_minor = v[1].parse::<u32>();
            if let (Ok(major), Ok(minor)) = (maybe_major, maybe_minor) {
                return ClangVersion {
                    parsed: Some((major, minor)),
                    full: raw_v.clone(),
                };
            }
        }
    };
    ClangVersion {
        parsed: None,
        full: raw_v.clone(),
    }
}

/// Looks for the env var `var_${TARGET}`, and falls back to just `var` when it is not found.
fn get_target_dependent_env_var(var: &str) -> Option<String> {
    if let Ok(target) = env::var("TARGET") {
        if let Ok(v) = env::var(&format!("{}_{}", var, target)) {
            return Some(v);
        }
        if let Ok(v) =
            env::var(&format!("{}_{}", var, target.replace("-", "_")))
        {
            return Some(v);
        }
    }
    env::var(var).ok()
}

/// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
/// line
///
/// When running inside a `build.rs` script, this can be used to make cargo invalidate the
/// generated bindings whenever any of the files included from the header change:
/// ```
/// use bindgen::builder;
/// let bindings = builder()
///     .header("path/to/input/header")
///     .parse_callbacks(Box::new(bindgen::CargoCallbacks))
///     .generate();
/// ```
#[derive(Debug)]
pub struct CargoCallbacks;

impl callbacks::ParseCallbacks for CargoCallbacks {
    fn include_file(&self, filename: &str) {
        println!("cargo:rerun-if-changed={}", filename);
    }
}

/// Test command_line_flag function.
#[test]
fn commandline_flag_unit_test_function() {
    //Test 1
    let bindings = crate::builder();
    let command_line_flags = bindings.command_line_flags();

    let test_cases = vec![
        "--rust-target",
        "--no-derive-default",
        "--generate",
        "functions,types,vars,methods,constructors,destructors",
    ]
    .iter()
    .map(|&x| x.into())
    .collect::<Vec<String>>();

    assert!(test_cases.iter().all(|x| command_line_flags.contains(x)));

    //Test 2
    let bindings = crate::builder()
        .header("input_header")
        .allowlist_type("Distinct_Type")
        .allowlist_function("safe_function");

    let command_line_flags = bindings.command_line_flags();
    let test_cases = vec![
        "--rust-target",
        "input_header",
        "--no-derive-default",
        "--generate",
        "functions,types,vars,methods,constructors,destructors",
        "--allowlist-type",
        "Distinct_Type",
        "--allowlist-function",
        "safe_function",
    ]
    .iter()
    .map(|&x| x.into())
    .collect::<Vec<String>>();
    println!("{:?}", command_line_flags);

    assert!(test_cases.iter().all(|x| command_line_flags.contains(x)));
}

#[test]
fn test_rust_to_clang_target() {
    assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios");
}

#[test]
fn test_rust_to_clang_target_riscv() {
    assert_eq!(
        rust_to_clang_target("riscv64gc-unknown-linux-gnu"),
        "riscv64-unknown-linux-gnu"
    )
}
