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(warnings)]
12 #![deny(unused_extern_crates)]
13 // To avoid rather annoying warnings when matching with CXCursor_xxx as a
14 // constant.
15 #![allow(non_upper_case_globals)]
16 // `quote!` nests quite deeply.
17 #![recursion_limit = "128"]
18 
19 #[macro_use]
20 extern crate bitflags;
21 extern crate cexpr;
22 #[macro_use]
23 #[allow(unused_extern_crates)]
24 extern crate cfg_if;
25 extern crate clang_sys;
26 extern crate rustc_hash;
27 #[macro_use]
28 extern crate lazy_static;
29 extern crate peeking_take_while;
30 #[macro_use]
31 extern crate quote;
32 extern crate proc_macro2;
33 extern crate regex;
34 extern crate shlex;
35 #[cfg(feature = "which-rustfmt")]
36 extern crate which;
37 
38 #[cfg(feature = "logging")]
39 #[macro_use]
40 extern crate log;
41 
42 #[cfg(not(feature = "logging"))]
43 #[macro_use]
44 mod log_stubs;
45 
46 #[macro_use]
47 mod extra_assertions;
48 
49 // A macro to declare an internal module for which we *must* provide
50 // documentation for. If we are building with the "testing_only_docs" feature,
51 // then the module is declared public, and our `#![deny(missing_docs)]` pragma
52 // applies to it. This feature is used in CI, so we won't let anything slip by
53 // undocumented. Normal builds, however, will leave the module private, so that
54 // we don't expose internals to library consumers.
55 macro_rules! doc_mod {
56     ($m:ident, $doc_mod_name:ident) => {
57         cfg_if! {
58             if #[cfg(feature = "testing_only_docs")] {
59                 pub mod $doc_mod_name {
60                     //! Autogenerated documentation module.
61                     pub use super::$m::*;
62                 }
63             } else {
64             }
65         }
66     };
67 }
68 
69 mod clang;
70 mod codegen;
71 mod features;
72 mod ir;
73 mod parse;
74 mod regex_set;
75 mod time;
76 
77 pub mod callbacks;
78 
79 doc_mod!(clang, clang_docs);
80 doc_mod!(features, features_docs);
81 doc_mod!(ir, ir_docs);
82 doc_mod!(parse, parse_docs);
83 doc_mod!(regex_set, regex_set_docs);
84 
85 pub use codegen::EnumVariation;
86 use features::RustFeatures;
87 pub use features::{RustTarget, LATEST_STABLE_RUST, RUST_TARGET_STRINGS};
88 use ir::context::{BindgenContext, ItemId};
89 use ir::item::Item;
90 use parse::{ClangItemParser, ParseError};
91 use regex_set::RegexSet;
92 
93 use std::borrow::Cow;
94 use std::fs::{File, OpenOptions};
95 use std::io::{self, Write};
96 use std::path::{Path, PathBuf};
97 use std::process::{Command, Stdio};
98 use std::sync::Arc;
99 use std::{env, iter};
100 
101 // Some convenient typedefs for a fast hash map and hash set.
102 type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;
103 type HashSet<K> = ::rustc_hash::FxHashSet<K>;
104 pub(crate) use std::collections::hash_map::Entry;
105 
args_are_cpp(clang_args: &[String]) -> bool106 fn args_are_cpp(clang_args: &[String]) -> bool {
107     return clang_args
108         .windows(2)
109         .any(|w| w[0] == "-xc++" || w[1] == "-xc++" || w == &["-x", "c++"]);
110 }
111 
112 bitflags! {
113     /// A type used to indicate which kind of items we have to generate.
114     pub struct CodegenConfig: u32 {
115         /// Whether to generate functions.
116         const FUNCTIONS = 1 << 0;
117         /// Whether to generate types.
118         const TYPES = 1 << 1;
119         /// Whether to generate constants.
120         const VARS = 1 << 2;
121         /// Whether to generate methods.
122         const METHODS = 1 << 3;
123         /// Whether to generate constructors
124         const CONSTRUCTORS = 1 << 4;
125         /// Whether to generate destructors.
126         const DESTRUCTORS = 1 << 5;
127     }
128 }
129 
130 impl CodegenConfig {
131     /// Returns true if functions should be generated.
functions(self) -> bool132     pub fn functions(self) -> bool {
133         self.contains(CodegenConfig::FUNCTIONS)
134     }
135 
136     /// Returns true if types should be generated.
types(self) -> bool137     pub fn types(self) -> bool {
138         self.contains(CodegenConfig::TYPES)
139     }
140 
141     /// Returns true if constants should be generated.
vars(self) -> bool142     pub fn vars(self) -> bool {
143         self.contains(CodegenConfig::VARS)
144     }
145 
146     /// Returns true if methds should be generated.
methods(self) -> bool147     pub fn methods(self) -> bool {
148         self.contains(CodegenConfig::METHODS)
149     }
150 
151     /// Returns true if constructors should be generated.
constructors(self) -> bool152     pub fn constructors(self) -> bool {
153         self.contains(CodegenConfig::CONSTRUCTORS)
154     }
155 
156     /// Returns true if destructors should be generated.
destructors(self) -> bool157     pub fn destructors(self) -> bool {
158         self.contains(CodegenConfig::DESTRUCTORS)
159     }
160 }
161 
162 impl Default for CodegenConfig {
default() -> Self163     fn default() -> Self {
164         CodegenConfig::all()
165     }
166 }
167 
168 /// Configure and generate Rust bindings for a C/C++ header.
169 ///
170 /// This is the main entry point to the library.
171 ///
172 /// ```ignore
173 /// use bindgen::builder;
174 ///
175 /// // Configure and generate bindings.
176 /// let bindings = builder().header("path/to/input/header")
177 ///     .whitelisted_type("SomeCoolClass")
178 ///     .whitelisted_function("do_some_cool_thing")
179 ///     .generate()?;
180 ///
181 /// // Write the generated bindings to an output file.
182 /// bindings.write_to_file("path/to/output.rs")?;
183 /// ```
184 ///
185 /// # Enums
186 ///
187 /// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
188 /// the pattern passed to several methods:
189 ///
190 /// 1. [`constified_enum_module()`](#method.constified_enum_module)
191 /// 2. [`bitfield_enum()`](#method.bitfield_enum)
192 /// 3. [`rustified_enum()`](#method.rustified_enum)
193 ///
194 /// For each C enum, bindgen tries to match the pattern in the following order:
195 ///
196 /// 1. Constified enum module
197 /// 2. Bitfield enum
198 /// 3. Rustified enum
199 ///
200 /// If none of the above patterns match, then bindgen will generate a set of Rust constants.
201 #[derive(Debug, Default)]
202 pub struct Builder {
203     options: BindgenOptions,
204     input_headers: Vec<String>,
205     // Tuples of unsaved file contents of the form (name, contents).
206     input_header_contents: Vec<(String, String)>,
207 }
208 
209 /// Construct a new [`Builder`](./struct.Builder.html).
builder() -> Builder210 pub fn builder() -> Builder {
211     Default::default()
212 }
213 
214 impl Builder {
215     /// Generates the command line flags use for creating `Builder`.
command_line_flags(&self) -> Vec<String>216     pub fn command_line_flags(&self) -> Vec<String> {
217         let mut output_vector: Vec<String> = Vec::new();
218 
219         if let Some(header) = self.input_headers.last().cloned() {
220             // Positional argument 'header'
221             output_vector.push(header);
222         }
223 
224         output_vector.push("--rust-target".into());
225         output_vector.push(self.options.rust_target.into());
226 
227         if self.options.default_enum_style != Default::default() {
228             output_vector.push("--default-enum-style=".into());
229             output_vector.push(
230                 match self.options.default_enum_style {
231                     codegen::EnumVariation::Rust {
232                         non_exhaustive: false,
233                     } => "rust",
234                     codegen::EnumVariation::Rust {
235                         non_exhaustive: true,
236                     } => "rust_non_exhaustive",
237                     codegen::EnumVariation::Bitfield => "bitfield",
238                     codegen::EnumVariation::Consts => "consts",
239                     codegen::EnumVariation::ModuleConsts => "moduleconsts",
240                 }
241                 .into(),
242             )
243         }
244 
245         self.options
246             .bitfield_enums
247             .get_items()
248             .iter()
249             .map(|item| {
250                 output_vector.push("--bitfield-enum".into());
251                 output_vector.push(item.to_owned());
252             })
253             .count();
254 
255         self.options
256             .rustified_enums
257             .get_items()
258             .iter()
259             .map(|item| {
260                 output_vector.push("--rustified-enum".into());
261                 output_vector.push(item.to_owned());
262             })
263             .count();
264 
265         self.options
266             .rustified_non_exhaustive_enums
267             .get_items()
268             .iter()
269             .map(|item| {
270                 output_vector.push("--rustified-enum-non-exhaustive".into());
271                 output_vector.push(item.to_owned());
272             })
273             .count();
274 
275         self.options
276             .constified_enum_modules
277             .get_items()
278             .iter()
279             .map(|item| {
280                 output_vector.push("--constified-enum-module".into());
281                 output_vector.push(item.to_owned());
282             })
283             .count();
284 
285         self.options
286             .constified_enums
287             .get_items()
288             .iter()
289             .map(|item| {
290                 output_vector.push("--constified-enum".into());
291                 output_vector.push(item.to_owned());
292             })
293             .count();
294 
295         self.options
296             .blacklisted_types
297             .get_items()
298             .iter()
299             .map(|item| {
300                 output_vector.push("--blacklist-type".into());
301                 output_vector.push(item.to_owned());
302             })
303             .count();
304 
305         self.options
306             .blacklisted_functions
307             .get_items()
308             .iter()
309             .map(|item| {
310                 output_vector.push("--blacklist-function".into());
311                 output_vector.push(item.to_owned());
312             })
313             .count();
314 
315         self.options
316             .blacklisted_items
317             .get_items()
318             .iter()
319             .map(|item| {
320                 output_vector.push("--blacklist-item".into());
321                 output_vector.push(item.to_owned());
322             })
323             .count();
324 
325         if !self.options.layout_tests {
326             output_vector.push("--no-layout-tests".into());
327         }
328 
329         if self.options.impl_debug {
330             output_vector.push("--impl-debug".into());
331         }
332 
333         if self.options.impl_partialeq {
334             output_vector.push("--impl-partialeq".into());
335         }
336 
337         if !self.options.derive_copy {
338             output_vector.push("--no-derive-copy".into());
339         }
340 
341         if !self.options.derive_debug {
342             output_vector.push("--no-derive-debug".into());
343         }
344 
345         if !self.options.derive_default {
346             output_vector.push("--no-derive-default".into());
347         } else {
348             output_vector.push("--with-derive-default".into());
349         }
350 
351         if self.options.derive_hash {
352             output_vector.push("--with-derive-hash".into());
353         }
354 
355         if self.options.derive_partialord {
356             output_vector.push("--with-derive-partialord".into());
357         }
358 
359         if self.options.derive_ord {
360             output_vector.push("--with-derive-ord".into());
361         }
362 
363         if self.options.derive_partialeq {
364             output_vector.push("--with-derive-partialeq".into());
365         }
366 
367         if self.options.derive_eq {
368             output_vector.push("--with-derive-eq".into());
369         }
370 
371         if self.options.time_phases {
372             output_vector.push("--time-phases".into());
373         }
374 
375         if !self.options.generate_comments {
376             output_vector.push("--no-doc-comments".into());
377         }
378 
379         if !self.options.whitelist_recursively {
380             output_vector.push("--no-recursive-whitelist".into());
381         }
382 
383         if self.options.objc_extern_crate {
384             output_vector.push("--objc-extern-crate".into());
385         }
386 
387         if self.options.generate_block {
388             output_vector.push("--generate-block".into());
389         }
390 
391         if self.options.block_extern_crate {
392             output_vector.push("--block-extern-crate".into());
393         }
394 
395         if self.options.builtins {
396             output_vector.push("--builtins".into());
397         }
398 
399         if let Some(ref prefix) = self.options.ctypes_prefix {
400             output_vector.push("--ctypes-prefix".into());
401             output_vector.push(prefix.clone());
402         }
403 
404         if self.options.emit_ast {
405             output_vector.push("--emit-clang-ast".into());
406         }
407 
408         if self.options.emit_ir {
409             output_vector.push("--emit-ir".into());
410         }
411         if let Some(ref graph) = self.options.emit_ir_graphviz {
412             output_vector.push("--emit-ir-graphviz".into());
413             output_vector.push(graph.clone())
414         }
415         if self.options.enable_cxx_namespaces {
416             output_vector.push("--enable-cxx-namespaces".into());
417         }
418         if self.options.enable_function_attribute_detection {
419             output_vector.push("--enable-function-attribute-detection".into());
420         }
421         if self.options.disable_name_namespacing {
422             output_vector.push("--disable-name-namespacing".into());
423         }
424 
425         if !self.options.codegen_config.functions() {
426             output_vector.push("--ignore-functions".into());
427         }
428 
429         output_vector.push("--generate".into());
430 
431         //Temporary placeholder for below 4 options
432         let mut options: Vec<String> = Vec::new();
433         if self.options.codegen_config.functions() {
434             options.push("functions".into());
435         }
436         if self.options.codegen_config.types() {
437             options.push("types".into());
438         }
439         if self.options.codegen_config.vars() {
440             options.push("vars".into());
441         }
442         if self.options.codegen_config.methods() {
443             options.push("methods".into());
444         }
445         if self.options.codegen_config.constructors() {
446             options.push("constructors".into());
447         }
448         if self.options.codegen_config.destructors() {
449             options.push("destructors".into());
450         }
451 
452         output_vector.push(options.join(","));
453 
454         if !self.options.codegen_config.methods() {
455             output_vector.push("--ignore-methods".into());
456         }
457 
458         if !self.options.convert_floats {
459             output_vector.push("--no-convert-floats".into());
460         }
461 
462         if !self.options.prepend_enum_name {
463             output_vector.push("--no-prepend-enum-name".into());
464         }
465 
466         if self.options.array_pointers_in_arguments {
467             output_vector.push("--use-array-pointers-in-arguments".into());
468         }
469 
470         self.options
471             .opaque_types
472             .get_items()
473             .iter()
474             .map(|item| {
475                 output_vector.push("--opaque-type".into());
476                 output_vector.push(item.to_owned());
477             })
478             .count();
479 
480         self.options
481             .raw_lines
482             .iter()
483             .map(|item| {
484                 output_vector.push("--raw-line".into());
485                 output_vector.push(item.to_owned());
486             })
487             .count();
488 
489         if self.options.use_core {
490             output_vector.push("--use-core".into());
491         }
492 
493         if self.options.conservative_inline_namespaces {
494             output_vector.push("--conservative-inline-namespaces".into());
495         }
496 
497         self.options
498             .whitelisted_functions
499             .get_items()
500             .iter()
501             .map(|item| {
502                 output_vector.push("--whitelist-function".into());
503                 output_vector.push(item.to_owned());
504             })
505             .count();
506 
507         self.options
508             .whitelisted_types
509             .get_items()
510             .iter()
511             .map(|item| {
512                 output_vector.push("--whitelist-type".into());
513                 output_vector.push(item.to_owned());
514             })
515             .count();
516 
517         self.options
518             .whitelisted_vars
519             .get_items()
520             .iter()
521             .map(|item| {
522                 output_vector.push("--whitelist-var".into());
523                 output_vector.push(item.to_owned());
524             })
525             .count();
526 
527         output_vector.push("--".into());
528 
529         if !self.options.clang_args.is_empty() {
530             output_vector.extend(self.options.clang_args.iter().cloned());
531         }
532 
533         if self.input_headers.len() > 1 {
534             output_vector.extend(
535                 self.input_headers[..self.input_headers.len() - 1]
536                     .iter()
537                     .cloned(),
538             );
539         }
540 
541         if !self.options.record_matches {
542             output_vector.push("--no-record-matches".into());
543         }
544 
545         if !self.options.rustfmt_bindings {
546             output_vector.push("--no-rustfmt-bindings".into());
547         }
548 
549         if let Some(path) = self
550             .options
551             .rustfmt_configuration_file
552             .as_ref()
553             .and_then(|f| f.to_str())
554         {
555             output_vector.push("--rustfmt-configuration-file".into());
556             output_vector.push(path.into());
557         }
558 
559         self.options
560             .no_partialeq_types
561             .get_items()
562             .iter()
563             .map(|item| {
564                 output_vector.push("--no-partialeq".into());
565                 output_vector.push(item.to_owned());
566             })
567             .count();
568 
569         self.options
570             .no_copy_types
571             .get_items()
572             .iter()
573             .map(|item| {
574                 output_vector.push("--no-copy".into());
575                 output_vector.push(item.to_owned());
576             })
577             .count();
578 
579         self.options
580             .no_hash_types
581             .get_items()
582             .iter()
583             .map(|item| {
584                 output_vector.push("--no-hash".into());
585                 output_vector.push(item.to_owned());
586             })
587             .count();
588 
589         output_vector
590     }
591 
592     /// Add an input C/C++ header to generate bindings for.
593     ///
594     /// This can be used to generate bindings to a single header:
595     ///
596     /// ```ignore
597     /// let bindings = bindgen::Builder::default()
598     ///     .header("input.h")
599     ///     .generate()
600     ///     .unwrap();
601     /// ```
602     ///
603     /// Or you can invoke it multiple times to generate bindings to multiple
604     /// headers:
605     ///
606     /// ```ignore
607     /// let bindings = bindgen::Builder::default()
608     ///     .header("first.h")
609     ///     .header("second.h")
610     ///     .header("third.h")
611     ///     .generate()
612     ///     .unwrap();
613     /// ```
header<T: Into<String>>(mut self, header: T) -> Builder614     pub fn header<T: Into<String>>(mut self, header: T) -> Builder {
615         self.input_headers.push(header.into());
616         self
617     }
618 
619     /// Add `contents` as an input C/C++ header named `name`.
620     ///
621     /// The file `name` will be added to the clang arguments.
header_contents(mut self, name: &str, contents: &str) -> Builder622     pub fn header_contents(mut self, name: &str, contents: &str) -> Builder {
623         self.input_header_contents
624             .push((name.into(), contents.into()));
625         self
626     }
627 
628     /// Specify the rust target
629     ///
630     /// The default is the latest stable Rust version
rust_target(mut self, rust_target: RustTarget) -> Self631     pub fn rust_target(mut self, rust_target: RustTarget) -> Self {
632         self.options.set_rust_target(rust_target);
633         self
634     }
635 
636     /// Disable support for native Rust unions, if supported.
disable_untagged_union(mut self) -> Self637     pub fn disable_untagged_union(mut self) -> Self {
638         self.options.rust_features.untagged_union = false;
639         self
640     }
641 
642     /// Set the output graphviz file.
emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder643     pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
644         let path = path.into();
645         self.options.emit_ir_graphviz = Some(path);
646         self
647     }
648 
649     /// Whether the generated bindings should contain documentation comments or
650     /// not.
651     ///
652     /// This ideally will always be true, but it may need to be false until we
653     /// implement some processing on comments to work around issues as described
654     /// in:
655     ///
656     /// https://github.com/rust-lang/rust-bindgen/issues/426
generate_comments(mut self, doit: bool) -> Self657     pub fn generate_comments(mut self, doit: bool) -> Self {
658         self.options.generate_comments = doit;
659         self
660     }
661 
662     /// Whether to whitelist recursively or not. Defaults to true.
663     ///
664     /// Given that we have explicitly whitelisted the "initiate_dance_party"
665     /// function in this C header:
666     ///
667     /// ```c
668     /// typedef struct MoonBoots {
669     ///     int bouncy_level;
670     /// } MoonBoots;
671     ///
672     /// void initiate_dance_party(MoonBoots* boots);
673     /// ```
674     ///
675     /// We would normally generate bindings to both the `initiate_dance_party`
676     /// function and the `MoonBoots` struct that it transitively references. By
677     /// configuring with `whitelist_recursively(false)`, `bindgen` will not emit
678     /// bindings for anything except the explicitly whitelisted items, and there
679     /// would be no emitted struct definition for `MoonBoots`. However, the
680     /// `initiate_dance_party` function would still reference `MoonBoots`!
681     ///
682     /// **Disabling this feature will almost certainly cause `bindgen` to emit
683     /// bindings that will not compile!** If you disable this feature, then it
684     /// is *your* responsibility to provide definitions for every type that is
685     /// referenced from an explicitly whitelisted item. One way to provide the
686     /// definitions is by using the [`Builder::raw_line`](#method.raw_line)
687     /// method, another would be to define them in Rust and then `include!(...)`
688     /// the bindings immediately afterwards.
whitelist_recursively(mut self, doit: bool) -> Self689     pub fn whitelist_recursively(mut self, doit: bool) -> Self {
690         self.options.whitelist_recursively = doit;
691         self
692     }
693 
694     /// Generate `#[macro_use] extern crate objc;` instead of `use objc;`
695     /// in the prologue of the files generated from objective-c files
objc_extern_crate(mut self, doit: bool) -> Self696     pub fn objc_extern_crate(mut self, doit: bool) -> Self {
697         self.options.objc_extern_crate = doit;
698         self
699     }
700 
701     /// Generate proper block signatures instead of void pointers.
generate_block(mut self, doit: bool) -> Self702     pub fn generate_block(mut self, doit: bool) -> Self {
703         self.options.generate_block = doit;
704         self
705     }
706 
707     /// Generate `#[macro_use] extern crate block;` instead of `use block;`
708     /// in the prologue of the files generated from apple block files
block_extern_crate(mut self, doit: bool) -> Self709     pub fn block_extern_crate(mut self, doit: bool) -> Self {
710         self.options.block_extern_crate = doit;
711         self
712     }
713 
714     /// Whether to use the clang-provided name mangling. This is true by default
715     /// and probably needed for C++ features.
716     ///
717     /// However, some old libclang versions seem to return incorrect results in
718     /// some cases for non-mangled functions, see [1], so we allow disabling it.
719     ///
720     /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
trust_clang_mangling(mut self, doit: bool) -> Self721     pub fn trust_clang_mangling(mut self, doit: bool) -> Self {
722         self.options.enable_mangling = doit;
723         self
724     }
725 
726     /// Hide the given type from the generated bindings. Regular expressions are
727     /// supported.
728     #[deprecated(note = "Use blacklist_type instead")]
hide_type<T: AsRef<str>>(self, arg: T) -> Builder729     pub fn hide_type<T: AsRef<str>>(self, arg: T) -> Builder {
730         self.blacklist_type(arg)
731     }
732 
733     /// Hide the given type from the generated bindings. Regular expressions are
734     /// supported.
blacklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder735     pub fn blacklist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
736         self.options.blacklisted_types.insert(arg);
737         self
738     }
739 
740     /// Hide the given function from the generated bindings. Regular expressions
741     /// are supported.
blacklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder742     pub fn blacklist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
743         self.options.blacklisted_functions.insert(arg);
744         self
745     }
746 
747     /// Hide the given item from the generated bindings, regardless of
748     /// whether it's a type, function, module, etc. Regular
749     /// expressions are supported.
blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder750     pub fn blacklist_item<T: AsRef<str>>(mut self, arg: T) -> Builder {
751         self.options.blacklisted_items.insert(arg);
752         self
753     }
754 
755     /// Treat the given type as opaque in the generated bindings. Regular
756     /// expressions are supported.
opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder757     pub fn opaque_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
758         self.options.opaque_types.insert(arg);
759         self
760     }
761 
762     /// Whitelist the given type so that it (and all types that it transitively
763     /// refers to) appears in the generated bindings. Regular expressions are
764     /// supported.
765     #[deprecated(note = "use whitelist_type instead")]
whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder766     pub fn whitelisted_type<T: AsRef<str>>(self, arg: T) -> Builder {
767         self.whitelist_type(arg)
768     }
769 
770     /// Whitelist the given type so that it (and all types that it transitively
771     /// refers to) appears in the generated bindings. Regular expressions are
772     /// supported.
whitelist_type<T: AsRef<str>>(mut self, arg: T) -> Builder773     pub fn whitelist_type<T: AsRef<str>>(mut self, arg: T) -> Builder {
774         self.options.whitelisted_types.insert(arg);
775         self
776     }
777 
778     /// Whitelist the given function so that it (and all types that it
779     /// transitively refers to) appears in the generated bindings. Regular
780     /// expressions are supported.
whitelist_function<T: AsRef<str>>(mut self, arg: T) -> Builder781     pub fn whitelist_function<T: AsRef<str>>(mut self, arg: T) -> Builder {
782         self.options.whitelisted_functions.insert(arg);
783         self
784     }
785 
786     /// Whitelist the given function.
787     ///
788     /// Deprecated: use whitelist_function instead.
789     #[deprecated(note = "use whitelist_function instead")]
whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder790     pub fn whitelisted_function<T: AsRef<str>>(self, arg: T) -> Builder {
791         self.whitelist_function(arg)
792     }
793 
794     /// Whitelist the given variable so that it (and all types that it
795     /// transitively refers to) appears in the generated bindings. Regular
796     /// expressions are supported.
whitelist_var<T: AsRef<str>>(mut self, arg: T) -> Builder797     pub fn whitelist_var<T: AsRef<str>>(mut self, arg: T) -> Builder {
798         self.options.whitelisted_vars.insert(arg);
799         self
800     }
801 
802     /// Whitelist the given variable.
803     ///
804     /// Deprecated: use whitelist_var instead.
805     #[deprecated(note = "use whitelist_var instead")]
whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder806     pub fn whitelisted_var<T: AsRef<str>>(self, arg: T) -> Builder {
807         self.whitelist_var(arg)
808     }
809 
810     /// Set the default style of code to generate for enums
default_enum_style( mut self, arg: codegen::EnumVariation, ) -> Builder811     pub fn default_enum_style(
812         mut self,
813         arg: codegen::EnumVariation,
814     ) -> Builder {
815         self.options.default_enum_style = arg;
816         self
817     }
818 
819     /// Mark the given enum (or set of enums, if using a pattern) as being
820     /// bitfield-like. Regular expressions are supported.
821     ///
822     /// This makes bindgen generate a type that isn't a rust `enum`. Regular
823     /// expressions are supported.
bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder824     pub fn bitfield_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
825         self.options.bitfield_enums.insert(arg);
826         self
827     }
828 
829     /// Mark the given enum (or set of enums, if using a pattern) as a Rust
830     /// enum.
831     ///
832     /// This makes bindgen generate enums instead of constants. Regular
833     /// expressions are supported.
834     ///
835     /// **Use this with caution,** you probably want to use the non_exhaustive
836     /// flavor of rust enums instead of this one. Take a look at
837     /// https://github.com/rust-lang/rust/issues/36927 for more information.
rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder838     pub fn rustified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
839         self.options.rustified_enums.insert(arg);
840         self
841     }
842 
843     /// Mark the given enum (or set of enums, if using a pattern) as a Rust
844     /// enum with the #[non_exhaustive] attribute.
845     ///
846     /// This makes bindgen generate enums instead of constants. Regular
847     /// expressions are supported.
rustified_non_exhaustive_enum<T: AsRef<str>>( mut self, arg: T, ) -> Builder848     pub fn rustified_non_exhaustive_enum<T: AsRef<str>>(
849         mut self,
850         arg: T,
851     ) -> Builder {
852         self.options.rustified_non_exhaustive_enums.insert(arg);
853         self
854     }
855 
856     /// Mark the given enum (or set of enums, if using a pattern) as a set of
857     /// constants that are not to be put into a module.
constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder858     pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
859         self.options.constified_enums.insert(arg);
860         self
861     }
862 
863     /// Mark the given enum (or set of enums, if using a pattern) as a set of
864     /// constants that should be put into a module.
865     ///
866     /// This makes bindgen generate modules containing constants instead of
867     /// just constants. Regular expressions are supported.
constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder868     pub fn constified_enum_module<T: AsRef<str>>(mut self, arg: T) -> Builder {
869         self.options.constified_enum_modules.insert(arg);
870         self
871     }
872 
873     /// Add a string to prepend to the generated bindings. The string is passed
874     /// through without any modification.
raw_line<T: Into<String>>(mut self, arg: T) -> Self875     pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
876         self.options.raw_lines.push(arg.into());
877         self
878     }
879 
880     /// 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>,881     pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
882     where
883         T: Into<String>,
884         U: Into<String>,
885     {
886         self.options
887             .module_lines
888             .entry(mod_.into())
889             .or_insert_with(Vec::new)
890             .push(line.into());
891         self
892     }
893 
894     /// 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>,895     pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
896     where
897         T: Into<String>,
898         I: IntoIterator,
899         I::Item: Into<String>,
900     {
901         self.options
902             .module_lines
903             .entry(mod_.into())
904             .or_insert_with(Vec::new)
905             .extend(lines.into_iter().map(Into::into));
906         self
907     }
908 
909     /// Add an argument to be passed straight through to clang.
clang_arg<T: Into<String>>(mut self, arg: T) -> Builder910     pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
911         self.options.clang_args.push(arg.into());
912         self
913     }
914 
915     /// Add arguments to be passed straight through to clang.
clang_args<I>(mut self, iter: I) -> Builder where I: IntoIterator, I::Item: AsRef<str>,916     pub fn clang_args<I>(mut self, iter: I) -> Builder
917     where
918         I: IntoIterator,
919         I::Item: AsRef<str>,
920     {
921         for arg in iter {
922             self = self.clang_arg(arg.as_ref())
923         }
924         self
925     }
926 
927     /// Emit bindings for builtin definitions (for example `__builtin_va_list`)
928     /// in the generated Rust.
emit_builtins(mut self) -> Builder929     pub fn emit_builtins(mut self) -> Builder {
930         self.options.builtins = true;
931         self
932     }
933 
934     /// Avoid converting floats to `f32`/`f64` by default.
no_convert_floats(mut self) -> Self935     pub fn no_convert_floats(mut self) -> Self {
936         self.options.convert_floats = false;
937         self
938     }
939 
940     /// Set whether layout tests should be generated.
layout_tests(mut self, doit: bool) -> Self941     pub fn layout_tests(mut self, doit: bool) -> Self {
942         self.options.layout_tests = doit;
943         self
944     }
945 
946     /// Set whether `Debug` should be implemented, if it can not be derived automatically.
impl_debug(mut self, doit: bool) -> Self947     pub fn impl_debug(mut self, doit: bool) -> Self {
948         self.options.impl_debug = doit;
949         self
950     }
951 
952     /// Set whether `PartialEq` should be implemented, if it can not be derived automatically.
impl_partialeq(mut self, doit: bool) -> Self953     pub fn impl_partialeq(mut self, doit: bool) -> Self {
954         self.options.impl_partialeq = doit;
955         self
956     }
957 
958     /// Set whether `Copy` should be derived by default.
derive_copy(mut self, doit: bool) -> Self959     pub fn derive_copy(mut self, doit: bool) -> Self {
960         self.options.derive_copy = doit;
961         self
962     }
963 
964     /// Set whether `Debug` should be derived by default.
derive_debug(mut self, doit: bool) -> Self965     pub fn derive_debug(mut self, doit: bool) -> Self {
966         self.options.derive_debug = doit;
967         self
968     }
969 
970     /// Set whether `Default` should be derived by default.
derive_default(mut self, doit: bool) -> Self971     pub fn derive_default(mut self, doit: bool) -> Self {
972         self.options.derive_default = doit;
973         self
974     }
975 
976     /// Set whether `Hash` should be derived by default.
derive_hash(mut self, doit: bool) -> Self977     pub fn derive_hash(mut self, doit: bool) -> Self {
978         self.options.derive_hash = doit;
979         self
980     }
981 
982     /// Set whether `PartialOrd` should be derived by default.
983     /// If we don't compute partialord, we also cannot compute
984     /// ord. Set the derive_ord to `false` when doit is `false`.
derive_partialord(mut self, doit: bool) -> Self985     pub fn derive_partialord(mut self, doit: bool) -> Self {
986         self.options.derive_partialord = doit;
987         if !doit {
988             self.options.derive_ord = false;
989         }
990         self
991     }
992 
993     /// Set whether `Ord` should be derived by default.
994     /// We can't compute `Ord` without computing `PartialOrd`,
995     /// so we set the same option to derive_partialord.
derive_ord(mut self, doit: bool) -> Self996     pub fn derive_ord(mut self, doit: bool) -> Self {
997         self.options.derive_ord = doit;
998         self.options.derive_partialord = doit;
999         self
1000     }
1001 
1002     /// Set whether `PartialEq` should be derived by default.
1003     ///
1004     /// If we don't derive `PartialEq`, we also cannot derive `Eq`, so deriving
1005     /// `Eq` is also disabled when `doit` is `false`.
derive_partialeq(mut self, doit: bool) -> Self1006     pub fn derive_partialeq(mut self, doit: bool) -> Self {
1007         self.options.derive_partialeq = doit;
1008         if !doit {
1009             self.options.derive_eq = false;
1010         }
1011         self
1012     }
1013 
1014     /// Set whether `Eq` should be derived by default.
1015     ///
1016     /// We can't derive `Eq` without also deriving `PartialEq`, so we also
1017     /// enable deriving `PartialEq` when `doit` is `true`.
derive_eq(mut self, doit: bool) -> Self1018     pub fn derive_eq(mut self, doit: bool) -> Self {
1019         self.options.derive_eq = doit;
1020         if doit {
1021             self.options.derive_partialeq = doit;
1022         }
1023         self
1024     }
1025 
1026     /// Set whether or not to time bindgen phases, and print information to
1027     /// stderr.
time_phases(mut self, doit: bool) -> Self1028     pub fn time_phases(mut self, doit: bool) -> Self {
1029         self.options.time_phases = doit;
1030         self
1031     }
1032 
1033     /// Emit Clang AST.
emit_clang_ast(mut self) -> Builder1034     pub fn emit_clang_ast(mut self) -> Builder {
1035         self.options.emit_ast = true;
1036         self
1037     }
1038 
1039     /// Emit IR.
emit_ir(mut self) -> Builder1040     pub fn emit_ir(mut self) -> Builder {
1041         self.options.emit_ir = true;
1042         self
1043     }
1044 
1045     /// Enable C++ namespaces.
enable_cxx_namespaces(mut self) -> Builder1046     pub fn enable_cxx_namespaces(mut self) -> Builder {
1047         self.options.enable_cxx_namespaces = true;
1048         self
1049     }
1050 
1051     /// Enable detecting must_use attributes on C functions.
1052     ///
1053     /// This is quite slow in some cases (see #1465), so it's disabled by
1054     /// default.
1055     ///
1056     /// Note that for this to do something meaningful for now at least, the rust
1057     /// target version has to have support for `#[must_use]`.
enable_function_attribute_detection(mut self) -> Self1058     pub fn enable_function_attribute_detection(mut self) -> Self {
1059         self.options.enable_function_attribute_detection = true;
1060         self
1061     }
1062 
1063     /// Disable name auto-namespacing.
1064     ///
1065     /// By default, bindgen mangles names like `foo::bar::Baz` to look like
1066     /// `foo_bar_Baz` instead of just `Baz`.
1067     ///
1068     /// This method disables that behavior.
1069     ///
1070     /// Note that this intentionally does not change the names used for
1071     /// whitelisting and blacklisting, which should still be mangled with the
1072     /// namespaces.
1073     ///
1074     /// Note, also, that this option may cause bindgen to generate duplicate
1075     /// names.
disable_name_namespacing(mut self) -> Builder1076     pub fn disable_name_namespacing(mut self) -> Builder {
1077         self.options.disable_name_namespacing = true;
1078         self
1079     }
1080 
1081     /// Treat inline namespaces conservatively.
1082     ///
1083     /// This is tricky, because in C++ is technically legal to override an item
1084     /// defined in an inline namespace:
1085     ///
1086     /// ```cpp
1087     /// inline namespace foo {
1088     ///     using Bar = int;
1089     /// }
1090     /// using Bar = long;
1091     /// ```
1092     ///
1093     /// Even though referencing `Bar` is a compiler error.
1094     ///
1095     /// We want to support this (arguably esoteric) use case, but we don't want
1096     /// to make the rest of bindgen users pay an usability penalty for that.
1097     ///
1098     /// To support this, we need to keep all the inline namespaces around, but
1099     /// then bindgen usage is a bit more difficult, because you cannot
1100     /// reference, e.g., `std::string` (you'd need to use the proper inline
1101     /// namespace).
1102     ///
1103     /// We could complicate a lot of the logic to detect name collisions, and if
1104     /// not detected generate a `pub use inline_ns::*` or something like that.
1105     ///
1106     /// That's probably something we can do if we see this option is needed in a
1107     /// lot of cases, to improve it's usability, but my guess is that this is
1108     /// not going to be too useful.
conservative_inline_namespaces(mut self) -> Builder1109     pub fn conservative_inline_namespaces(mut self) -> Builder {
1110         self.options.conservative_inline_namespaces = true;
1111         self
1112     }
1113 
1114     /// Whether inline functions should be generated or not.
1115     ///
1116     /// Note that they will usually not work. However you can use
1117     /// `-fkeep-inline-functions` or `-fno-inline-functions` if you are
1118     /// responsible of compiling the library to make them callable.
generate_inline_functions(mut self, doit: bool) -> Self1119     pub fn generate_inline_functions(mut self, doit: bool) -> Self {
1120         self.options.generate_inline_functions = doit;
1121         self
1122     }
1123 
1124     /// Ignore functions.
ignore_functions(mut self) -> Builder1125     pub fn ignore_functions(mut self) -> Builder {
1126         self.options.codegen_config.remove(CodegenConfig::FUNCTIONS);
1127         self
1128     }
1129 
1130     /// Ignore methods.
ignore_methods(mut self) -> Builder1131     pub fn ignore_methods(mut self) -> Builder {
1132         self.options.codegen_config.remove(CodegenConfig::METHODS);
1133         self
1134     }
1135 
1136     /// Avoid generating any unstable Rust, such as Rust unions, in the generated bindings.
1137     #[deprecated(note = "please use `rust_target` instead")]
unstable_rust(self, doit: bool) -> Self1138     pub fn unstable_rust(self, doit: bool) -> Self {
1139         let rust_target = if doit {
1140             RustTarget::Nightly
1141         } else {
1142             LATEST_STABLE_RUST
1143         };
1144         self.rust_target(rust_target)
1145     }
1146 
1147     /// Use core instead of libstd in the generated bindings.
use_core(mut self) -> Builder1148     pub fn use_core(mut self) -> Builder {
1149         self.options.use_core = true;
1150         self
1151     }
1152 
1153     /// Use the given prefix for the raw types instead of `::std::os::raw`.
ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder1154     pub fn ctypes_prefix<T: Into<String>>(mut self, prefix: T) -> Builder {
1155         self.options.ctypes_prefix = Some(prefix.into());
1156         self
1157     }
1158 
1159     /// Allows configuring types in different situations, see the
1160     /// [`ParseCallbacks`](./callbacks/trait.ParseCallbacks.html) documentation.
parse_callbacks( mut self, cb: Box<dyn callbacks::ParseCallbacks>, ) -> Self1161     pub fn parse_callbacks(
1162         mut self,
1163         cb: Box<dyn callbacks::ParseCallbacks>,
1164     ) -> Self {
1165         self.options.parse_callbacks = Some(cb);
1166         self
1167     }
1168 
1169     /// Choose what to generate using a
1170     /// [`CodegenConfig`](./struct.CodegenConfig.html).
with_codegen_config(mut self, config: CodegenConfig) -> Self1171     pub fn with_codegen_config(mut self, config: CodegenConfig) -> Self {
1172         self.options.codegen_config = config;
1173         self
1174     }
1175 
1176     /// Whether to detect include paths using clang_sys.
detect_include_paths(mut self, doit: bool) -> Self1177     pub fn detect_include_paths(mut self, doit: bool) -> Self {
1178         self.options.detect_include_paths = doit;
1179         self
1180     }
1181 
1182     /// Prepend the enum name to constant or bitfield variants.
prepend_enum_name(mut self, doit: bool) -> Self1183     pub fn prepend_enum_name(mut self, doit: bool) -> Self {
1184         self.options.prepend_enum_name = doit;
1185         self
1186     }
1187 
1188     /// Set whether rustfmt should format the generated bindings.
rustfmt_bindings(mut self, doit: bool) -> Self1189     pub fn rustfmt_bindings(mut self, doit: bool) -> Self {
1190         self.options.rustfmt_bindings = doit;
1191         self
1192     }
1193 
1194     /// Set whether we should record matched items in our regex sets.
record_matches(mut self, doit: bool) -> Self1195     pub fn record_matches(mut self, doit: bool) -> Self {
1196         self.options.record_matches = doit;
1197         self
1198     }
1199 
1200     /// Set the absolute path to the rustfmt configuration file, if None, the standard rustfmt
1201     /// options are used.
rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self1202     pub fn rustfmt_configuration_file(mut self, path: Option<PathBuf>) -> Self {
1203         self = self.rustfmt_bindings(true);
1204         self.options.rustfmt_configuration_file = path;
1205         self
1206     }
1207 
1208     /// Sets an explicit path to rustfmt, to be used when rustfmt is enabled.
with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self1209     pub fn with_rustfmt<P: Into<PathBuf>>(mut self, path: P) -> Self {
1210         self.options.rustfmt_path = Some(path.into());
1211         self
1212     }
1213 
1214     /// Generate the Rust bindings using the options built up thus far.
generate(mut self) -> Result<Bindings, ()>1215     pub fn generate(mut self) -> Result<Bindings, ()> {
1216         // Add any extra arguments from the environment to the clang command line.
1217         if let Some(extra_clang_args) =
1218             env::var("BINDGEN_EXTRA_CLANG_ARGS").ok()
1219         {
1220             // Try to parse it with shell quoting. If we fail, make it one single big argument.
1221             if let Some(strings) = shlex::split(&extra_clang_args) {
1222                 self.options.clang_args.extend(strings);
1223             } else {
1224                 self.options.clang_args.push(extra_clang_args);
1225             };
1226         }
1227 
1228         // Transform input headers to arguments on the clang command line.
1229         self.options.input_header = self.input_headers.pop();
1230         self.options
1231             .clang_args
1232             .extend(self.input_headers.drain(..).flat_map(|header| {
1233                 iter::once("-include".into()).chain(iter::once(header))
1234             }));
1235 
1236         self.options.input_unsaved_files.extend(
1237             self.input_header_contents
1238                 .drain(..)
1239                 .map(|(name, contents)| {
1240                     clang::UnsavedFile::new(&name, &contents)
1241                 }),
1242         );
1243 
1244         Bindings::generate(self.options)
1245     }
1246 
1247     /// Preprocess and dump the input header files to disk.
1248     ///
1249     /// This is useful when debugging bindgen, using C-Reduce, or when filing
1250     /// issues. The resulting file will be named something like `__bindgen.i` or
1251     /// `__bindgen.ii`
dump_preprocessed_input(&self) -> io::Result<()>1252     pub fn dump_preprocessed_input(&self) -> io::Result<()> {
1253         fn check_is_cpp(name_file: &str) -> bool {
1254             name_file.ends_with(".hpp") ||
1255                 name_file.ends_with(".hxx") ||
1256                 name_file.ends_with(".hh") ||
1257                 name_file.ends_with(".h++")
1258         }
1259 
1260         let clang =
1261             clang_sys::support::Clang::find(None, &[]).ok_or_else(|| {
1262                 io::Error::new(
1263                     io::ErrorKind::Other,
1264                     "Cannot find clang executable",
1265                 )
1266             })?;
1267 
1268         // The contents of a wrapper file that includes all the input header
1269         // files.
1270         let mut wrapper_contents = String::new();
1271 
1272         // Whether we are working with C or C++ inputs.
1273         let mut is_cpp = args_are_cpp(&self.options.clang_args);
1274 
1275         // For each input header, add `#include "$header"`.
1276         for header in &self.input_headers {
1277             is_cpp |= check_is_cpp(header);
1278 
1279             wrapper_contents.push_str("#include \"");
1280             wrapper_contents.push_str(header);
1281             wrapper_contents.push_str("\"\n");
1282         }
1283 
1284         // For each input header content, add a prefix line of `#line 0 "$name"`
1285         // followed by the contents.
1286         for &(ref name, ref contents) in &self.input_header_contents {
1287             is_cpp |= check_is_cpp(name);
1288 
1289             wrapper_contents.push_str("#line 0 \"");
1290             wrapper_contents.push_str(name);
1291             wrapper_contents.push_str("\"\n");
1292             wrapper_contents.push_str(contents);
1293         }
1294 
1295         let wrapper_path = PathBuf::from(if is_cpp {
1296             "__bindgen.cpp"
1297         } else {
1298             "__bindgen.c"
1299         });
1300 
1301         {
1302             let mut wrapper_file = File::create(&wrapper_path)?;
1303             wrapper_file.write(wrapper_contents.as_bytes())?;
1304         }
1305 
1306         let mut cmd = Command::new(&clang.path);
1307         cmd.arg("-save-temps")
1308             .arg("-E")
1309             .arg("-C")
1310             .arg("-c")
1311             .arg(&wrapper_path)
1312             .stdout(Stdio::piped());
1313 
1314         for a in &self.options.clang_args {
1315             cmd.arg(a);
1316         }
1317 
1318         let mut child = cmd.spawn()?;
1319 
1320         let mut preprocessed = child.stdout.take().unwrap();
1321         let mut file = File::create(if is_cpp {
1322             "__bindgen.ii"
1323         } else {
1324             "__bindgen.i"
1325         })?;
1326         io::copy(&mut preprocessed, &mut file)?;
1327 
1328         if child.wait()?.success() {
1329             Ok(())
1330         } else {
1331             Err(io::Error::new(
1332                 io::ErrorKind::Other,
1333                 "clang exited with non-zero status",
1334             ))
1335         }
1336     }
1337 
1338     /// Don't derive `PartialEq` for a given type. Regular
1339     /// expressions are supported.
no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder1340     pub fn no_partialeq<T: Into<String>>(mut self, arg: T) -> Builder {
1341         self.options.no_partialeq_types.insert(arg.into());
1342         self
1343     }
1344 
1345     /// Don't derive `Copy` for a given type. Regular
1346     /// expressions are supported.
no_copy<T: Into<String>>(mut self, arg: T) -> Self1347     pub fn no_copy<T: Into<String>>(mut self, arg: T) -> Self {
1348         self.options.no_copy_types.insert(arg.into());
1349         self
1350     }
1351 
1352     /// Don't derive `Hash` for a given type. Regular
1353     /// expressions are supported.
no_hash<T: Into<String>>(mut self, arg: T) -> Builder1354     pub fn no_hash<T: Into<String>>(mut self, arg: T) -> Builder {
1355         self.options.no_hash_types.insert(arg.into());
1356         self
1357     }
1358 
1359     /// 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) -> Self1360     pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self {
1361         self.options.array_pointers_in_arguments = doit;
1362         self
1363     }
1364 }
1365 
1366 /// Configuration options for generated bindings.
1367 #[derive(Debug)]
1368 struct BindgenOptions {
1369     /// The set of types that have been blacklisted and should not appear
1370     /// anywhere in the generated code.
1371     blacklisted_types: RegexSet,
1372 
1373     /// The set of functions that have been blacklisted and should not appear
1374     /// in the generated code.
1375     blacklisted_functions: RegexSet,
1376 
1377     /// The set of items, regardless of item-type, that have been
1378     /// blacklisted and should not appear in the generated code.
1379     blacklisted_items: RegexSet,
1380 
1381     /// The set of types that should be treated as opaque structures in the
1382     /// generated code.
1383     opaque_types: RegexSet,
1384 
1385     /// The explicit rustfmt path.
1386     rustfmt_path: Option<PathBuf>,
1387 
1388     /// The set of types that we should have bindings for in the generated
1389     /// code.
1390     ///
1391     /// This includes all types transitively reachable from any type in this
1392     /// set. One might think of whitelisted types/vars/functions as GC roots,
1393     /// and the generated Rust code as including everything that gets marked.
1394     whitelisted_types: RegexSet,
1395 
1396     /// Whitelisted functions. See docs for `whitelisted_types` for more.
1397     whitelisted_functions: RegexSet,
1398 
1399     /// Whitelisted variables. See docs for `whitelisted_types` for more.
1400     whitelisted_vars: RegexSet,
1401 
1402     /// The default style of code to generate for enums
1403     default_enum_style: codegen::EnumVariation,
1404 
1405     /// The enum patterns to mark an enum as bitfield.
1406     bitfield_enums: RegexSet,
1407 
1408     /// The enum patterns to mark an enum as a Rust enum.
1409     rustified_enums: RegexSet,
1410 
1411     rustified_non_exhaustive_enums: RegexSet,
1412 
1413     /// The enum patterns to mark an enum as a module of constants.
1414     constified_enum_modules: RegexSet,
1415 
1416     /// The enum patterns to mark an enum as a set of constants.
1417     constified_enums: RegexSet,
1418 
1419     /// Whether we should generate builtins or not.
1420     builtins: bool,
1421 
1422     /// True if we should dump the Clang AST for debugging purposes.
1423     emit_ast: bool,
1424 
1425     /// True if we should dump our internal IR for debugging purposes.
1426     emit_ir: bool,
1427 
1428     /// Output graphviz dot file.
1429     emit_ir_graphviz: Option<String>,
1430 
1431     /// True if we should emulate C++ namespaces with Rust modules in the
1432     /// generated bindings.
1433     enable_cxx_namespaces: bool,
1434 
1435     /// True if we should try to find unexposed attributes in functions, in
1436     /// order to be able to generate #[must_use] attributes in Rust.
1437     enable_function_attribute_detection: bool,
1438 
1439     /// True if we should avoid mangling names with namespaces.
1440     disable_name_namespacing: bool,
1441 
1442     /// True if we should generate layout tests for generated structures.
1443     layout_tests: bool,
1444 
1445     /// True if we should implement the Debug trait for C/C++ structures and types
1446     /// that do not support automatically deriving Debug.
1447     impl_debug: bool,
1448 
1449     /// True if we should implement the PartialEq trait for C/C++ structures and types
1450     /// that do not support automatically deriving PartialEq.
1451     impl_partialeq: bool,
1452 
1453     /// True if we should derive Copy trait implementations for C/C++ structures
1454     /// and types.
1455     derive_copy: bool,
1456 
1457     /// True if we should derive Debug trait implementations for C/C++ structures
1458     /// and types.
1459     derive_debug: bool,
1460 
1461     /// True if we should derive Default trait implementations for C/C++ structures
1462     /// and types.
1463     derive_default: bool,
1464 
1465     /// True if we should derive Hash trait implementations for C/C++ structures
1466     /// and types.
1467     derive_hash: bool,
1468 
1469     /// True if we should derive PartialOrd trait implementations for C/C++ structures
1470     /// and types.
1471     derive_partialord: bool,
1472 
1473     /// True if we should derive Ord trait implementations for C/C++ structures
1474     /// and types.
1475     derive_ord: bool,
1476 
1477     /// True if we should derive PartialEq trait implementations for C/C++ structures
1478     /// and types.
1479     derive_partialeq: bool,
1480 
1481     /// True if we should derive Eq trait implementations for C/C++ structures
1482     /// and types.
1483     derive_eq: bool,
1484 
1485     /// True if we should avoid using libstd to use libcore instead.
1486     use_core: bool,
1487 
1488     /// An optional prefix for the "raw" types, like `c_int`, `c_void`...
1489     ctypes_prefix: Option<String>,
1490 
1491     /// Whether to time the bindgen phases.
1492     time_phases: bool,
1493 
1494     /// True if we should generate constant names that are **directly** under
1495     /// namespaces.
1496     namespaced_constants: bool,
1497 
1498     /// True if we should use MSVC name mangling rules.
1499     msvc_mangling: bool,
1500 
1501     /// Whether we should convert float types to f32/f64 types.
1502     convert_floats: bool,
1503 
1504     /// The set of raw lines to prepend to the top-level module of generated
1505     /// Rust code.
1506     raw_lines: Vec<String>,
1507 
1508     /// The set of raw lines to prepend to each of the modules.
1509     ///
1510     /// This only makes sense if the `enable_cxx_namespaces` option is set.
1511     module_lines: HashMap<String, Vec<String>>,
1512 
1513     /// The set of arguments to pass straight through to Clang.
1514     clang_args: Vec<String>,
1515 
1516     /// The input header file.
1517     input_header: Option<String>,
1518 
1519     /// Unsaved files for input.
1520     input_unsaved_files: Vec<clang::UnsavedFile>,
1521 
1522     /// A user-provided visitor to allow customizing different kinds of
1523     /// situations.
1524     parse_callbacks: Option<Box<dyn callbacks::ParseCallbacks>>,
1525 
1526     /// Which kind of items should we generate? By default, we'll generate all
1527     /// of them.
1528     codegen_config: CodegenConfig,
1529 
1530     /// Whether to treat inline namespaces conservatively.
1531     ///
1532     /// See the builder method description for more details.
1533     conservative_inline_namespaces: bool,
1534 
1535     /// Whether to keep documentation comments in the generated output. See the
1536     /// documentation for more details.
1537     generate_comments: bool,
1538 
1539     /// Whether to generate inline functions. Defaults to false.
1540     generate_inline_functions: bool,
1541 
1542     /// Whether to whitelist types recursively. Defaults to true.
1543     whitelist_recursively: bool,
1544 
1545     /// Instead of emitting 'use objc;' to files generated from objective c files,
1546     /// generate '#[macro_use] extern crate objc;'
1547     objc_extern_crate: bool,
1548 
1549     /// Instead of emitting 'use block;' to files generated from objective c files,
1550     /// generate '#[macro_use] extern crate block;'
1551     generate_block: bool,
1552 
1553     /// Instead of emitting 'use block;' to files generated from objective c files,
1554     /// generate '#[macro_use] extern crate block;'
1555     block_extern_crate: bool,
1556 
1557     /// Whether to use the clang-provided name mangling. This is true and
1558     /// probably needed for C++ features.
1559     ///
1560     /// However, some old libclang versions seem to return incorrect results in
1561     /// some cases for non-mangled functions, see [1], so we allow disabling it.
1562     ///
1563     /// [1]: https://github.com/rust-lang/rust-bindgen/issues/528
1564     enable_mangling: bool,
1565 
1566     /// Whether to detect include paths using clang_sys.
1567     detect_include_paths: bool,
1568 
1569     /// Whether to prepend the enum name to bitfield or constant variants.
1570     prepend_enum_name: bool,
1571 
1572     /// Version of the Rust compiler to target
1573     rust_target: RustTarget,
1574 
1575     /// Features to enable, derived from `rust_target`
1576     rust_features: RustFeatures,
1577 
1578     /// Whether we should record which items in the regex sets ever matched.
1579     ///
1580     /// This may be a bit slower, but will enable reporting of unused whitelist
1581     /// items via the `error!` log.
1582     record_matches: bool,
1583 
1584     /// Whether rustfmt should format the generated bindings.
1585     rustfmt_bindings: bool,
1586 
1587     /// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
1588     /// options are used.
1589     rustfmt_configuration_file: Option<PathBuf>,
1590 
1591     /// The set of types that we should not derive `PartialEq` for.
1592     no_partialeq_types: RegexSet,
1593 
1594     /// The set of types that we should not derive `Copy` for.
1595     no_copy_types: RegexSet,
1596 
1597     /// The set of types that we should not derive `Hash` for.
1598     no_hash_types: RegexSet,
1599 
1600     /// Decide if C arrays should be regular pointers in rust or array pointers
1601     array_pointers_in_arguments: bool,
1602 }
1603 
1604 /// TODO(emilio): This is sort of a lie (see the error message that results from
1605 /// removing this), but since we don't share references across panic boundaries
1606 /// it's ok.
1607 impl ::std::panic::UnwindSafe for BindgenOptions {}
1608 
1609 impl BindgenOptions {
build(&mut self)1610     fn build(&mut self) {
1611         let mut regex_sets = [
1612             &mut self.whitelisted_vars,
1613             &mut self.whitelisted_types,
1614             &mut self.whitelisted_functions,
1615             &mut self.blacklisted_types,
1616             &mut self.blacklisted_functions,
1617             &mut self.blacklisted_items,
1618             &mut self.opaque_types,
1619             &mut self.bitfield_enums,
1620             &mut self.constified_enums,
1621             &mut self.constified_enum_modules,
1622             &mut self.rustified_enums,
1623             &mut self.no_partialeq_types,
1624             &mut self.no_copy_types,
1625             &mut self.no_hash_types,
1626         ];
1627         let record_matches = self.record_matches;
1628         for regex_set in &mut regex_sets {
1629             regex_set.build(record_matches);
1630         }
1631     }
1632 
1633     /// Update rust target version
set_rust_target(&mut self, rust_target: RustTarget)1634     pub fn set_rust_target(&mut self, rust_target: RustTarget) {
1635         self.rust_target = rust_target;
1636 
1637         // Keep rust_features synced with rust_target
1638         self.rust_features = rust_target.into();
1639     }
1640 
1641     /// Get features supported by target Rust version
rust_features(&self) -> RustFeatures1642     pub fn rust_features(&self) -> RustFeatures {
1643         self.rust_features
1644     }
1645 }
1646 
1647 impl Default for BindgenOptions {
default() -> BindgenOptions1648     fn default() -> BindgenOptions {
1649         let rust_target = RustTarget::default();
1650 
1651         BindgenOptions {
1652             rust_target,
1653             rust_features: rust_target.into(),
1654             blacklisted_types: Default::default(),
1655             blacklisted_functions: Default::default(),
1656             blacklisted_items: Default::default(),
1657             opaque_types: Default::default(),
1658             rustfmt_path: Default::default(),
1659             whitelisted_types: Default::default(),
1660             whitelisted_functions: Default::default(),
1661             whitelisted_vars: Default::default(),
1662             default_enum_style: Default::default(),
1663             bitfield_enums: Default::default(),
1664             rustified_enums: Default::default(),
1665             rustified_non_exhaustive_enums: Default::default(),
1666             constified_enums: Default::default(),
1667             constified_enum_modules: Default::default(),
1668             builtins: false,
1669             emit_ast: false,
1670             emit_ir: false,
1671             emit_ir_graphviz: None,
1672             layout_tests: true,
1673             impl_debug: false,
1674             impl_partialeq: false,
1675             derive_copy: true,
1676             derive_debug: true,
1677             derive_default: false,
1678             derive_hash: false,
1679             derive_partialord: false,
1680             derive_ord: false,
1681             derive_partialeq: false,
1682             derive_eq: false,
1683             enable_cxx_namespaces: false,
1684             enable_function_attribute_detection: false,
1685             disable_name_namespacing: false,
1686             use_core: false,
1687             ctypes_prefix: None,
1688             namespaced_constants: true,
1689             msvc_mangling: false,
1690             convert_floats: true,
1691             raw_lines: vec![],
1692             module_lines: HashMap::default(),
1693             clang_args: vec![],
1694             input_header: None,
1695             input_unsaved_files: vec![],
1696             parse_callbacks: None,
1697             codegen_config: CodegenConfig::all(),
1698             conservative_inline_namespaces: false,
1699             generate_comments: true,
1700             generate_inline_functions: false,
1701             whitelist_recursively: true,
1702             generate_block: false,
1703             objc_extern_crate: false,
1704             block_extern_crate: false,
1705             enable_mangling: true,
1706             detect_include_paths: true,
1707             prepend_enum_name: true,
1708             time_phases: false,
1709             record_matches: true,
1710             rustfmt_bindings: true,
1711             rustfmt_configuration_file: None,
1712             no_partialeq_types: Default::default(),
1713             no_copy_types: Default::default(),
1714             no_hash_types: Default::default(),
1715             array_pointers_in_arguments: false,
1716         }
1717     }
1718 }
1719 
ensure_libclang_is_loaded()1720 fn ensure_libclang_is_loaded() {
1721     if clang_sys::is_loaded() {
1722         return;
1723     }
1724 
1725     // XXX (issue #350): Ensure that our dynamically loaded `libclang`
1726     // doesn't get dropped prematurely, nor is loaded multiple times
1727     // across different threads.
1728 
1729     lazy_static! {
1730         static ref LIBCLANG: Arc<clang_sys::SharedLibrary> = {
1731             clang_sys::load().expect("Unable to find libclang");
1732             clang_sys::get_library().expect(
1733                 "We just loaded libclang and it had better still be \
1734                  here!",
1735             )
1736         };
1737     }
1738 
1739     clang_sys::set_library(Some(LIBCLANG.clone()));
1740 }
1741 
1742 /// Generated Rust bindings.
1743 #[derive(Debug)]
1744 pub struct Bindings {
1745     options: BindgenOptions,
1746     module: proc_macro2::TokenStream,
1747 }
1748 
1749 impl Bindings {
1750     /// Generate bindings for the given options.
generate( mut options: BindgenOptions, ) -> Result<Bindings, ()>1751     pub(crate) fn generate(
1752         mut options: BindgenOptions,
1753     ) -> Result<Bindings, ()> {
1754         ensure_libclang_is_loaded();
1755 
1756         debug!(
1757             "Generating bindings, libclang at {}",
1758             clang_sys::get_library().unwrap().path().display()
1759         );
1760 
1761         options.build();
1762 
1763         fn detect_include_paths(options: &mut BindgenOptions) {
1764             if !options.detect_include_paths {
1765                 return;
1766             }
1767 
1768             // Filter out include paths and similar stuff, so we don't incorrectly
1769             // promote them to `-isystem`.
1770             let clang_args_for_clang_sys = {
1771                 let mut last_was_include_prefix = false;
1772                 options
1773                     .clang_args
1774                     .iter()
1775                     .filter(|arg| {
1776                         if last_was_include_prefix {
1777                             last_was_include_prefix = false;
1778                             return false;
1779                         }
1780 
1781                         let arg = &**arg;
1782 
1783                         // https://clang.llvm.org/docs/ClangCommandLineReference.html
1784                         // -isystem and -isystem-after are harmless.
1785                         if arg == "-I" || arg == "--include-directory" {
1786                             last_was_include_prefix = true;
1787                             return false;
1788                         }
1789 
1790                         if arg.starts_with("-I") ||
1791                             arg.starts_with("--include-directory=")
1792                         {
1793                             return false;
1794                         }
1795 
1796                         true
1797                     })
1798                     .cloned()
1799                     .collect::<Vec<_>>()
1800             };
1801 
1802             debug!(
1803                 "Trying to find clang with flags: {:?}",
1804                 clang_args_for_clang_sys
1805             );
1806 
1807             let clang = match clang_sys::support::Clang::find(
1808                 None,
1809                 &clang_args_for_clang_sys,
1810             ) {
1811                 None => return,
1812                 Some(clang) => clang,
1813             };
1814 
1815             debug!("Found clang: {:?}", clang);
1816 
1817             // Whether we are working with C or C++ inputs.
1818             let is_cpp = args_are_cpp(&options.clang_args);
1819             let search_paths = if is_cpp {
1820                 clang.cpp_search_paths
1821             } else {
1822                 clang.c_search_paths
1823             };
1824 
1825             if let Some(search_paths) = search_paths {
1826                 for path in search_paths.into_iter() {
1827                     if let Ok(path) = path.into_os_string().into_string() {
1828                         options.clang_args.push("-isystem".to_owned());
1829                         options.clang_args.push(path);
1830                     }
1831                 }
1832             }
1833         }
1834 
1835         detect_include_paths(&mut options);
1836 
1837         #[cfg(unix)]
1838         fn can_read(perms: &std::fs::Permissions) -> bool {
1839             use std::os::unix::fs::PermissionsExt;
1840             perms.mode() & 0o444 > 0
1841         }
1842 
1843         #[cfg(not(unix))]
1844         fn can_read(_: &std::fs::Permissions) -> bool {
1845             true
1846         }
1847 
1848         if let Some(h) = options.input_header.as_ref() {
1849             if let Ok(md) = std::fs::metadata(h) {
1850                 if md.is_dir() {
1851                     eprintln!("error: '{}' is a folder", h);
1852                     return Err(());
1853                 }
1854                 if !can_read(&md.permissions()) {
1855                     eprintln!(
1856                         "error: insufficient permissions to read '{}'",
1857                         h
1858                     );
1859                     return Err(());
1860                 }
1861                 options.clang_args.push(h.clone())
1862             } else {
1863                 eprintln!("error: header '{}' does not exist.", h);
1864                 return Err(());
1865             }
1866         }
1867 
1868         for f in options.input_unsaved_files.iter() {
1869             options.clang_args.push(f.name.to_str().unwrap().to_owned())
1870         }
1871 
1872         debug!("Fixed-up options: {:?}", options);
1873 
1874         let time_phases = options.time_phases;
1875         let mut context = BindgenContext::new(options);
1876 
1877         {
1878             let _t = time::Timer::new("parse").with_output(time_phases);
1879             parse(&mut context)?;
1880         }
1881 
1882         let (items, options) = codegen::codegen(context);
1883 
1884         Ok(Bindings {
1885             options: options,
1886             module: quote! {
1887                 #( #items )*
1888             },
1889         })
1890     }
1891 
1892     /// Convert these bindings into source text (with raw lines prepended).
to_string(&self) -> String1893     pub fn to_string(&self) -> String {
1894         let mut bytes = vec![];
1895         self.write(Box::new(&mut bytes) as Box<dyn Write>)
1896             .expect("writing to a vec cannot fail");
1897         String::from_utf8(bytes)
1898             .expect("we should only write bindings that are valid utf-8")
1899     }
1900 
1901     /// Write these bindings as source text to a file.
write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()>1902     pub fn write_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
1903         let file = OpenOptions::new()
1904             .write(true)
1905             .truncate(true)
1906             .create(true)
1907             .open(path.as_ref())?;
1908         self.write(Box::new(file))?;
1909         Ok(())
1910     }
1911 
1912     /// Write these bindings as source text to the given `Write`able.
write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()>1913     pub fn write<'a>(&self, mut writer: Box<dyn Write + 'a>) -> io::Result<()> {
1914         writer.write(
1915             "/* automatically generated by rust-bindgen */\n\n".as_bytes(),
1916         )?;
1917 
1918         for line in self.options.raw_lines.iter() {
1919             writer.write(line.as_bytes())?;
1920             writer.write("\n".as_bytes())?;
1921         }
1922 
1923         if !self.options.raw_lines.is_empty() {
1924             writer.write("\n".as_bytes())?;
1925         }
1926 
1927         let bindings = self.module.to_string();
1928 
1929         match self.rustfmt_generated_string(&bindings) {
1930             Ok(rustfmt_bindings) => {
1931                 writer.write(rustfmt_bindings.as_bytes())?;
1932             }
1933             Err(err) => {
1934                 eprintln!(
1935                     "Failed to run rustfmt: {} (non-fatal, continuing)",
1936                     err
1937                 );
1938                 writer.write(bindings.as_bytes())?;
1939             }
1940         }
1941         Ok(())
1942     }
1943 
1944     /// Gets the rustfmt path to rustfmt the generated bindings.
rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>>1945     fn rustfmt_path<'a>(&'a self) -> io::Result<Cow<'a, PathBuf>> {
1946         debug_assert!(self.options.rustfmt_bindings);
1947         if let Some(ref p) = self.options.rustfmt_path {
1948             return Ok(Cow::Borrowed(p));
1949         }
1950         if let Ok(rustfmt) = env::var("RUSTFMT") {
1951             return Ok(Cow::Owned(rustfmt.into()));
1952         }
1953         #[cfg(feature = "which-rustfmt")]
1954         match which::which("rustfmt") {
1955             Ok(p) => Ok(Cow::Owned(p)),
1956             Err(e) => {
1957                 Err(io::Error::new(io::ErrorKind::Other, format!("{}", e)))
1958             }
1959         }
1960         #[cfg(not(feature = "which-rustfmt"))]
1961         Err(io::Error::new(
1962             io::ErrorKind::Other,
1963             "which wasn't enabled, and no rustfmt binary specified",
1964         ))
1965     }
1966 
1967     /// 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>>1968     fn rustfmt_generated_string<'a>(
1969         &self,
1970         source: &'a str,
1971     ) -> io::Result<Cow<'a, str>> {
1972         let _t = time::Timer::new("rustfmt_generated_string")
1973             .with_output(self.options.time_phases);
1974 
1975         if !self.options.rustfmt_bindings {
1976             return Ok(Cow::Borrowed(source));
1977         }
1978 
1979         let rustfmt = self.rustfmt_path()?;
1980         let mut cmd = Command::new(&*rustfmt);
1981 
1982         cmd.stdin(Stdio::piped()).stdout(Stdio::piped());
1983 
1984         if let Some(path) = self
1985             .options
1986             .rustfmt_configuration_file
1987             .as_ref()
1988             .and_then(|f| f.to_str())
1989         {
1990             cmd.args(&["--config-path", path]);
1991         }
1992 
1993         let mut child = cmd.spawn()?;
1994         let mut child_stdin = child.stdin.take().unwrap();
1995         let mut child_stdout = child.stdout.take().unwrap();
1996 
1997         let source = source.to_owned();
1998 
1999         // Write to stdin in a new thread, so that we can read from stdout on this
2000         // thread. This keeps the child from blocking on writing to its stdout which
2001         // might block us from writing to its stdin.
2002         let stdin_handle = ::std::thread::spawn(move || {
2003             let _ = child_stdin.write_all(source.as_bytes());
2004             source
2005         });
2006 
2007         let mut output = vec![];
2008         io::copy(&mut child_stdout, &mut output)?;
2009 
2010         let status = child.wait()?;
2011         let source = stdin_handle.join().expect(
2012             "The thread writing to rustfmt's stdin doesn't do \
2013              anything that could panic",
2014         );
2015 
2016         match String::from_utf8(output) {
2017             Ok(bindings) => match status.code() {
2018                 Some(0) => Ok(Cow::Owned(bindings)),
2019                 Some(2) => Err(io::Error::new(
2020                     io::ErrorKind::Other,
2021                     "Rustfmt parsing errors.".to_string(),
2022                 )),
2023                 Some(3) => {
2024                     warn!("Rustfmt could not format some lines.");
2025                     Ok(Cow::Owned(bindings))
2026                 }
2027                 _ => Err(io::Error::new(
2028                     io::ErrorKind::Other,
2029                     "Internal rustfmt error".to_string(),
2030                 )),
2031             },
2032             _ => Ok(Cow::Owned(source)),
2033         }
2034     }
2035 }
2036 
2037 /// Determines whether the given cursor is in any of the files matched by the
2038 /// options.
filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool2039 fn filter_builtins(ctx: &BindgenContext, cursor: &clang::Cursor) -> bool {
2040     ctx.options().builtins || !cursor.is_builtin()
2041 }
2042 
2043 /// Parse one `Item` from the Clang cursor.
parse_one( ctx: &mut BindgenContext, cursor: clang::Cursor, parent: Option<ItemId>, ) -> clang_sys::CXChildVisitResult2044 fn parse_one(
2045     ctx: &mut BindgenContext,
2046     cursor: clang::Cursor,
2047     parent: Option<ItemId>,
2048 ) -> clang_sys::CXChildVisitResult {
2049     if !filter_builtins(ctx, &cursor) {
2050         return CXChildVisit_Continue;
2051     }
2052 
2053     use clang_sys::CXChildVisit_Continue;
2054     match Item::parse(cursor, parent, ctx) {
2055         Ok(..) => {}
2056         Err(ParseError::Continue) => {}
2057         Err(ParseError::Recurse) => {
2058             cursor.visit(|child| parse_one(ctx, child, parent));
2059         }
2060     }
2061     CXChildVisit_Continue
2062 }
2063 
2064 /// Parse the Clang AST into our `Item` internal representation.
parse(context: &mut BindgenContext) -> Result<(), ()>2065 fn parse(context: &mut BindgenContext) -> Result<(), ()> {
2066     use clang_sys::*;
2067 
2068     let mut any_error = false;
2069     for d in context.translation_unit().diags().iter() {
2070         let msg = d.format();
2071         let is_err = d.severity() >= CXDiagnostic_Error;
2072         eprintln!("{}, err: {}", msg, is_err);
2073         any_error |= is_err;
2074     }
2075 
2076     if any_error {
2077         return Err(());
2078     }
2079 
2080     let cursor = context.translation_unit().cursor();
2081 
2082     if context.options().emit_ast {
2083         fn dump_if_not_builtin(cur: &clang::Cursor) -> CXChildVisitResult {
2084             if !cur.is_builtin() {
2085                 clang::ast_dump(&cur, 0)
2086             } else {
2087                 CXChildVisit_Continue
2088             }
2089         }
2090         cursor.visit(|cur| dump_if_not_builtin(&cur));
2091     }
2092 
2093     let root = context.root_module();
2094     context.with_module(root, |context| {
2095         cursor.visit(|cursor| parse_one(context, cursor, None))
2096     });
2097 
2098     assert!(
2099         context.current_module() == context.root_module(),
2100         "How did this happen?"
2101     );
2102     Ok(())
2103 }
2104 
2105 /// Extracted Clang version data
2106 #[derive(Debug)]
2107 pub struct ClangVersion {
2108     /// Major and minor semver, if parsing was successful
2109     pub parsed: Option<(u32, u32)>,
2110     /// full version string
2111     pub full: String,
2112 }
2113 
2114 /// Get the major and the minor semver numbers of Clang's version
clang_version() -> ClangVersion2115 pub fn clang_version() -> ClangVersion {
2116     if !clang_sys::is_loaded() {
2117         // TODO(emilio): Return meaningful error (breaking).
2118         clang_sys::load().expect("Unable to find libclang");
2119     }
2120 
2121     let raw_v: String = clang::extract_clang_version();
2122     let split_v: Option<Vec<&str>> = raw_v
2123         .split_whitespace()
2124         .nth(2)
2125         .map(|v| v.split('.').collect());
2126     match split_v {
2127         Some(v) => {
2128             if v.len() >= 2 {
2129                 let maybe_major = v[0].parse::<u32>();
2130                 let maybe_minor = v[1].parse::<u32>();
2131                 match (maybe_major, maybe_minor) {
2132                     (Ok(major), Ok(minor)) => {
2133                         return ClangVersion {
2134                             parsed: Some((major, minor)),
2135                             full: raw_v.clone(),
2136                         }
2137                     }
2138                     _ => {}
2139                 }
2140             }
2141         }
2142         None => {}
2143     };
2144     ClangVersion {
2145         parsed: None,
2146         full: raw_v.clone(),
2147     }
2148 }
2149 
2150 /// Test command_line_flag function.
2151 #[test]
commandline_flag_unit_test_function()2152 fn commandline_flag_unit_test_function() {
2153     //Test 1
2154     let bindings = ::builder();
2155     let command_line_flags = bindings.command_line_flags();
2156 
2157     let test_cases = vec![
2158         "--rust-target",
2159         "--no-derive-default",
2160         "--generate",
2161         "functions,types,vars,methods,constructors,destructors",
2162     ]
2163     .iter()
2164     .map(|&x| x.into())
2165     .collect::<Vec<String>>();
2166 
2167     assert!(test_cases
2168         .iter()
2169         .all(|ref x| command_line_flags.contains(x),));
2170 
2171     //Test 2
2172     let bindings = ::builder()
2173         .header("input_header")
2174         .whitelist_type("Distinct_Type")
2175         .whitelist_function("safe_function");
2176 
2177     let command_line_flags = bindings.command_line_flags();
2178     let test_cases = vec![
2179         "--rust-target",
2180         "input_header",
2181         "--no-derive-default",
2182         "--generate",
2183         "functions,types,vars,methods,constructors,destructors",
2184         "--whitelist-type",
2185         "Distinct_Type",
2186         "--whitelist-function",
2187         "safe_function",
2188     ]
2189     .iter()
2190     .map(|&x| x.into())
2191     .collect::<Vec<String>>();
2192     println!("{:?}", command_line_flags);
2193 
2194     assert!(test_cases
2195         .iter()
2196         .all(|ref x| command_line_flags.contains(x),));
2197 }
2198