• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Generate Rust bindings for C and C++ libraries.
2 //!
3 //! Provide a C/C++ header file, receive Rust FFI code to call into C/C++
4 //! functions and use types defined in the header.
5 //!
6 //! See the [`Builder`](./struct.Builder.html) struct for usage.
7 //!
8 //! See the [Users Guide](https://rust-lang.github.io/rust-bindgen/) for
9 //! additional documentation.
10 #![deny(missing_docs)]
11 #![deny(unused_extern_crates)]
12 // To avoid rather annoying warnings when matching with CXCursor_xxx as a
13 // constant.
14 #![allow(non_upper_case_globals)]
15 // `quote!` nests quite deeply.
16 #![recursion_limit = "128"]
17 
18 #[macro_use]
19 extern crate bitflags;
20 #[macro_use]
21 extern crate lazy_static;
22 #[macro_use]
23 extern crate quote;
24 
25 #[cfg(feature = "logging")]
26 #[macro_use]
27 extern crate log;
28 
29 #[cfg(not(feature = "logging"))]
30 #[macro_use]
31 mod log_stubs;
32 
33 #[macro_use]
34 mod extra_assertions;
35 
36 // A macro to declare an internal module for which we *must* provide
37 // documentation for. If we are building with the "testing_only_docs" feature,
38 // then the module is declared public, and our `#![deny(missing_docs)]` pragma
39 // applies to it. This feature is used in CI, so we won't let anything slip by
40 // undocumented. Normal builds, however, will leave the module private, so that
41 // we don't expose internals to library consumers.
42 macro_rules! doc_mod {
43     ($m:ident, $doc_mod_name:ident) => {
44         #[cfg(feature = "testing_only_docs")]
45         pub mod $doc_mod_name {
46             //! Autogenerated documentation module.
47             pub use super::$m::*;
48         }
49     };
50 }
51 
52 mod clang;
53 mod codegen;
54 mod features;
55 mod ir;
56 mod parse;
57 mod regex_set;
58 mod time;
59 
60 pub mod callbacks;
61 
62 doc_mod!(clang, clang_docs);
63 doc_mod!(features, features_docs);
64 doc_mod!(ir, ir_docs);
65 doc_mod!(parse, parse_docs);
66 doc_mod!(regex_set, regex_set_docs);
67 
68 pub use crate::codegen::{AliasVariation, EnumVariation, MacroTypeVariation};
69 use crate::features::RustFeatures;
70 pub use crate::features::{
71     RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS,
72 };
73 use crate::ir::context::{BindgenContext, ItemId};
74 use crate::ir::item::Item;
75 use crate::parse::{ClangItemParser, ParseError};
76 use crate::regex_set::RegexSet;
77 
78 use std::borrow::Cow;
79 use std::fs::{File, OpenOptions};
80 use std::io::{self, Write};
81 use std::path::{Path, PathBuf};
82 use std::process::{Command, Stdio};
83 use std::{env, iter};
84 
85 // Some convenient typedefs for a fast hash map and hash set.
86 type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;
87 type HashSet<K> = ::rustc_hash::FxHashSet<K>;
88 pub(crate) use std::collections::hash_map::Entry;
89 
90 /// Default prefix for the anon fields.
91 pub const DEFAULT_ANON_FIELDS_PREFIX: &'static str = "__bindgen_anon_";
92 
file_is_cpp(name_file: &str) -> bool93 fn file_is_cpp(name_file: &str) -> bool {
94     name_file.ends_with(".hpp") ||
95         name_file.ends_with(".hxx") ||
96         name_file.ends_with(".hh") ||
97         name_file.ends_with(".h++")
98 }
99 
args_are_cpp(clang_args: &[String]) -> bool100 fn args_are_cpp(clang_args: &[String]) -> bool {
101     for w in clang_args.windows(2) {
102         if w[0] == "-xc++" || w[1] == "-xc++" {
103             return true;
104         }
105         if w[0] == "-x" && w[1] == "c++" {
106             return true;
107         }
108         if w[0] == "-include" && file_is_cpp(&w[1]) {
109             return true;
110         }
111     }
112     false
113 }
114 
115 bitflags! {
116     /// A type used to indicate which kind of items we have to generate.
117     pub struct CodegenConfig: u32 {
118         /// Whether to generate functions.
119         const FUNCTIONS = 1 << 0;
120         /// Whether to generate types.
121         const TYPES = 1 << 1;
122         /// Whether to generate constants.
123         const VARS = 1 << 2;
124         /// Whether to generate methods.
125         const METHODS = 1 << 3;
126         /// Whether to generate constructors
127         const CONSTRUCTORS = 1 << 4;
128         /// Whether to generate destructors.
129         const DESTRUCTORS = 1 << 5;
130     }
131 }
132 
133 impl CodegenConfig {
134     /// Returns true if functions should be generated.
functions(self) -> bool135     pub fn functions(self) -> bool {
136         self.contains(CodegenConfig::FUNCTIONS)
137     }
138 
139     /// Returns true if types should be generated.
types(self) -> bool140     pub fn types(self) -> bool {
141         self.contains(CodegenConfig::TYPES)
142     }
143 
144     /// Returns true if constants should be generated.
vars(self) -> bool145     pub fn vars(self) -> bool {
146         self.contains(CodegenConfig::VARS)
147     }
148 
149     /// Returns true if methds should be generated.
methods(self) -> bool150     pub fn methods(self) -> bool {
151         self.contains(CodegenConfig::METHODS)
152     }
153 
154     /// Returns true if constructors should be generated.
constructors(self) -> bool155     pub fn constructors(self) -> bool {
156         self.contains(CodegenConfig::CONSTRUCTORS)
157     }
158 
159     /// Returns true if destructors should be generated.
destructors(self) -> bool160     pub fn destructors(self) -> bool {
161         self.contains(CodegenConfig::DESTRUCTORS)
162     }
163 }
164 
165 impl Default for CodegenConfig {
default() -> Self166     fn default() -> Self {
167         CodegenConfig::all()
168     }
169 }
170 
171 /// Configure and generate Rust bindings for a C/C++ header.
172 ///
173 /// This is the main entry point to the library.
174 ///
175 /// ```ignore
176 /// use bindgen::builder;
177 ///
178 /// // Configure and generate bindings.
179 /// let bindings = builder().header("path/to/input/header")
180 ///     .allowlist_type("SomeCoolClass")
181 ///     .allowlist_function("do_some_cool_thing")
182 ///     .generate()?;
183 ///
184 /// // Write the generated bindings to an output file.
185 /// bindings.write_to_file("path/to/output.rs")?;
186 /// ```
187 ///
188 /// # Enums
189 ///
190 /// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
191 /// the pattern passed to several methods:
192 ///
193 /// 1. [`constified_enum_module()`](#method.constified_enum_module)
194 /// 2. [`bitfield_enum()`](#method.bitfield_enum)
195 /// 3. [`newtype_enum()`](#method.newtype_enum)
196 /// 4. [`rustified_enum()`](#method.rustified_enum)
197 ///
198 /// For each C enum, bindgen tries to match the pattern in the following order:
199 ///
200 /// 1. Constified enum module
201 /// 2. Bitfield enum
202 /// 3. Newtype enum
203 /// 4. Rustified enum
204 ///
205 /// If none of the above patterns match, then bindgen will generate a set of Rust constants.
206 ///
207 /// # Clang arguments
208 ///
209 /// Extra arguments can be passed to with clang:
210 /// 1. [`clang_arg()`](#method.clang_arg): takes a single argument
211 /// 2. [`clang_args()`](#method.clang_args): takes an iterator of arguments
212 /// 3. `BINDGEN_EXTRA_CLANG_ARGS` environment variable: whitespace separate
213 ///    environment variable of arguments
214 ///
215 /// Clang arguments specific to your crate should be added via the
216 /// `clang_arg()`/`clang_args()` methods.
217 ///
218 /// End-users of the crate may need to set the `BINDGEN_EXTRA_CLANG_ARGS` environment variable to
219 /// add additional arguments. For example, to build against a different sysroot a user could set
220 /// `BINDGEN_EXTRA_CLANG_ARGS` to `--sysroot=/path/to/sysroot`.
221 #[derive(Debug, Default)]
222 pub struct Builder {
223     options: BindgenOptions,
224     input_headers: Vec<String>,
225     // Tuples of unsaved file contents of the form (name, contents).
226     input_header_contents: Vec<(String, String)>,
227 }
228 
229 /// Construct a new [`Builder`](./struct.Builder.html).
builder() -> Builder230 pub fn builder() -> Builder {
231     Default::default()
232 }
233 
234 impl Builder {
235     /// Generates the command line flags use for creating `Builder`.
command_line_flags(&self) -> Vec<String>236     pub fn command_line_flags(&self) -> Vec<String> {
237         let mut output_vector: Vec<String> = Vec::new();
238 
239         if let Some(header) = self.input_headers.last().cloned() {
240             // Positional argument 'header'
241             output_vector.push(header);
242         }
243 
244         output_vector.push("--rust-target".into());
245         output_vector.push(self.options.rust_target.into());
246 
247         // FIXME(emilio): This is a bit hacky, maybe we should stop re-using the
248         // RustFeatures to store the "disable_untagged_union" call, and make it
249         // a different flag that we check elsewhere / in generate().
250         if !self.options.rust_features.untagged_union &&
251             RustFeatures::from(self.options.rust_target).untagged_union
252         {
253             output_vector.push("--disable-untagged-union".into());
254         }
255 
256         if self.options.default_enum_style != Default::default() {
257             output_vector.push("--default-enum-style".into());
258             output_vector.push(
259                 match self.options.default_enum_style {
260                     codegen::EnumVariation::Rust {
261                         non_exhaustive: false,
262                     } => "rust",
263                     codegen::EnumVariation::Rust {
264                         non_exhaustive: true,
265                     } => "rust_non_exhaustive",
266                     codegen::EnumVariation::NewType { is_bitfield: true } => {
267                         "bitfield"
268                     }
269                     codegen::EnumVariation::NewType { is_bitfield: false } => {
270                         "newtype"
271                     }
272                     codegen::EnumVariation::Consts => "consts",
273                     codegen::EnumVariation::ModuleConsts => "moduleconsts",
274                 }
275                 .into(),
276             )
277         }
278 
279         if self.options.default_macro_constant_type != Default::default() {
280             output_vector.push("--default-macro-constant-type".into());
281             output_vector
282                 .push(self.options.default_macro_constant_type.as_str().into());
283         }
284 
285         if self.options.default_alias_style != Default::default() {
286             output_vector.push("--default-alias-style".into());
287             output_vector
288                 .push(self.options.default_alias_style.as_str().into());
289         }
290 
291         let regex_sets = &[
292             (&self.options.bitfield_enums, "--bitfield-enum"),
293             (&self.options.newtype_enums, "--newtype-enum"),
294             (&self.options.rustified_enums, "--rustified-enum"),
295             (
296                 &self.options.rustified_non_exhaustive_enums,
297                 "--rustified-enum-non-exhaustive",
298             ),
299             (
300                 &self.options.constified_enum_modules,
301                 "--constified-enum-module",
302             ),
303             (&self.options.constified_enums, "--constified-enum"),
304             (&self.options.type_alias, "--type-alias"),
305             (&self.options.new_type_alias, "--new-type-alias"),
306             (&self.options.new_type_alias_deref, "--new-type-alias-deref"),
307             (&self.options.blocklisted_types, "--blocklist-type"),
308             (&self.options.blocklisted_functions, "--blocklist-function"),
309             (&self.options.blocklisted_items, "--blocklist-item"),
310             (&self.options.opaque_types, "--opaque-type"),
311             (&self.options.allowlisted_functions, "--allowlist-function"),
312             (&self.options.allowlisted_types, "--allowlist-type"),
313             (&self.options.allowlisted_vars, "--allowlist-var"),
314             (&self.options.no_partialeq_types, "--no-partialeq"),
315             (&self.options.no_copy_types, "--no-copy"),
316             (&self.options.no_debug_types, "--no-debug"),
317             (&self.options.no_default_types, "--no-default"),
318             (&self.options.no_hash_types, "--no-hash"),
319         ];
320 
321         for (set, flag) in regex_sets {
322             for item in set.get_items() {
323                 output_vector.push((*flag).to_owned());
324                 output_vector.push(item.to_owned());
325             }
326         }
327 
328         if !self.options.layout_tests {
329             output_vector.push("--no-layout-tests".into());
330         }
331 
332         if self.options.impl_debug {
333             output_vector.push("--impl-debug".into());
334         }
335 
336         if self.options.impl_partialeq {
337             output_vector.push("--impl-partialeq".into());
338         }
339 
340         if !self.options.derive_copy {
341             output_vector.push("--no-derive-copy".into());
342         }
343 
344         if !self.options.derive_debug {
345             output_vector.push("--no-derive-debug".into());
346         }
347 
348         if !self.options.derive_default {
349             output_vector.push("--no-derive-default".into());
350         } else {
351             output_vector.push("--with-derive-default".into());
352         }
353 
354         if self.options.derive_hash {
355             output_vector.push("--with-derive-hash".into());
356         }
357 
358         if self.options.derive_partialord {
359             output_vector.push("--with-derive-partialord".into());
360         }
361 
362         if self.options.derive_ord {
363             output_vector.push("--with-derive-ord".into());
364         }
365 
366         if self.options.derive_partialeq {
367             output_vector.push("--with-derive-partialeq".into());
368         }
369 
370         if self.options.derive_eq {
371             output_vector.push("--with-derive-eq".into());
372         }
373 
374         if self.options.time_phases {
375             output_vector.push("--time-phases".into());
376         }
377 
378         if !self.options.generate_comments {
379             output_vector.push("--no-doc-comments".into());
380         }
381 
382         if !self.options.allowlist_recursively {
383             output_vector.push("--no-recursive-allowlist".into());
384         }
385 
386         if self.options.objc_extern_crate {
387             output_vector.push("--objc-extern-crate".into());
388         }
389 
390         if self.options.generate_block {
391             output_vector.push("--generate-block".into());
392         }
393 
394         if self.options.block_extern_crate {
395             output_vector.push("--block-extern-crate".into());
396         }
397 
398         if self.options.builtins {
399             output_vector.push("--builtins".into());
400         }
401 
402         if let Some(ref prefix) = self.options.ctypes_prefix {
403             output_vector.push("--ctypes-prefix".into());
404             output_vector.push(prefix.clone());
405         }
406 
407         if self.options.anon_fields_prefix != DEFAULT_ANON_FIELDS_PREFIX {
408             output_vector.push("--anon-fields-prefix".into());
409             output_vector.push(self.options.anon_fields_prefix.clone());
410         }
411 
412         if self.options.emit_ast {
413             output_vector.push("--emit-clang-ast".into());
414         }
415 
416         if self.options.emit_ir {
417             output_vector.push("--emit-ir".into());
418         }
419         if let Some(ref graph) = self.options.emit_ir_graphviz {
420             output_vector.push("--emit-ir-graphviz".into());
421             output_vector.push(graph.clone())
422         }
423         if self.options.enable_cxx_namespaces {
424             output_vector.push("--enable-cxx-namespaces".into());
425         }
426         if self.options.enable_function_attribute_detection {
427             output_vector.push("--enable-function-attribute-detection".into());
428         }
429         if self.options.disable_name_namespacing {
430             output_vector.push("--disable-name-namespacing".into());
431         }
432         if self.options.disable_nested_struct_naming {
433             output_vector.push("--disable-nested-struct-naming".into());
434         }
435 
436         if self.options.disable_header_comment {
437             output_vector.push("--disable-header-comment".into());
438         }
439 
440         if !self.options.codegen_config.functions() {
441             output_vector.push("--ignore-functions".into());
442         }
443 
444         output_vector.push("--generate".into());
445 
446         //Temporary placeholder for below 4 options
447         let mut options: Vec<String> = Vec::new();
448         if self.options.codegen_config.functions() {
449             options.push("functions".into());
450         }
451         if self.options.codegen_config.types() {
452             options.push("types".into());
453         }
454         if self.options.codegen_config.vars() {
455             options.push("vars".into());
456         }
457         if self.options.codegen_config.methods() {
458             options.push("methods".into());
459         }
460         if self.options.codegen_config.constructors() {
461             options.push("constructors".into());
462         }
463         if self.options.codegen_config.destructors() {
464             options.push("destructors".into());
465         }
466 
467         output_vector.push(options.join(","));
468 
469         if !self.options.codegen_config.methods() {
470             output_vector.push("--ignore-methods".into());
471         }
472 
473         if !self.options.convert_floats {
474             output_vector.push("--no-convert-floats".into());
475         }
476 
477         if !self.options.prepend_enum_name {
478             output_vector.push("--no-prepend-enum-name".into());
479         }
480 
481         if self.options.fit_macro_constants {
482             output_vector.push("--fit-macro-constant-types".into());
483         }
484 
485         if self.options.array_pointers_in_arguments {
486             output_vector.push("--use-array-pointers-in-arguments".into());
487         }
488 
489         if let Some(ref wasm_import_module_name) =
490             self.options.wasm_import_module_name
491         {
492             output_vector.push("--wasm-import-module-name".into());
493             output_vector.push(wasm_import_module_name.clone());
494         }
495 
496         for line in &self.options.raw_lines {
497             output_vector.push("--raw-line".into());
498             output_vector.push(line.clone());
499         }
500 
501         for (module, lines) in &self.options.module_lines {
502             for line in lines.iter() {
503                 output_vector.push("--module-raw-line".into());
504                 output_vector.push(module.clone());
505                 output_vector.push(line.clone());
506             }
507         }
508 
509         if self.options.use_core {
510             output_vector.push("--use-core".into());
511         }
512 
513         if self.options.conservative_inline_namespaces {
514             output_vector.push("--conservative-inline-namespaces".into());
515         }
516 
517         if self.options.generate_inline_functions {
518             output_vector.push("--generate-inline-functions".into());
519         }
520 
521         if !self.options.record_matches {
522             output_vector.push("--no-record-matches".into());
523         }
524 
525         if self.options.size_t_is_usize {
526             output_vector.push("--size_t-is-usize".into());
527         }
528 
529         if !self.options.rustfmt_bindings {
530             output_vector.push("--no-rustfmt-bindings".into());
531         }
532 
533         if let Some(path) = self
534             .options
535             .rustfmt_configuration_file
536             .as_ref()
537             .and_then(|f| f.to_str())
538         {
539             output_vector.push("--rustfmt-configuration-file".into());
540             output_vector.push(path.into());
541         }
542 
543         if let Some(ref name) = self.options.dynamic_library_name {
544             output_vector.push("--dynamic-loading".into());
545             output_vector.push(name.clone());
546         }
547 
548         if self.options.dynamic_link_require_all {
549             output_vector.push("--dynamic-link-require-all".into());
550         }
551 
552         if self.options.respect_cxx_access_specs {
553             output_vector.push("--respect-cxx-access-specs".into());
554         }
555 
556         if self.options.translate_enum_integer_types {
557             output_vector.push("--translate-enum-integer-types".into());
558         }
559 
560         // Add clang arguments
561 
562         output_vector.push("--".into());
563 
564         if !self.options.clang_args.is_empty() {
565             output_vector.extend(self.options.clang_args.iter().cloned());
566         }
567 
568         if self.input_headers.len() > 1 {
569             // To pass more than one header, we need to pass all but the last
570             // header via the `-include` clang arg
571             for header in &self.input_headers[..self.input_headers.len() - 1] {
572                 output_vector.push("-include".to_string());
573                 output_vector.push(header.clone());
574             }
575         }
576 
577         output_vector
578     }
579 
580     /// Add an input C/C++ header to generate bindings for.
581     ///
582     /// This can be used to generate bindings to a single header:
583     ///
584     /// ```ignore
585     /// let bindings = bindgen::Builder::default()
586     ///     .header("input.h")
587     ///     .generate()
588     ///     .unwrap();
589     /// ```
590     ///
591     /// Or you can invoke it multiple times to generate bindings to multiple
592     /// headers:
593     ///
594     /// ```ignore
595     /// let bindings = bindgen::Builder::default()
596     ///     .header("first.h")
597     ///     .header("second.h")
598     ///     .header("third.h")
599     ///     .generate()
600     ///     .unwrap();
601     /// ```
header<T: Into<String>>(mut self, header: T) -> Builder602     pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
603         self.input_headers.push(header.into());
604         self
605     }
606 
607     /// Add `contents` as an input C/C++ header named `name`.
608     ///
609     /// The file `name` will be added to the clang arguments.
header_contents(mut self, name: &str, contents: &str) -> Builder610     pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
611         // Apparently clang relies on having virtual FS correspondent to
612         // the real one, so we need absolute paths here
613         let absolute_path = env::current_dir()
614             .expect("Cannot retrieve current directory")
615             .join(name)
616             .to_str()
617             .expect("Cannot convert current directory name to string")
618             .to_owned();
619         self.input_header_contents
620             .push((absolute_path, contents.into()));
621         self
622     }
623 
624     /// Specify the rust target
625     ///
626     /// The default is the latest stable Rust version
rust_target(mut self, rust_target: RustTarget) -> Self627     pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
628         self.options.set_rust_target(rust_target);
629         self
630     }
631 
632     /// Disable support for native Rust unions, if supported.
disable_untagged_union(mut self) -> Self633     pub fn disable_untagged_union(mut self) -> Self {
634         self.options.rust_features.untagged_union = false;
635         self
636     }
637 
638     /// Disable insertion of bindgen's version identifier into generated
639     /// bindings.
disable_header_comment(mut self) -> Self640     pub fn disable_header_comment(mut self) -> Self {
641         self.options.disable_header_comment = true;
642         self
643     }
644 
645     /// Set the output graphviz file.
emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder646     pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
647         let path = path.into();
648         self.options.emit_ir_graphviz = Some(path);
649         self
650     }
651 
652     /// Whether the generated bindings should contain documentation comments
653     /// (docstrings) or not. This is set to true by default.
654     ///
655     /// Note that clang by default excludes comments from system headers, pass
656     /// `-fretain-comments-from-system-headers` as
657     /// [`clang_arg`][Builder::clang_arg] to include them. It can also be told
658     /// to process all comments (not just documentation ones) using the
659     /// `-fparse-all-comments` flag. See [slides on clang comment parsing](
660     /// https://llvm.org/devmtg/2012-11/Gribenko_CommentParsing.pdf) for
661     /// background and examples.
generate_comments(mut self, doit: bool) -> Self662     pub fn generate_comments(mut self, doit: bool) -> Self {
663         self.options.generate_comments = doit;
664         self
665     }
666 
667     /// Whether to allowlist recursively or not. Defaults to true.
668     ///
669     /// Given that we have explicitly allowlisted the "initiate_dance_party"
670     /// function in this C header:
671     ///
672     /// ```c
673     /// typedef struct MoonBoots {
674     ///     int bouncy_level;
675     /// } MoonBoots;
676     ///
677     /// void initiate_dance_party(MoonBoots* boots);
678     /// ```
679     ///
680     /// We would normally generate bindings to both the `initiate_dance_party`
681     /// function and the `MoonBoots` struct that it transitively references. By
682     /// configuring with `allowlist_recursively(false)`, `bindgen` will not emit
683     /// bindings for anything except the explicitly allowlisted items, and there
684     /// would be no emitted struct definition for `MoonBoots`. However, the
685     /// `initiate_dance_party` function would still reference `MoonBoots`!
686     ///
687     /// **Disabling this feature will almost certainly cause `bindgen` to emit
688     /// bindings that will not compile!** If you disable this feature, then it
689     /// is *your* responsibility to provide definitions for every type that is
690     /// referenced from an explicitly allowlisted item. One way to provide the
691     /// definitions is by using the [`Builder::raw_line`](#method.raw_line)
692     /// method, another would be to define them in Rust and then `include!(...)`
693     /// the bindings immediately afterwards.
allowlist_recursively(mut self, doit: bool) -> Self694     pub fn allowlist_recursively(mut self, doit: bool) -> Self {
695         self.options.allowlist_recursively = doit;
696         self
697     }
698 
699     /// Deprecated alias for allowlist_recursively.
700     #[deprecated(note = "Use allowlist_recursively instead")]
whitelist_recursively(self, doit: bool) -> Self701     pub fn whitelist_recursively(self, doit: bool) -> Self {
702         self.allowlist_recursively(doit)
703     }
704 
705     /// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
706     /// in the prologue of the files generated from objective-c files
objc_extern_crate(mut self, doit: bool) -> Self707     pub fn objc_extern_crate(mut self, doit: bool) -> Self {
708         self.options.objc_extern_crate = doit;
709         self
710     }
711 
712     /// Generate proper block signatures instead of void pointers.
generate_block(mut self, doit: bool) -> Self713     pub fn generate_block(mut self, doit: bool) -> Self {
714         self.options.generate_block = doit;
715         self
716     }
717 
718     /// Generate `#[macro_use] extern crate block;` instead of `use block;`
719     /// in the prologue of the files generated from apple block files
block_extern_crate(mut self, doit: bool) -> Self720     pub fn block_extern_crate(mut self, doit: bool) -> Self {
721         self.options.block_extern_crate = doit;
722         self
723     }
724 
725     /// Whether to use the clang-provided name mangling. This is true by default
726     /// and probably needed for C++ features.
727     ///
728     /// However, some old libclang versions seem to return incorrect results in
729     /// some cases for non-mangled functions, see [1], so we allow disabling it.
730     ///
731     /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
trust_clang_mangling(mut self, doit: bool) -> Self732     pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
733         self.options.enable_mangling = doit;
734         self
735     }
736 
737     /// Hide the given type from the generated bindings. Regular expressions are
738     /// supported.
739     #[deprecated(note = "Use blocklist_type instead")]
hide_type<T: AsRef<str>>(self, arg: T) -> Builder740     pub fn hide_type<T: AsRef<str>>(self, arg: T) -> Builder {
741         self.blocklist_type(arg)
742     }
743 
744     /// Hide the given type from the generated bindings. Regular expressions are
745     /// supported.
746     #[deprecated(note = "Use blocklist_type instead")]
blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder747     pub fn blacklist_type<T: AsRef<str>>(self, arg: T) -> Builder {
748         self.blocklist_type(arg)
749     }
750 
751     /// Hide the given type from the generated bindings. Regular expressions are
752     /// supported.
753     ///
754     /// To blocklist types prefixed with "mylib" use `"mylib_.*"`.
755     /// For more complicated expressions check
756     /// [regex](https://docs.rs/regex/*/regex/) docs
blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder757     pub fn blocklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
758         self.options.blocklisted_types.insert(arg);
759         self
760     }
761 
762     /// Hide the given function from the generated bindings. Regular expressions
763     /// are supported.
764     #[deprecated(note = "Use blocklist_function instead")]
blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder765     pub fn blacklist_function<T: AsRef<str>>(self, arg: T) -> Builder {
766         self.blocklist_function(arg)
767     }
768 
769     /// Hide the given function from the generated bindings. Regular expressions
770     /// are supported.
771     ///
772     /// To blocklist functions prefixed with "mylib" use `"mylib_.*"`.
773     /// For more complicated expressions check
774     /// [regex](https://docs.rs/regex/*/regex/) docs
blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder775     pub fn blocklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
776         self.options.blocklisted_functions.insert(arg);
777         self
778     }
779 
780     /// Hide the given item from the generated bindings, regardless of
781     /// whether it's a type, function, module, etc. Regular
782     /// expressions are supported.
783     #[deprecated(note = "Use blocklist_item instead")]
blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder784     pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
785         self.options.blocklisted_items.insert(arg);
786         self
787     }
788 
789     /// Hide the given item from the generated bindings, regardless of
790     /// whether it's a type, function, module, etc. Regular
791     /// expressions are supported.
792     ///
793     /// To blocklist items prefixed with "mylib" use `"mylib_.*"`.
794     /// For more complicated expressions check
795     /// [regex](https://docs.rs/regex/*/regex/) docs
blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder796     pub fn blocklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
797         self.options.blocklisted_items.insert(arg);
798         self
799     }
800 
801     /// Treat the given type as opaque in the generated bindings. Regular
802     /// expressions are supported.
803     ///
804     /// To change types prefixed with "mylib" into opaque, use `"mylib_.*"`.
805     /// For more complicated expressions check
806     /// [regex](https://docs.rs/regex/*/regex/) docs
opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder807     pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
808         self.options.opaque_types.insert(arg);
809         self
810     }
811 
812     /// Allowlist the given type so that it (and all types that it transitively
813     /// refers to) appears in the generated bindings. Regular expressions are
814     /// supported.
815     #[deprecated(note = "use allowlist_type instead")]
whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder816     pub fn whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder {
817         self.allowlist_type(arg)
818     }
819 
820     /// Allowlist the given type so that it (and all types that it transitively
821     /// refers to) appears in the generated bindings. Regular expressions are
822     /// supported.
823     #[deprecated(note = "use allowlist_type instead")]
whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder824     pub fn whitelist_type<T: AsRef<str>>(self, arg: T) -> Builder {
825         self.allowlist_type(arg)
826     }
827 
828     /// Allowlist the given type so that it (and all types that it transitively
829     /// refers to) appears in the generated bindings. Regular expressions are
830     /// supported.
831     ///
832     /// To allowlist types prefixed with "mylib" use `"mylib_.*"`.
833     /// For more complicated expressions check
834     /// [regex](https://docs.rs/regex/*/regex/) docs
allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder835     pub fn allowlist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
836         self.options.allowlisted_types.insert(arg);
837         self
838     }
839 
840     /// Allowlist the given function so that it (and all types that it
841     /// transitively refers to) appears in the generated bindings. Regular
842     /// expressions are supported.
843     ///
844     /// To allowlist functions prefixed with "mylib" use `"mylib_.*"`.
845     /// For more complicated expressions check
846     /// [regex](https://docs.rs/regex/*/regex/) docs
allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder847     pub fn allowlist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
848         self.options.allowlisted_functions.insert(arg);
849         self
850     }
851 
852     /// Allowlist the given function.
853     ///
854     /// Deprecated: use allowlist_function instead.
855     #[deprecated(note = "use allowlist_function instead")]
whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder856     pub fn whitelist_function<T: AsRef<str>>(self, arg: T) -> Builder {
857         self.allowlist_function(arg)
858     }
859 
860     /// Allowlist the given function.
861     ///
862     /// Deprecated: use allowlist_function instead.
863     #[deprecated(note = "use allowlist_function instead")]
whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder864     pub fn whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder {
865         self.allowlist_function(arg)
866     }
867 
868     /// Allowlist the given variable so that it (and all types that it
869     /// transitively refers to) appears in the generated bindings. Regular
870     /// expressions are supported.
871     ///
872     /// To allowlist variables prefixed with "mylib" use `"mylib_.*"`.
873     /// For more complicated expressions check
874     /// [regex](https://docs.rs/regex/*/regex/) docs
allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder875     pub fn allowlist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
876         self.options.allowlisted_vars.insert(arg);
877         self
878     }
879 
880     /// Deprecated: use allowlist_var instead.
881     #[deprecated(note = "use allowlist_var instead")]
whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder882     pub fn whitelist_var<T: AsRef<str>>(self, arg: T) -> Builder {
883         self.allowlist_var(arg)
884     }
885 
886     /// Allowlist the given variable.
887     ///
888     /// Deprecated: use allowlist_var instead.
889     #[deprecated(note = "use allowlist_var instead")]
whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder890     pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
891         self.allowlist_var(arg)
892     }
893 
894     /// Set the default style of code to generate for enums
default_enum_style( mut self, arg: codegen::EnumVariation, ) -> Builder895     pub fn default_enum_style(
896         mut self,
897         arg: codegen::EnumVariation,
898     ) -> Builder {
899         self.options.default_enum_style = arg;
900         self
901     }
902 
903     /// Mark the given enum (or set of enums, if using a pattern) as being
904     /// bitfield-like. Regular expressions are supported.
905     ///
906     /// This makes bindgen generate a type that isn't a rust `enum`. Regular
907     /// expressions are supported.
908     ///
909     /// This is similar to the newtype enum style, but with the bitwise
910     /// operators implemented.
bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder911     pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
912         self.options.bitfield_enums.insert(arg);
913         self
914     }
915 
916     /// Mark the given enum (or set of enums, if using a pattern) as a newtype.
917     /// Regular expressions are supported.
918     ///
919     /// This makes bindgen generate a type that isn't a Rust `enum`. Regular
920     /// expressions are supported.
newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder921     pub fn newtype_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
922         self.options.newtype_enums.insert(arg);
923         self
924     }
925 
926     /// Mark the given enum (or set of enums, if using a pattern) as a Rust
927     /// enum.
928     ///
929     /// This makes bindgen generate enums instead of constants. Regular
930     /// expressions are supported.
931     ///
932     /// **Use this with caution**, creating this in unsafe code
933     /// (including FFI) with an invalid value will invoke undefined behaviour.
934     /// You may want to use the newtype enum style instead.
rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder935     pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
936         self.options.rustified_enums.insert(arg);
937         self
938     }
939 
940     /// Mark the given enum (or set of enums, if using a pattern) as a Rust
941     /// enum with the `#[non_exhaustive]` attribute.
942     ///
943     /// This makes bindgen generate enums instead of constants. Regular
944     /// expressions are supported.
945     ///
946     /// **Use this with caution**, creating this in unsafe code
947     /// (including FFI) with an invalid value will invoke undefined behaviour.
948     /// You may want to use the newtype enum style instead.
rustified_non_exhaustive_enum<T: AsRef<str>>( mut self, arg: T, ) -> Builder949     pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(
950         mut self,
951         arg: T,
952     ) -> Builder {
953         self.options.rustified_non_exhaustive_enums.insert(arg);
954         self
955     }
956 
957     /// Mark the given enum (or set of enums, if using a pattern) as a set of
958     /// constants that are not to be put into a module.
constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder959     pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
960         self.options.constified_enums.insert(arg);
961         self
962     }
963 
964     /// Mark the given enum (or set of enums, if using a pattern) as a set of
965     /// constants that should be put into a module.
966     ///
967     /// This makes bindgen generate modules containing constants instead of
968     /// just constants. Regular expressions are supported.
constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder969     pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
970         self.options.constified_enum_modules.insert(arg);
971         self
972     }
973 
974     /// Set the default type for macro constants
default_macro_constant_type( mut self, arg: codegen::MacroTypeVariation, ) -> Builder975     pub fn default_macro_constant_type(
976         mut self,
977         arg: codegen::MacroTypeVariation,
978     ) -> Builder {
979         self.options.default_macro_constant_type = arg;
980         self
981     }
982 
983     /// Set the default style of code to generate for typedefs
default_alias_style( mut self, arg: codegen::AliasVariation, ) -> Builder984     pub fn default_alias_style(
985         mut self,
986         arg: codegen::AliasVariation,
987     ) -> Builder {
988         self.options.default_alias_style = arg;
989         self
990     }
991 
992     /// Mark the given typedef alias (or set of aliases, if using a pattern) to
993     /// use regular Rust type aliasing.
994     ///
995     /// This is the default behavior and should be used if `default_alias_style`
996     /// was set to NewType or NewTypeDeref and you want to override it for a
997     /// set of typedefs.
type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder998     pub fn type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
999         self.options.type_alias.insert(arg);
1000         self
1001     }
1002 
1003     /// Mark the given typedef alias (or set of aliases, if using a pattern) to
1004     /// be generated as a new type by having the aliased type be wrapped in a
1005     /// #[repr(transparent)] struct.
1006     ///
1007     /// Used to enforce stricter type checking.
new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder1008     pub fn new_type_alias<T: AsRef<str>>(mut self, arg: T) -> Builder {
1009         self.options.new_type_alias.insert(arg);
1010         self
1011     }
1012 
1013     /// Mark the given typedef alias (or set of aliases, if using a pattern) to
1014     /// be generated as a new type by having the aliased type be wrapped in a
1015     /// #[repr(transparent)] struct and also have an automatically generated
1016     /// impl's of `Deref` and `DerefMut` to their aliased type.
new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder1017     pub fn new_type_alias_deref<T: AsRef<str>>(mut self, arg: T) -> Builder {
1018         self.options.new_type_alias_deref.insert(arg);
1019         self
1020     }
1021 
1022     /// Add a string to prepend to the generated bindings. The string is passed
1023     /// through without any modification.
raw_line<T: Into<String>>(mut self, arg: T) -> Self1024     pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
1025         self.options.raw_lines.push(arg.into());
1026         self
1027     }
1028 
1029     /// Add a given line to the beginning of module `mod`.
module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self where T: Into<String>, U: Into<String>,1030     pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
1031     where
1032         T: Into<String>,
1033         U: Into<String>,
1034     {
1035         self.options
1036             .module_lines
1037             .entry(mod_.into())
1038             .or_insert_with(Vec::new)
1039             .push(line.into());
1040         self
1041     }
1042 
1043     /// Add a given set of lines to the beginning of module `mod`.
module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self where T: Into<String>, I: IntoIterator, I::Item: Into<String>,1044     pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
1045     where
1046         T: Into<String>,
1047         I: IntoIterator,
1048         I::Item: Into<String>,
1049     {
1050         self.options
1051             .module_lines
1052             .entry(mod_.into())
1053             .or_insert_with(Vec::new)
1054             .extend(lines.into_iter().map(Into::into));
1055         self
1056     }
1057 
1058     /// Add an argument to be passed straight through to clang.
clang_arg<T: Into<String>>(mut self, arg: T) -> Builder1059     pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
1060         self.options.clang_args.push(arg.into());
1061         self
1062     }
1063 
1064     /// Add arguments to be passed straight through to clang.
clang_args<I>(mut self, iter: I) -> Builder where I: IntoIterator, I::Item: AsRef<str>,1065     pub fn clang_args<I>(mut self, iter: I) -> Builder
1066     where
1067         I: IntoIterator,
1068         I::Item: AsRef<str>,
1069     {
1070         for arg in iter {
1071             self = self.clang_arg(arg.as_ref())
1072         }
1073         self
1074     }
1075 
1076     /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
1077     /// in the generated Rust.
emit_builtins(mut self) -> Builder1078     pub fn emit_builtins(mut self) -> Builder {
1079         self.options.builtins = true;
1080         self
1081     }
1082 
1083     /// Avoid converting floats to `f32`/`f64` by default.
no_convert_floats(mut self) -> Self1084     pub fn no_convert_floats(mut self) -> Self {
1085         self.options.convert_floats = false;
1086         self
1087     }
1088 
1089     /// Set whether layout tests should be generated.
layout_tests(mut self, doit: bool) -> Self1090     pub fn layout_tests(mut self, doit: bool) -> Self {
1091         self.options.layout_tests = doit;
1092         self
1093     }
1094 
1095     /// Set whether `Debug` should be implemented, if it can not be derived automatically.
impl_debug(mut self, doit: bool) -> Self1096     pub fn impl_debug(mut self, doit: bool) -> Self {
1097         self.options.impl_debug = doit;
1098         self
1099     }
1100 
1101     /// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
impl_partialeq(mut self, doit: bool) -> Self1102     pub fn impl_partialeq(mut self, doit: bool) -> Self {
1103         self.options.impl_partialeq = doit;
1104         self
1105     }
1106 
1107     /// Set whether `Copy` should be derived by default.
derive_copy(mut self, doit: bool) -> Self1108     pub fn derive_copy(mut self, doit: bool) -> Self {
1109         self.options.derive_copy = doit;
1110         self
1111     }
1112 
1113     /// Set whether `Debug` should be derived by default.
derive_debug(mut self, doit: bool) -> Self1114     pub fn derive_debug(mut self, doit: bool) -> Self {
1115         self.options.derive_debug = doit;
1116         self
1117     }
1118 
1119     /// Set whether `Default` should be derived by default.
derive_default(mut self, doit: bool) -> Self1120     pub fn derive_default(mut self, doit: bool) -> Self {
1121         self.options.derive_default = doit;
1122         self
1123     }
1124 
1125     /// Set whether `Hash` should be derived by default.
derive_hash(mut self, doit: bool) -> Self1126     pub fn derive_hash(mut self, doit: bool) -> Self {
1127         self.options.derive_hash = doit;
1128         self
1129     }
1130 
1131     /// Set whether `PartialOrd` should be derived by default.
1132     /// If we don't compute partialord, we also cannot compute
1133     /// ord. Set the derive_ord to `false` when doit is `false`.
derive_partialord(mut self, doit: bool) -> Self1134     pub fn derive_partialord(mut self, doit: bool) -> Self {
1135         self.options.derive_partialord = doit;
1136         if !doit {
1137             self.options.derive_ord = false;
1138         }
1139         self
1140     }
1141 
1142     /// Set whether `Ord` should be derived by default.
1143     /// We can't compute `Ord` without computing `PartialOrd`,
1144     /// so we set the same option to derive_partialord.
derive_ord(mut self, doit: bool) -> Self1145     pub fn derive_ord(mut self, doit: bool) -> Self {
1146         self.options.derive_ord = doit;
1147         self.options.derive_partialord = doit;
1148         self
1149     }
1150 
1151     /// Set whether `PartialEq` should be derived by default.
1152     ///
1153     /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
1154     /// `Eq` is also disabled when `doit` is `false`.
derive_partialeq(mut self, doit: bool) -> Self1155     pub fn derive_partialeq(mut self, doit: bool) -> Self {
1156         self.options.derive_partialeq = doit;
1157         if !doit {
1158             self.options.derive_eq = false;
1159         }
1160         self
1161     }
1162 
1163     /// Set whether `Eq` should be derived by default.
1164     ///
1165     /// We can't derive `Eq` without also deriving `PartialEq`, so we also
1166     /// enable deriving `PartialEq` when `doit` is `true`.
derive_eq(mut self, doit: bool) -> Self1167     pub fn derive_eq(mut self, doit: bool) -> Self {
1168         self.options.derive_eq = doit;
1169         if doit {
1170             self.options.derive_partialeq = doit;
1171         }
1172         self
1173     }
1174 
1175     /// Set whether or not to time bindgen phases, and print information to
1176     /// stderr.
time_phases(mut self, doit: bool) -> Self1177     pub fn time_phases(mut self, doit: bool) -> Self {
1178         self.options.time_phases = doit;
1179         self
1180     }
1181 
1182     /// Emit Clang AST.
emit_clang_ast(mut self) -> Builder1183     pub fn emit_clang_ast(mut self) -> Builder {
1184         self.options.emit_ast = true;
1185         self
1186     }
1187 
1188     /// Emit IR.
emit_ir(mut self) -> Builder1189     pub fn emit_ir(mut self) -> Builder {
1190         self.options.emit_ir = true;
1191         self
1192     }
1193 
1194     /// Enable C++ namespaces.
enable_cxx_namespaces(mut self) -> Builder1195     pub fn enable_cxx_namespaces(mut self) -> Builder {
1196         self.options.enable_cxx_namespaces = true;
1197         self
1198     }
1199 
1200     /// Enable detecting must_use attributes on C functions.
1201     ///
1202     /// This is quite slow in some cases (see #1465), so it's disabled by
1203     /// default.
1204     ///
1205     /// Note that for this to do something meaningful for now at least, the rust
1206     /// target version has to have support for `#[must_use]`.
enable_function_attribute_detection(mut self) -> Self1207     pub fn enable_function_attribute_detection(mut self) -> Self {
1208         self.options.enable_function_attribute_detection = true;
1209         self
1210     }
1211 
1212     /// Disable name auto-namespacing.
1213     ///
1214     /// By default, bindgen mangles names like `foo::bar::Baz` to look like
1215     /// `foo_bar_Baz` instead of just `Baz`.
1216     ///
1217     /// This method disables that behavior.
1218     ///
1219     /// Note that this intentionally does not change the names used for
1220     /// allowlisting and blocklisting, which should still be mangled with the
1221     /// namespaces.
1222     ///
1223     /// Note, also, that this option may cause bindgen to generate duplicate
1224     /// names.
disable_name_namespacing(mut self) -> Builder1225     pub fn disable_name_namespacing(mut self) -> Builder {
1226         self.options.disable_name_namespacing = true;
1227         self
1228     }
1229 
1230     /// Disable nested struct naming.
1231     ///
1232     /// The following structs have different names for C and C++. In case of C
1233     /// they are visible as `foo` and `bar`. In case of C++ they are visible as
1234     /// `foo` and `foo::bar`.
1235     ///
1236     /// ```c
1237     /// struct foo {
1238     ///     struct bar {
1239     ///     } b;
1240     /// };
1241     /// ```
1242     ///
1243     /// Bindgen wants to avoid duplicate names by default so it follows C++ naming
1244     /// and it generates `foo`/`foo_bar` instead of just `foo`/`bar`.
1245     ///
1246     /// This method disables this behavior and it is indented to be used only
1247     /// for headers that were written for C.
disable_nested_struct_naming(mut self) -> Builder1248     pub fn disable_nested_struct_naming(mut self) -> Builder {
1249         self.options.disable_nested_struct_naming = true;
1250         self
1251     }
1252 
1253     /// Treat inline namespaces conservatively.
1254     ///
1255     /// This is tricky, because in C++ is technically legal to override an item
1256     /// defined in an inline namespace:
1257     ///
1258     /// ```cpp
1259     /// inline namespace foo {
1260     ///     using Bar = int;
1261     /// }
1262     /// using Bar = long;
1263     /// ```
1264     ///
1265     /// Even though referencing `Bar` is a compiler error.
1266     ///
1267     /// We want to support this (arguably esoteric) use case, but we don't want
1268     /// to make the rest of bindgen users pay an usability penalty for that.
1269     ///
1270     /// To support this, we need to keep all the inline namespaces around, but
1271     /// then bindgen usage is a bit more difficult, because you cannot
1272     /// reference, e.g., `std::string` (you'd need to use the proper inline
1273     /// namespace).
1274     ///
1275     /// We could complicate a lot of the logic to detect name collisions, and if
1276     /// not detected generate a `pub use inline_ns::*` or something like that.
1277     ///
1278     /// That's probably something we can do if we see this option is needed in a
1279     /// lot of cases, to improve it's usability, but my guess is that this is
1280     /// not going to be too useful.
conservative_inline_namespaces(mut self) -> Builder1281     pub fn conservative_inline_namespaces(mut self) -> Builder {
1282         self.options.conservative_inline_namespaces = true;
1283         self
1284     }
1285 
1286     /// Whether inline functions should be generated or not.
1287     ///
1288     /// Note that they will usually not work. However you can use
1289     /// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
1290     /// responsible of compiling the library to make them callable.
generate_inline_functions(mut self, doit: bool) -> Self1291     pub fn generate_inline_functions(mut self, doit: bool) -> Self {
1292         self.options.generate_inline_functions = doit;
1293         self
1294     }
1295 
1296     /// Ignore functions.
ignore_functions(mut self) -> Builder1297     pub fn ignore_functions(mut self) -> Builder {
1298         self.options.codegen_config.remove(CodegenConfig::FUNCTIONS);
1299         self
1300     }
1301 
1302     /// Ignore methods.
ignore_methods(mut self) -> Builder1303     pub fn ignore_methods(mut self) -> Builder {
1304         self.options.codegen_config.remove(CodegenConfig::METHODS);
1305         self
1306     }
1307 
1308     /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
1309     #[deprecated(note = "please use `rust_target` instead")]
unstable_rust(self, doit: bool) -> Self1310     pub fn unstable_rust(self, doit: bool) -> Self {
1311         let rust_target = if doit {
1312             RustTarget::Nightly
1313         } else {
1314             LATEST_STABLE_RUST
1315         };
1316         self.rust_target(rust_target)
1317     }
1318 
1319     /// Use core instead of libstd in the generated bindings.
use_core(mut self) -> Builder1320     pub fn use_core(mut self) -> Builder {
1321         self.options.use_core = true;
1322         self
1323     }
1324 
1325     /// Use the given prefix for the raw types instead of `::std::os::raw`.
ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder1326     pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
1327         self.options.ctypes_prefix = Some(prefix.into());
1328         self
1329     }
1330 
1331     /// Use the given prefix for the anon fields.
anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder1332     pub fn anon_fields_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
1333         self.options.anon_fields_prefix = prefix.into();
1334         self
1335     }
1336 
1337     /// Allows configuring types in different situations, see the
1338     /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
parse_callbacks( mut self, cb: Box<dyn callbacks::ParseCallbacks>, ) -> Self1339     pub fn parse_callbacks(
1340         mut self,
1341         cb: Box<dyn callbacks::ParseCallbacks>,
1342     ) -> Self {
1343         self.options.parse_callbacks = Some(cb);
1344         self
1345     }
1346 
1347     /// Choose what to generate using a
1348     /// [`CodegenConfig`](./struct.CodegenConfig.html).
with_codegen_config(mut self, config: CodegenConfig) -> Self1349     pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
1350         self.options.codegen_config = config;
1351         self
1352     }
1353 
1354     /// Whether to detect include paths using clang_sys.
detect_include_paths(mut self, doit: bool) -> Self1355     pub fn detect_include_paths(mut self, doit: bool) -> Self {
1356         self.options.detect_include_paths = doit;
1357         self
1358     }
1359 
1360     /// Whether to try to fit macro constants to types smaller than u32/i32
fit_macro_constants(mut self, doit: bool) -> Self1361     pub fn fit_macro_constants(mut self, doit: bool) -> Self {
1362         self.options.fit_macro_constants = doit;
1363         self
1364     }
1365 
1366     /// Prepend the enum name to constant or newtype variants.
prepend_enum_name(mut self, doit: bool) -> Self1367     pub fn prepend_enum_name(mut self, doit: bool) -> Self {
1368         self.options.prepend_enum_name = doit;
1369         self
1370     }
1371 
1372     /// Set whether `size_t` should be translated to `usize` automatically.
size_t_is_usize(mut self, is: bool) -> Self1373     pub fn size_t_is_usize(mut self, is: bool) -> Self {
1374         self.options.size_t_is_usize = is;
1375         self
1376     }
1377 
1378     /// Set whether rustfmt should format the generated bindings.
rustfmt_bindings(mut self, doit: bool) -> Self1379     pub fn rustfmt_bindings(mut self, doit: bool) -> Self {
1380         self.options.rustfmt_bindings = doit;
1381         self
1382     }
1383 
1384     /// Set whether we should record matched items in our regex sets.
record_matches(mut self, doit: bool) -> Self1385     pub fn record_matches(mut self, doit: bool) -> Self {
1386         self.options.record_matches = doit;
1387         self
1388     }
1389 
1390     /// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt
1391     /// options are used.
rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self1392     pub fn rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self {
1393         self = self.rustfmt_bindings(true);
1394         self.options.rustfmt_configuration_file = path;
1395         self
1396     }
1397 
1398     /// Sets an explicit path to rustfmt, to be used when rustfmt is enabled.
with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self1399     pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
1400         self.options.rustfmt_path = Some(path.into());
1401         self
1402     }
1403 
1404     /// Generate the Rust bindings using the options built up thus far.
generate(mut self) -> Result<Bindings, ()>1405     pub fn generate(mut self) -> Result<Bindings, ()> {
1406         // Add any extra arguments from the environment to the clang command line.
1407         if let Some(extra_clang_args) =
1408             env::var("BINDGEN_EXTRA_CLANG_ARGS").ok()
1409         {
1410             // Try to parse it with shell quoting. If we fail, make it one single big argument.
1411             if let Some(strings) = shlex::split(&extra_clang_args) {
1412                 self.options.clang_args.extend(strings);
1413             } else {
1414                 self.options.clang_args.push(extra_clang_args);
1415             };
1416         }
1417 
1418         // Transform input headers to arguments on the clang command line.
1419         self.options.input_header = self.input_headers.pop();
1420         self.options
1421             .clang_args
1422             .extend(self.input_headers.drain(..).flat_map(|header| {
1423                 iter::once("-include".into()).chain(iter::once(header))
1424             }));
1425 
1426         self.options.input_unsaved_files.extend(
1427             self.input_header_contents
1428                 .drain(..)
1429                 .map(|(name, contents)| {
1430                     clang::UnsavedFile::new(&name, &contents)
1431                 }),
1432         );
1433 
1434         Bindings::generate(self.options)
1435     }
1436 
1437     /// Preprocess and dump the input header files to disk.
1438     ///
1439     /// This is useful when debugging bindgen, using C-Reduce, or when filing
1440     /// issues. The resulting file will be named something like `__bindgen.i` or
1441     /// `__bindgen.ii`
dump_preprocessed_input(&self) -> io::Result<()>1442     pub fn dump_preprocessed_input(&self) -> io::Result<()> {
1443         let clang =
1444             clang_sys::support::Clang::find(None, &[]).ok_or_else(|| {
1445                 io::Error::new(
1446                     io::ErrorKind::Other,
1447                     "Cannot find clang executable",
1448                 )
1449             })?;
1450 
1451         // The contents of a wrapper file that includes all the input header
1452         // files.
1453         let mut wrapper_contents = String::new();
1454 
1455         // Whether we are working with C or C++ inputs.
1456         let mut is_cpp = args_are_cpp(&self.options.clang_args);
1457 
1458         // For each input header, add `#include "$header"`.
1459         for header in &self.input_headers {
1460             is_cpp |= file_is_cpp(header);
1461 
1462             wrapper_contents.push_str("#include \"");
1463             wrapper_contents.push_str(header);
1464             wrapper_contents.push_str("\"\n");
1465         }
1466 
1467         // For each input header content, add a prefix line of `#line 0 "$name"`
1468         // followed by the contents.
1469         for &(ref name, ref contents) in &self.input_header_contents {
1470             is_cpp |= file_is_cpp(name);
1471 
1472             wrapper_contents.push_str("#line 0 \"");
1473             wrapper_contents.push_str(name);
1474             wrapper_contents.push_str("\"\n");
1475             wrapper_contents.push_str(contents);
1476         }
1477 
1478         let wrapper_path = PathBuf::from(if is_cpp {
1479             "__bindgen.cpp"
1480         } else {
1481             "__bindgen.c"
1482         });
1483 
1484         {
1485             let mut wrapper_file = File::create(&wrapper_path)?;
1486             wrapper_file.write_all(wrapper_contents.as_bytes())?;
1487         }
1488 
1489         let mut cmd = Command::new(&clang.path);
1490         cmd.arg("-save-temps")
1491             .arg("-E")
1492             .arg("-C")
1493             .arg("-c")
1494             .arg(&wrapper_path)
1495             .stdout(Stdio::piped());
1496 
1497         for a in &self.options.clang_args {
1498             cmd.arg(a);
1499         }
1500 
1501         let mut child = cmd.spawn()?;
1502 
1503         let mut preprocessed = child.stdout.take().unwrap();
1504         let mut file = File::create(if is_cpp {
1505             "__bindgen.ii"
1506         } else {
1507             "__bindgen.i"
1508         })?;
1509         io::copy(&mut preprocessed, &mut file)?;
1510 
1511         if child.wait()?.success() {
1512             Ok(())
1513         } else {
1514             Err(io::Error::new(
1515                 io::ErrorKind::Other,
1516                 "clang exited with non-zero status",
1517             ))
1518         }
1519     }
1520 
1521     /// Don't derive `PartialEq` for a given type. Regular
1522     /// expressions are supported.
no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder1523     pub fn no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder {
1524         self.options.no_partialeq_types.insert(arg.into());
1525         self
1526     }
1527 
1528     /// Don't derive `Copy` for a given type. Regular
1529     /// expressions are supported.
no_copy<T: Into<String>>(mut self, arg: T) -> Self1530     pub fn no_copy<T: Into<String>>(mut self, arg: T) -> Self {
1531         self.options.no_copy_types.insert(arg.into());
1532         self
1533     }
1534 
1535     /// Don't derive `Debug` for a given type. Regular
1536     /// expressions are supported.
no_debug<T: Into<String>>(mut self, arg: T) -> Self1537     pub fn no_debug<T: Into<String>>(mut self, arg: T) -> Self {
1538         self.options.no_debug_types.insert(arg.into());
1539         self
1540     }
1541 
1542     /// Don't derive/impl `Default` for a given type. Regular
1543     /// expressions are supported.
no_default<T: Into<String>>(mut self, arg: T) -> Self1544     pub fn no_default<T: Into<String>>(mut self, arg: T) -> Self {
1545         self.options.no_default_types.insert(arg.into());
1546         self
1547     }
1548 
1549     /// Don't derive `Hash` for a given type. Regular
1550     /// expressions are supported.
no_hash<T: Into<String>>(mut self, arg: T) -> Builder1551     pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
1552         self.options.no_hash_types.insert(arg.into());
1553         self
1554     }
1555 
1556     /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut)
array_pointers_in_arguments(mut self, doit: bool) -> Self1557     pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
1558         self.options.array_pointers_in_arguments = doit;
1559         self
1560     }
1561 
1562     /// Set the wasm import module name
wasm_import_module_name<T: Into<String>>( mut self, import_name: T, ) -> Self1563     pub fn wasm_import_module_name<T: Into<String>>(
1564         mut self,
1565         import_name: T,
1566     ) -> Self {
1567         self.options.wasm_import_module_name = Some(import_name.into());
1568         self
1569     }
1570 
1571     /// Specify the dynamic library name if we are generating bindings for a shared library.
dynamic_library_name<T: Into<String>>( mut self, dynamic_library_name: T, ) -> Self1572     pub fn dynamic_library_name<T: Into<String>>(
1573         mut self,
1574         dynamic_library_name: T,
1575     ) -> Self {
1576         self.options.dynamic_library_name = Some(dynamic_library_name.into());
1577         self
1578     }
1579 
1580     /// Require successful linkage for all routines in a shared library.
1581     /// This allows us to optimize function calls by being able to safely assume function pointers
1582     /// are valid.
dynamic_link_require_all(mut self, req: bool) -> Self1583     pub fn dynamic_link_require_all(mut self, req: bool) -> Self {
1584         self.options.dynamic_link_require_all = req;
1585         self
1586     }
1587 
1588     /// Generate bindings as `pub` only if the bound item is publically accessible by C++.
respect_cxx_access_specs(mut self, doit: bool) -> Self1589     pub fn respect_cxx_access_specs(mut self, doit: bool) -> Self {
1590         self.options.respect_cxx_access_specs = doit;
1591         self
1592     }
1593 
1594     /// Always translate enum integer types to native Rust integer types.
1595     ///
1596     /// This will result in enums having types such as `u32` and `i16` instead
1597     /// of `c_uint` and `c_short`. Types for Rustified enums are always
1598     /// translated.
translate_enum_integer_types(mut self, doit: bool) -> Self1599     pub fn translate_enum_integer_types(mut self, doit: bool) -> Self {
1600         self.options.translate_enum_integer_types = doit;
1601         self
1602     }
1603 }
1604 
1605 /// Configuration options for generated bindings.
1606 #[derive(Debug)]
1607 struct BindgenOptions {
1608     /// The set of types that have been blocklisted and should not appear
1609     /// anywhere in the generated code.
1610     blocklisted_types: RegexSet,
1611 
1612     /// The set of functions that have been blocklisted and should not appear
1613     /// in the generated code.
1614     blocklisted_functions: RegexSet,
1615 
1616     /// The set of items, regardless of item-type, that have been
1617     /// blocklisted and should not appear in the generated code.
1618     blocklisted_items: RegexSet,
1619 
1620     /// The set of types that should be treated as opaque structures in the
1621     /// generated code.
1622     opaque_types: RegexSet,
1623 
1624     /// The explicit rustfmt path.
1625     rustfmt_path: Option<PathBuf>,
1626 
1627     /// The set of types that we should have bindings for in the generated
1628     /// code.
1629     ///
1630     /// This includes all types transitively reachable from any type in this
1631     /// set. One might think of allowlisted types/vars/functions as GC roots,
1632     /// and the generated Rust code as including everything that gets marked.
1633     allowlisted_types: RegexSet,
1634 
1635     /// Allowlisted functions. See docs for `allowlisted_types` for more.
1636     allowlisted_functions: RegexSet,
1637 
1638     /// Allowlisted variables. See docs for `allowlisted_types` for more.
1639     allowlisted_vars: RegexSet,
1640 
1641     /// The default style of code to generate for enums
1642     default_enum_style: codegen::EnumVariation,
1643 
1644     /// The enum patterns to mark an enum as a bitfield
1645     /// (newtype with bitwise operations).
1646     bitfield_enums: RegexSet,
1647 
1648     /// The enum patterns to mark an enum as a newtype.
1649     newtype_enums: RegexSet,
1650 
1651     /// The enum patterns to mark an enum as a Rust enum.
1652     rustified_enums: RegexSet,
1653 
1654     /// The enum patterns to mark an enum as a non-exhaustive Rust enum.
1655     rustified_non_exhaustive_enums: RegexSet,
1656 
1657     /// The enum patterns to mark an enum as a module of constants.
1658     constified_enum_modules: RegexSet,
1659 
1660     /// The enum patterns to mark an enum as a set of constants.
1661     constified_enums: RegexSet,
1662 
1663     /// The default type for C macro constants.
1664     default_macro_constant_type: codegen::MacroTypeVariation,
1665 
1666     /// The default style of code to generate for typedefs.
1667     default_alias_style: codegen::AliasVariation,
1668 
1669     /// Typedef patterns that will use regular type aliasing.
1670     type_alias: RegexSet,
1671 
1672     /// Typedef patterns that will be aliased by creating a new struct.
1673     new_type_alias: RegexSet,
1674 
1675     /// Typedef patterns that will be wrapped in a new struct and have
1676     /// Deref and Deref to their aliased type.
1677     new_type_alias_deref: RegexSet,
1678 
1679     /// Whether we should generate builtins or not.
1680     builtins: bool,
1681 
1682     /// True if we should dump the Clang AST for debugging purposes.
1683     emit_ast: bool,
1684 
1685     /// True if we should dump our internal IR for debugging purposes.
1686     emit_ir: bool,
1687 
1688     /// Output graphviz dot file.
1689     emit_ir_graphviz: Option<String>,
1690 
1691     /// True if we should emulate C++ namespaces with Rust modules in the
1692     /// generated bindings.
1693     enable_cxx_namespaces: bool,
1694 
1695     /// True if we should try to find unexposed attributes in functions, in
1696     /// order to be able to generate #[must_use] attributes in Rust.
1697     enable_function_attribute_detection: bool,
1698 
1699     /// True if we should avoid mangling names with namespaces.
1700     disable_name_namespacing: bool,
1701 
1702     /// True if we should avoid generating nested struct names.
1703     disable_nested_struct_naming: bool,
1704 
1705     /// True if we should avoid embedding version identifiers into source code.
1706     disable_header_comment: bool,
1707 
1708     /// True if we should generate layout tests for generated structures.
1709     layout_tests: bool,
1710 
1711     /// True if we should implement the Debug trait for C/C++ structures and types
1712     /// that do not support automatically deriving Debug.
1713     impl_debug: bool,
1714 
1715     /// True if we should implement the PartialEq trait for C/C++ structures and types
1716     /// that do not support automatically deriving PartialEq.
1717     impl_partialeq: bool,
1718 
1719     /// True if we should derive Copy trait implementations for C/C++ structures
1720     /// and types.
1721     derive_copy: bool,
1722 
1723     /// True if we should derive Debug trait implementations for C/C++ structures
1724     /// and types.
1725     derive_debug: bool,
1726 
1727     /// True if we should derive Default trait implementations for C/C++ structures
1728     /// and types.
1729     derive_default: bool,
1730 
1731     /// True if we should derive Hash trait implementations for C/C++ structures
1732     /// and types.
1733     derive_hash: bool,
1734 
1735     /// True if we should derive PartialOrd trait implementations for C/C++ structures
1736     /// and types.
1737     derive_partialord: bool,
1738 
1739     /// True if we should derive Ord trait implementations for C/C++ structures
1740     /// and types.
1741     derive_ord: bool,
1742 
1743     /// True if we should derive PartialEq trait implementations for C/C++ structures
1744     /// and types.
1745     derive_partialeq: bool,
1746 
1747     /// True if we should derive Eq trait implementations for C/C++ structures
1748     /// and types.
1749     derive_eq: bool,
1750 
1751     /// True if we should avoid using libstd to use libcore instead.
1752     use_core: bool,
1753 
1754     /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
1755     ctypes_prefix: Option<String>,
1756 
1757     /// The prefix for the anon fields.
1758     anon_fields_prefix: String,
1759 
1760     /// Whether to time the bindgen phases.
1761     time_phases: bool,
1762 
1763     /// True if we should generate constant names that are **directly** under
1764     /// namespaces.
1765     namespaced_constants: bool,
1766 
1767     /// True if we should use MSVC name mangling rules.
1768     msvc_mangling: bool,
1769 
1770     /// Whether we should convert float types to f32/f64 types.
1771     convert_floats: bool,
1772 
1773     /// The set of raw lines to prepend to the top-level module of generated
1774     /// Rust code.
1775     raw_lines: Vec<String>,
1776 
1777     /// The set of raw lines to prepend to each of the modules.
1778     ///
1779     /// This only makes sense if the `enable_cxx_namespaces` option is set.
1780     module_lines: HashMap<String, Vec<String>>,
1781 
1782     /// The set of arguments to pass straight through to Clang.
1783     clang_args: Vec<String>,
1784 
1785     /// The input header file.
1786     input_header: Option<String>,
1787 
1788     /// Unsaved files for input.
1789     input_unsaved_files: Vec<clang::UnsavedFile>,
1790 
1791     /// A user-provided visitor to allow customizing different kinds of
1792     /// situations.
1793     parse_callbacks: Option<Box<dyn callbacks::ParseCallbacks>>,
1794 
1795     /// Which kind of items should we generate? By default, we'll generate all
1796     /// of them.
1797     codegen_config: CodegenConfig,
1798 
1799     /// Whether to treat inline namespaces conservatively.
1800     ///
1801     /// See the builder method description for more details.
1802     conservative_inline_namespaces: bool,
1803 
1804     /// Whether to keep documentation comments in the generated output. See the
1805     /// documentation for more details. Defaults to true.
1806     generate_comments: bool,
1807 
1808     /// Whether to generate inline functions. Defaults to false.
1809     generate_inline_functions: bool,
1810 
1811     /// Whether to allowlist types recursively. Defaults to true.
1812     allowlist_recursively: bool,
1813 
1814     /// Instead of emitting 'use objc;' to files generated from objective c files,
1815     /// generate '#[macro_use] extern crate objc;'
1816     objc_extern_crate: bool,
1817 
1818     /// Instead of emitting 'use block;' to files generated from objective c files,
1819     /// generate '#[macro_use] extern crate block;'
1820     generate_block: bool,
1821 
1822     /// Instead of emitting 'use block;' to files generated from objective c files,
1823     /// generate '#[macro_use] extern crate block;'
1824     block_extern_crate: bool,
1825 
1826     /// Whether to use the clang-provided name mangling. This is true and
1827     /// probably needed for C++ features.
1828     ///
1829     /// However, some old libclang versions seem to return incorrect results in
1830     /// some cases for non-mangled functions, see [1], so we allow disabling it.
1831     ///
1832     /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
1833     enable_mangling: bool,
1834 
1835     /// Whether to detect include paths using clang_sys.
1836     detect_include_paths: bool,
1837 
1838     /// Whether to try to fit macro constants into types smaller than u32/i32
1839     fit_macro_constants: bool,
1840 
1841     /// Whether to prepend the enum name to constant or newtype variants.
1842     prepend_enum_name: bool,
1843 
1844     /// Version of the Rust compiler to target
1845     rust_target: RustTarget,
1846 
1847     /// Features to enable, derived from `rust_target`
1848     rust_features: RustFeatures,
1849 
1850     /// Whether we should record which items in the regex sets ever matched.
1851     ///
1852     /// This may be a bit slower, but will enable reporting of unused allowlist
1853     /// items via the `error!` log.
1854     record_matches: bool,
1855 
1856     /// Whether `size_t` should be translated to `usize` automatically.
1857     size_t_is_usize: bool,
1858 
1859     /// Whether rustfmt should format the generated bindings.
1860     rustfmt_bindings: bool,
1861 
1862     /// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
1863     /// options are used.
1864     rustfmt_configuration_file: Option<PathBuf>,
1865 
1866     /// The set of types that we should not derive `PartialEq` for.
1867     no_partialeq_types: RegexSet,
1868 
1869     /// The set of types that we should not derive `Copy` for.
1870     no_copy_types: RegexSet,
1871 
1872     /// The set of types that we should not derive `Debug` for.
1873     no_debug_types: RegexSet,
1874 
1875     /// The set of types that we should not derive/impl `Default` for.
1876     no_default_types: RegexSet,
1877 
1878     /// The set of types that we should not derive `Hash` for.
1879     no_hash_types: RegexSet,
1880 
1881     /// Decide if C arrays should be regular pointers in rust or array pointers
1882     array_pointers_in_arguments: bool,
1883 
1884     /// Wasm import module name.
1885     wasm_import_module_name: Option<String>,
1886 
1887     /// The name of the dynamic library (if we are generating bindings for a shared library). If
1888     /// this is None, no dynamic bindings are created.
1889     dynamic_library_name: Option<String>,
1890 
1891     /// Require successful linkage for all routines in a shared library.
1892     /// This allows us to optimize function calls by being able to safely assume function pointers
1893     /// are valid. No effect if `dynamic_library_name` is None.
1894     dynamic_link_require_all: bool,
1895 
1896     /// Only make generated bindings `pub` if the items would be publically accessible
1897     /// by C++.
1898     respect_cxx_access_specs: bool,
1899 
1900     /// Always translate enum integer types to native Rust integer types.
1901     translate_enum_integer_types: bool,
1902 }
1903 
1904 /// TODO(emilio): This is sort of a lie (see the error message that results from
1905 /// removing this), but since we don't share references across panic boundaries
1906 /// it's ok.
1907 impl ::std::panic::UnwindSafe for BindgenOptions {}
1908 
1909 impl BindgenOptions {
build(&mut self)1910     fn build(&mut self) {
1911         let mut regex_sets = [
1912             &mut self.allowlisted_vars,
1913             &mut self.allowlisted_types,
1914             &mut self.allowlisted_functions,
1915             &mut self.blocklisted_types,
1916             &mut self.blocklisted_functions,
1917             &mut self.blocklisted_items,
1918             &mut self.opaque_types,
1919             &mut self.bitfield_enums,
1920             &mut self.constified_enums,
1921             &mut self.constified_enum_modules,
1922             &mut self.newtype_enums,
1923             &mut self.rustified_enums,
1924             &mut self.rustified_non_exhaustive_enums,
1925             &mut self.type_alias,
1926             &mut self.new_type_alias,
1927             &mut self.new_type_alias_deref,
1928             &mut self.no_partialeq_types,
1929             &mut self.no_copy_types,
1930             &mut self.no_debug_types,
1931             &mut self.no_default_types,
1932             &mut self.no_hash_types,
1933         ];
1934         let record_matches = self.record_matches;
1935         for regex_set in &mut regex_sets {
1936             regex_set.build(record_matches);
1937         }
1938     }
1939 
1940     /// Update rust target version
set_rust_target(&mut self, rust_target: RustTarget)1941     pub fn set_rust_target(&mut self, rust_target: RustTarget) {
1942         self.rust_target = rust_target;
1943 
1944         // Keep rust_features synced with rust_target
1945         self.rust_features = rust_target.into();
1946     }
1947 
1948     /// Get features supported by target Rust version
rust_features(&self) -> RustFeatures1949     pub fn rust_features(&self) -> RustFeatures {
1950         self.rust_features
1951     }
1952 }
1953 
1954 impl Default for BindgenOptions {
default() -> BindgenOptions1955     fn default() -> BindgenOptions {
1956         let rust_target = RustTarget::default();
1957 
1958         BindgenOptions {
1959             rust_target,
1960             rust_features: rust_target.into(),
1961             blocklisted_types: Default::default(),
1962             blocklisted_functions: Default::default(),
1963             blocklisted_items: Default::default(),
1964             opaque_types: Default::default(),
1965             rustfmt_path: Default::default(),
1966             allowlisted_types: Default::default(),
1967             allowlisted_functions: Default::default(),
1968             allowlisted_vars: Default::default(),
1969             default_enum_style: Default::default(),
1970             bitfield_enums: Default::default(),
1971             newtype_enums: Default::default(),
1972             rustified_enums: Default::default(),
1973             rustified_non_exhaustive_enums: Default::default(),
1974             constified_enums: Default::default(),
1975             constified_enum_modules: Default::default(),
1976             default_macro_constant_type: Default::default(),
1977             default_alias_style: Default::default(),
1978             type_alias: Default::default(),
1979             new_type_alias: Default::default(),
1980             new_type_alias_deref: Default::default(),
1981             builtins: false,
1982             emit_ast: false,
1983             emit_ir: false,
1984             emit_ir_graphviz: None,
1985             layout_tests: true,
1986             impl_debug: false,
1987             impl_partialeq: false,
1988             derive_copy: true,
1989             derive_debug: true,
1990             derive_default: false,
1991             derive_hash: false,
1992             derive_partialord: false,
1993             derive_ord: false,
1994             derive_partialeq: false,
1995             derive_eq: false,
1996             enable_cxx_namespaces: false,
1997             enable_function_attribute_detection: false,
1998             disable_name_namespacing: false,
1999             disable_nested_struct_naming: false,
2000             disable_header_comment: false,
2001             use_core: false,
2002             ctypes_prefix: None,
2003             anon_fields_prefix: DEFAULT_ANON_FIELDS_PREFIX.into(),
2004             namespaced_constants: true,
2005             msvc_mangling: false,
2006             convert_floats: true,
2007             raw_lines: vec![],
2008             module_lines: HashMap::default(),
2009             clang_args: vec![],
2010             input_header: None,
2011             input_unsaved_files: vec![],
2012             parse_callbacks: None,
2013             codegen_config: CodegenConfig::all(),
2014             conservative_inline_namespaces: false,
2015             generate_comments: true,
2016             generate_inline_functions: false,
2017             allowlist_recursively: true,
2018             generate_block: false,
2019             objc_extern_crate: false,
2020             block_extern_crate: false,
2021             enable_mangling: true,
2022             detect_include_paths: true,
2023             fit_macro_constants: false,
2024             prepend_enum_name: true,
2025             time_phases: false,
2026             record_matches: true,
2027             rustfmt_bindings: true,
2028             size_t_is_usize: false,
2029             rustfmt_configuration_file: None,
2030             no_partialeq_types: Default::default(),
2031             no_copy_types: Default::default(),
2032             no_debug_types: Default::default(),
2033             no_default_types: Default::default(),
2034             no_hash_types: Default::default(),
2035             array_pointers_in_arguments: false,
2036             wasm_import_module_name: None,
2037             dynamic_library_name: None,
2038             dynamic_link_require_all: false,
2039             respect_cxx_access_specs: false,
2040             translate_enum_integer_types: false,
2041         }
2042     }
2043 }
2044 
2045 #[cfg(feature = "runtime")]
ensure_libclang_is_loaded()2046 fn ensure_libclang_is_loaded() {
2047     if clang_sys::is_loaded() {
2048         return;
2049     }
2050 
2051     // XXX (issue #350): Ensure that our dynamically loaded `libclang`
2052     // doesn't get dropped prematurely, nor is loaded multiple times
2053     // across different threads.
2054 
2055     lazy_static! {
2056         static ref LIBCLANG: std::sync::Arc<clang_sys::SharedLibrary> = {
2057             clang_sys::load().expect("Unable to find libclang");
2058             clang_sys::get_library().expect(
2059                 "We just loaded libclang and it had better still be \
2060                  here!",
2061             )
2062         };
2063     }
2064 
2065     clang_sys::set_library(Some(LIBCLANG.clone()));
2066 }
2067 
2068 #[cfg(not(feature = "runtime"))]
ensure_libclang_is_loaded()2069 fn ensure_libclang_is_loaded() {}
2070 
2071 /// Generated Rust bindings.
2072 #[derive(Debug)]
2073 pub struct Bindings {
2074     options: BindgenOptions,
2075     module: proc_macro2::TokenStream,
2076 }
2077 
2078 pub(crate) const HOST_TARGET: &'static str =
2079     include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
2080 
2081 // Some architecture triplets are different between rust and libclang, see #1211
2082 // and duplicates.
rust_to_clang_target(rust_target: &str) -> String2083 fn rust_to_clang_target(rust_target: &str) -> String {
2084     if rust_target.starts_with("aarch64-apple-") {
2085         let mut clang_target = "arm64-apple-".to_owned();
2086         clang_target.push_str(&rust_target["aarch64-apple-".len()..]);
2087         return clang_target;
2088     }
2089     rust_target.to_owned()
2090 }
2091 
2092 /// Returns the effective target, and whether it was explicitly specified on the
2093 /// clang flags.
find_effective_target(clang_args: &[String]) -> (String, bool)2094 fn find_effective_target(clang_args: &[String]) -> (String, bool) {
2095     let mut args = clang_args.iter();
2096     while let Some(opt) = args.next() {
2097         if opt.starts_with("--target=") {
2098             let mut split = opt.split('=');
2099             split.next();
2100             return (split.next().unwrap().to_owned(), true);
2101         }
2102 
2103         if opt == "-target" {
2104             if let Some(target) = args.next() {
2105                 return (target.clone(), true);
2106             }
2107         }
2108     }
2109 
2110     // If we're running from a build script, try to find the cargo target.
2111     if let Ok(t) = env::var("TARGET") {
2112         return (rust_to_clang_target(&t), false);
2113     }
2114 
2115     (rust_to_clang_target(HOST_TARGET), false)
2116 }
2117 
2118 impl Bindings {
2119     /// Generate bindings for the given options.
generate( mut options: BindgenOptions, ) -> Result<Bindings, ()>2120     pub(crate) fn generate(
2121         mut options: BindgenOptions,
2122     ) -> Result<Bindings, ()> {
2123         ensure_libclang_is_loaded();
2124 
2125         #[cfg(feature = "runtime")]
2126         debug!(
2127             "Generating bindings, libclang at {}",
2128             clang_sys::get_library().unwrap().path().display()
2129         );
2130         #[cfg(not(feature = "runtime"))]
2131         debug!("Generating bindings, libclang linked");
2132 
2133         options.build();
2134 
2135         let (effective_target, explicit_target) =
2136             find_effective_target(&options.clang_args);
2137 
2138         let is_host_build =
2139             rust_to_clang_target(HOST_TARGET) == effective_target;
2140 
2141         // NOTE: The is_host_build check wouldn't be sound normally in some
2142         // cases if we were to call a binary (if you have a 32-bit clang and are
2143         // building on a 64-bit system for example).  But since we rely on
2144         // opening libclang.so, it has to be the same architecture and thus the
2145         // check is fine.
2146         if !explicit_target && !is_host_build {
2147             options
2148                 .clang_args
2149                 .insert(0, format!("--target={}", effective_target));
2150         };
2151 
2152         fn detect_include_paths(options: &mut BindgenOptions) {
2153             if !options.detect_include_paths {
2154                 return;
2155             }
2156 
2157             // Filter out include paths and similar stuff, so we don't incorrectly
2158             // promote them to `-isystem`.
2159             let clang_args_for_clang_sys = {
2160                 let mut last_was_include_prefix = false;
2161                 options
2162                     .clang_args
2163                     .iter()
2164                     .filter(|arg| {
2165                         if last_was_include_prefix {
2166                             last_was_include_prefix = false;
2167                             return false;
2168                         }
2169 
2170                         let arg = &**arg;
2171 
2172                         // https://clang.llvm.org/docs/ClangCommandLineReference.html
2173                         // -isystem and -isystem-after are harmless.
2174                         if arg == "-I" || arg == "--include-directory" {
2175                             last_was_include_prefix = true;
2176                             return false;
2177                         }
2178 
2179                         if arg.starts_with("-I") ||
2180                             arg.starts_with("--include-directory=")
2181                         {
2182                             return false;
2183                         }
2184 
2185                         true
2186                     })
2187                     .cloned()
2188                     .collect::<Vec<_>>()
2189             };
2190 
2191             debug!(
2192                 "Trying to find clang with flags: {:?}",
2193                 clang_args_for_clang_sys
2194             );
2195 
2196             let clang = match clang_sys::support::Clang::find(
2197                 None,
2198                 &clang_args_for_clang_sys,
2199             ) {
2200                 None => return,
2201                 Some(clang) => clang,
2202             };
2203 
2204             debug!("Found clang: {:?}", clang);
2205 
2206             // Whether we are working with C or C++ inputs.
2207             let is_cpp = args_are_cpp(&options.clang_args) ||
2208                 options
2209                     .input_header
2210                     .as_ref()
2211                     .map_or(false, |i| file_is_cpp(&i));
2212 
2213             let search_paths = if is_cpp {
2214                 clang.cpp_search_paths
2215             } else {
2216                 clang.c_search_paths
2217             };
2218 
2219             if let Some(search_paths) = search_paths {
2220                 for path in search_paths.into_iter() {
2221                     if let Ok(path) = path.into_os_string().into_string() {
2222                         options.clang_args.push("-isystem".to_owned());
2223                         options.clang_args.push(path);
2224                     }
2225                 }
2226             }
2227         }
2228 
2229         detect_include_paths(&mut options);
2230 
2231         #[cfg(unix)]
2232         fn can_read(perms: &std::fs::Permissions) -> bool {
2233             use std::os::unix::fs::PermissionsExt;
2234             perms.mode() & 0o444 > 0
2235         }
2236 
2237         #[cfg(not(unix))]
2238         fn can_read(_: &std::fs::Permissions) -> bool {
2239             true
2240         }
2241 
2242         if let Some(h) = options.input_header.as_ref() {
2243             if let Ok(md) = std::fs::metadata(h) {
2244                 if md.is_dir() {
2245                     eprintln!("error: '{}' is a folder", h);
2246                     return Err(());
2247                 }
2248                 if !can_read(&md.permissions()) {
2249                     eprintln!(
2250                         "error: insufficient permissions to read '{}'",
2251                         h
2252                     );
2253                     return Err(());
2254                 }
2255                 options.clang_args.push(h.clone())
2256             } else {
2257                 eprintln!("error: header '{}' does not exist.", h);
2258                 return Err(());
2259             }
2260         }
2261 
2262         for (idx, f) in options.input_unsaved_files.iter().enumerate() {
2263             if idx != 0 || options.input_header.is_some() {
2264                 options.clang_args.push("-include".to_owned());
2265             }
2266             options.clang_args.push(f.name.to_str().unwrap().to_owned())
2267         }
2268 
2269         debug!("Fixed-up options: {:?}", options);
2270 
2271         let time_phases = options.time_phases;
2272         let mut context = BindgenContext::new(options);
2273 
2274         if is_host_build {
2275             debug_assert_eq!(
2276                 context.target_pointer_size(),
2277                 std::mem::size_of::<*mut ()>(),
2278                 "{:?} {:?}",
2279                 effective_target,
2280                 HOST_TARGET
2281             );
2282         }
2283 
2284         {
2285             let _t = time::Timer::new("parse").with_output(time_phases);
2286             parse(&mut context)?;
2287         }
2288 
2289         let (items, options) = codegen::codegen(context);
2290 
2291         Ok(Bindings {
2292             options,
2293             module: quote! {
2294                 #( #items )*
2295             },
2296         })
2297     }
2298 
2299     /// Convert these bindings into source text (with raw lines prepended).
to_string(&self) -> String2300     pub fn to_string(&self) -> String {
2301         let mut bytes = vec![];
2302         self.write(Box::new(&mut bytes) as Box<dyn Write>)
2303             .expect("writing to a vec cannot fail");
2304         String::from_utf8(bytes)
2305             .expect("we should only write bindings that are valid utf-8")
2306     }
2307 
2308     /// Write these bindings as source text to a file.
write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()>2309     pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
2310         let file = OpenOptions::new()
2311             .write(true)
2312             .truncate(true)
2313             .create(true)
2314             .open(path.as_ref())?;
2315         self.write(Box::new(file))?;
2316         Ok(())
2317     }
2318 
2319     /// Write these bindings as source text to the given `Write`able.
write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()>2320     pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
2321         if !self.options.disable_header_comment {
2322             let version = Some("0.58.1");
2323             let header = format!(
2324                 "/* automatically generated by rust-bindgen {} */\n\n",
2325                 version.unwrap_or("(unknown version)")
2326             );
2327             writer.write_all(header.as_bytes())?;
2328         }
2329 
2330         for line in self.options.raw_lines.iter() {
2331             writer.write_all(line.as_bytes())?;
2332             writer.write_all("\n".as_bytes())?;
2333         }
2334 
2335         if !self.options.raw_lines.is_empty() {
2336             writer.write_all("\n".as_bytes())?;
2337         }
2338 
2339         let bindings = self.module.to_string();
2340 
2341         match self.rustfmt_generated_string(&bindings) {
2342             Ok(rustfmt_bindings) => {
2343                 writer.write_all(rustfmt_bindings.as_bytes())?;
2344             }
2345             Err(err) => {
2346                 eprintln!(
2347                     "Failed to run rustfmt: {} (non-fatal, continuing)",
2348                     err
2349                 );
2350                 writer.write_all(bindings.as_bytes())?;
2351             }
2352         }
2353         Ok(())
2354     }
2355 
2356     /// Gets the rustfmt path to rustfmt the generated bindings.
rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>>2357     fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> {
2358         debug_assert!(self.options.rustfmt_bindings);
2359         if let Some(ref p) = self.options.rustfmt_path {
2360             return Ok(Cow::Borrowed(p));
2361         }
2362         if let Ok(rustfmt) = env::var("RUSTFMT") {
2363             return Ok(Cow::Owned(rustfmt.into()));
2364         }
2365         #[cfg(feature = "which-rustfmt")]
2366         match which::which("rustfmt") {
2367             Ok(p) => Ok(Cow::Owned(p)),
2368             Err(e) => {
2369                 Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
2370             }
2371         }
2372         #[cfg(not(feature = "which-rustfmt"))]
2373         // No rustfmt binary was specified, so assume that the binary is called
2374         // "rustfmt" and that it is in the user's PATH.
2375         Ok(Cow::Owned("rustfmt".into()))
2376     }
2377 
2378     /// Checks if rustfmt_bindings is set and runs rustfmt on the string
rustfmt_generated_string<'a>( &self, source: &'a str, ) -> io::Result<Cow<'a, str>>2379     fn rustfmt_generated_string<'a>(
2380         &self,
2381         source: &'a str,
2382     ) -> io::Result<Cow<'a, str>> {
2383         let _t = time::Timer::new("rustfmt_generated_string")
2384             .with_output(self.options.time_phases);
2385 
2386         if !self.options.rustfmt_bindings {
2387             return Ok(Cow::Borrowed(source));
2388         }
2389 
2390         let rustfmt = self.rustfmt_path()?;
2391         let mut cmd = Command::new(&*rustfmt);
2392 
2393         cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
2394 
2395         if let Some(path) = self
2396             .options
2397             .rustfmt_configuration_file
2398             .as_ref()
2399             .and_then(|f| f.to_str())
2400         {
2401             cmd.args(&["--config-path", path]);
2402         }
2403 
2404         let mut child = cmd.spawn()?;
2405         let mut child_stdin = child.stdin.take().unwrap();
2406         let mut child_stdout = child.stdout.take().unwrap();
2407 
2408         let source = source.to_owned();
2409 
2410         // Write to stdin in a new thread, so that we can read from stdout on this
2411         // thread. This keeps the child from blocking on writing to its stdout which
2412         // might block us from writing to its stdin.
2413         let stdin_handle = ::std::thread::spawn(move || {
2414             let _ = child_stdin.write_all(source.as_bytes());
2415             source
2416         });
2417 
2418         let mut output = vec![];
2419         io::copy(&mut child_stdout, &mut output)?;
2420 
2421         let status = child.wait()?;
2422         let source = stdin_handle.join().expect(
2423             "The thread writing to rustfmt's stdin doesn't do \
2424              anything that could panic",
2425         );
2426 
2427         match String::from_utf8(output) {
2428             Ok(bindings) => match status.code() {
2429                 Some(0) => Ok(Cow::Owned(bindings)),
2430                 Some(2) => Err(io::Error::new(
2431                     io::ErrorKind::Other,
2432                     "Rustfmt parsing errors.".to_string(),
2433                 )),
2434                 Some(3) => {
2435                     warn!("Rustfmt could not format some lines.");
2436                     Ok(Cow::Owned(bindings))
2437                 }
2438                 _ => Err(io::Error::new(
2439                     io::ErrorKind::Other,
2440                     "Internal rustfmt error".to_string(),
2441                 )),
2442             },
2443             _ => Ok(Cow::Owned(source)),
2444         }
2445     }
2446 }
2447 
2448 /// Determines whether the given cursor is in any of the files matched by the
2449 /// options.
filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool2450 fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
2451     ctx.options().builtins || !cursor.is_builtin()
2452 }
2453 
2454 /// Parse one `Item` from the Clang cursor.
parse_one( ctx: &mut BindgenContext, cursor: clang::Cursor, parent: Option<ItemId>, ) -> clang_sys::CXChildVisitResult2455 fn parse_one(
2456     ctx: &mut BindgenContext,
2457     cursor: clang::Cursor,
2458     parent: Option<ItemId>,
2459 ) -> clang_sys::CXChildVisitResult {
2460     if !filter_builtins(ctx, &cursor) {
2461         return CXChildVisit_Continue;
2462     }
2463 
2464     use clang_sys::CXChildVisit_Continue;
2465     match Item::parse(cursor, parent, ctx) {
2466         Ok(..) => {}
2467         Err(ParseError::Continue) => {}
2468         Err(ParseError::Recurse) => {
2469             cursor.visit(|child| parse_one(ctx, child, parent));
2470         }
2471     }
2472     CXChildVisit_Continue
2473 }
2474 
2475 /// Parse the Clang AST into our `Item` internal representation.
parse(context: &mut BindgenContext) -> Result<(), ()>2476 fn parse(context: &mut BindgenContext) -> Result<(), ()> {
2477     use clang_sys::*;
2478 
2479     let mut any_error = false;
2480     for d in context.translation_unit().diags().iter() {
2481         let msg = d.format();
2482         let is_err = d.severity() >= CXDiagnostic_Error;
2483         eprintln!("{}, err: {}", msg, is_err);
2484         any_error |= is_err;
2485     }
2486 
2487     if any_error {
2488         return Err(());
2489     }
2490 
2491     let cursor = context.translation_unit().cursor();
2492 
2493     if context.options().emit_ast {
2494         fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
2495             if !cur.is_builtin() {
2496                 clang::ast_dump(&cur, 0)
2497             } else {
2498                 CXChildVisit_Continue
2499             }
2500         }
2501         cursor.visit(|cur| dump_if_not_builtin(&cur));
2502     }
2503 
2504     let root = context.root_module();
2505     context.with_module(root, |context| {
2506         cursor.visit(|cursor| parse_one(context, cursor, None))
2507     });
2508 
2509     assert!(
2510         context.current_module() == context.root_module(),
2511         "How did this happen?"
2512     );
2513     Ok(())
2514 }
2515 
2516 /// Extracted Clang version data
2517 #[derive(Debug)]
2518 pub struct ClangVersion {
2519     /// Major and minor semver, if parsing was successful
2520     pub parsed: Option<(u32, u32)>,
2521     /// full version string
2522     pub full: String,
2523 }
2524 
2525 /// Get the major and the minor semver numbers of Clang's version
clang_version() -> ClangVersion2526 pub fn clang_version() -> ClangVersion {
2527     ensure_libclang_is_loaded();
2528 
2529     //Debian clang version 11.0.1-2
2530     let raw_v: String = clang::extract_clang_version();
2531     let split_v: Option<Vec<&str>> = raw_v
2532         .split_whitespace()
2533         .filter(|t| t.chars().next().map_or(false, |v| v.is_ascii_digit()))
2534         .next()
2535         .map(|v| v.split('.').collect());
2536     match split_v {
2537         Some(v) => {
2538             if v.len() >= 2 {
2539                 let maybe_major = v[0].parse::<u32>();
2540                 let maybe_minor = v[1].parse::<u32>();
2541                 match (maybe_major, maybe_minor) {
2542                     (Ok(major), Ok(minor)) => {
2543                         return ClangVersion {
2544                             parsed: Some((major, minor)),
2545                             full: raw_v.clone(),
2546                         }
2547                     }
2548                     _ => {}
2549                 }
2550             }
2551         }
2552         None => {}
2553     };
2554     ClangVersion {
2555         parsed: None,
2556         full: raw_v.clone(),
2557     }
2558 }
2559 
2560 /// A ParseCallbacks implementation that will act on file includes by echoing a rerun-if-changed
2561 /// line
2562 ///
2563 /// When running in side a `build.rs` script, this can be used to make cargo invalidate the
2564 /// generated bindings whenever any of the files included from the header change:
2565 /// ```
2566 /// use bindgen::builder;
2567 /// let bindings = builder()
2568 ///     .header("path/to/input/header")
2569 ///     .parse_callbacks(Box::new(bindgen::CargoCallbacks))
2570 ///     .generate();
2571 /// ```
2572 #[derive(Debug)]
2573 pub struct CargoCallbacks;
2574 
2575 impl callbacks::ParseCallbacks for CargoCallbacks {
include_file(&self, filename: &str)2576     fn include_file(&self, filename: &str) {
2577         println!("cargo:rerun-if-changed={}", filename);
2578     }
2579 }
2580 
2581 /// Test command_line_flag function.
2582 #[test]
commandline_flag_unit_test_function()2583 fn commandline_flag_unit_test_function() {
2584     //Test 1
2585     let bindings = crate::builder();
2586     let command_line_flags = bindings.command_line_flags();
2587 
2588     let test_cases = vec![
2589         "--rust-target",
2590         "--no-derive-default",
2591         "--generate",
2592         "functions,types,vars,methods,constructors,destructors",
2593     ]
2594     .iter()
2595     .map(|&x| x.into())
2596     .collect::<Vec<String>>();
2597 
2598     assert!(test_cases
2599         .iter()
2600         .all(|ref x| command_line_flags.contains(x),));
2601 
2602     //Test 2
2603     let bindings = crate::builder()
2604         .header("input_header")
2605         .allowlist_type("Distinct_Type")
2606         .allowlist_function("safe_function");
2607 
2608     let command_line_flags = bindings.command_line_flags();
2609     let test_cases = vec![
2610         "--rust-target",
2611         "input_header",
2612         "--no-derive-default",
2613         "--generate",
2614         "functions,types,vars,methods,constructors,destructors",
2615         "--allowlist-type",
2616         "Distinct_Type",
2617         "--allowlist-function",
2618         "safe_function",
2619     ]
2620     .iter()
2621     .map(|&x| x.into())
2622     .collect::<Vec<String>>();
2623     println!("{:?}", command_line_flags);
2624 
2625     assert!(test_cases
2626         .iter()
2627         .all(|ref x| command_line_flags.contains(x),));
2628 }
2629 
2630 #[test]
test_rust_to_clang_target()2631 fn test_rust_to_clang_target() {
2632     assert_eq!(rust_to_clang_target("aarch64-apple-ios"), "arm64-apple-ios");
2633 }
2634